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

(xalan-java) branch xalan-j_xslt3.0 updated: refactoring of codebase to process xpath constructor, stylesheet function and xpath extension function calls

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 137267d1d refactoring of codebase to process xpath constructor, stylesheet function and xpath extension function calls
137267d1d is described below

commit 137267d1dbf78eb3ffab263e5d17a721b6353673
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Sat Jul 20 11:27:36 2024 +0530

    refactoring of codebase to process xpath constructor, stylesheet function and xpath extension function calls
---
 .../apache/xalan/extensions/ExpressionVisitor.java |   6 +-
 .../apache/xalan/extensions/ExtensionHandler.java  |   4 +-
 .../extensions/ExtensionHandlerExsltFunction.java  |   4 +-
 .../xalan/extensions/ExtensionHandlerGeneral.java  |   4 +-
 .../extensions/ExtensionHandlerJavaClass.java      |   4 +-
 .../extensions/ExtensionHandlerJavaPackage.java    |  51 +-
 .../apache/xalan/extensions/ExtensionsTable.java   |   4 +-
 src/org/apache/xalan/templates/AbsPathChecker.java |   4 +-
 src/org/apache/xalan/templates/ElemFunction.java   |  77 ++-
 src/org/apache/xalan/templates/ElemSequence.java   |  21 +-
 src/org/apache/xalan/templates/ElemValueOf.java    |  10 +-
 src/org/apache/xalan/templates/ElemVariable.java   |  67 ++-
 .../xalan/templates/XSConstructorFunctionUtil.java | 642 ---------------------
 .../apache/xalan/transformer/TransformerImpl.java  |   4 +-
 .../xslt/util/XslTransformEvaluationHelper.java    |   6 +-
 src/org/apache/xpath/ExtensionsProvider.java       |   4 +-
 src/org/apache/xpath/XPathContext.java             |   6 +
 src/org/apache/xpath/axes/FilterExprWalker.java    |   2 +-
 src/org/apache/xpath/axes/UnionPathIterator.java   |   2 +-
 src/org/apache/xpath/axes/WalkerFactory.java       |  18 +-
 src/org/apache/xpath/compiler/Compiler.java        |  18 +-
 src/org/apache/xpath/compiler/OpCodes.java         |   4 +-
 src/org/apache/xpath/compiler/XPathParser.java     |  61 +-
 .../xpath/functions/FuncDaysFromDuration.java      |   2 +-
 .../xpath/functions/FuncHoursFromDuration.java     |   2 +-
 .../xpath/functions/FuncMinutesFromDuration.java   |   2 +-
 .../xpath/functions/FuncMonthsFromDuration.java    |   2 +-
 src/org/apache/xpath/functions/FuncNot.java        |  13 +-
 .../xpath/functions/FuncSecondsFromDuration.java   |   2 +-
 .../xpath/functions/FuncYearsFromDuration.java     |   2 +-
 ...LConstructorStylesheetOrExtensionFunction.java} |  78 ++-
 .../apache/xpath/functions/XSLFunctionBuilder.java |  34 ++
 .../apache/xpath/functions/XSLFunctionService.java | 642 +++++++++++++++++++++
 .../apache/xpath/jaxp/JAXPExtensionsProvider.java  |   4 +-
 src/org/apache/xpath/operations/Operation.java     |  24 +-
 src/org/apache/xpath/operations/Range.java         |  27 +-
 .../apache/xpath/operations/SimpleMapOperator.java |  18 +-
 37 files changed, 942 insertions(+), 933 deletions(-)

diff --git a/src/org/apache/xalan/extensions/ExpressionVisitor.java b/src/org/apache/xalan/extensions/ExpressionVisitor.java
index 6b12c82a6..cfd75868b 100644
--- a/src/org/apache/xalan/extensions/ExpressionVisitor.java
+++ b/src/org/apache/xalan/extensions/ExpressionVisitor.java
@@ -23,7 +23,7 @@ package org.apache.xalan.extensions;
 import org.apache.xalan.templates.StylesheetRoot;
 import org.apache.xpath.ExpressionOwner;
 import org.apache.xpath.XPathVisitor;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.functions.FuncExtFunctionAvailable;
 import org.apache.xpath.functions.Function;
 
@@ -61,9 +61,9 @@ public class ExpressionVisitor extends XPathVisitor
    */
   public boolean visitFunction(ExpressionOwner owner, Function func)
   {
-    if (func instanceof FuncExtFunction)
+    if (func instanceof XSLConstructorStylesheetOrExtensionFunction)
     {
-      String namespace = ((FuncExtFunction)func).getNamespace();
+      String namespace = ((XSLConstructorStylesheetOrExtensionFunction)func).getNamespace();
       m_sroot.getExtensionNamespacesManager().registerExtension(namespace);      
     }
     else if (func instanceof FuncExtFunctionAvailable)
diff --git a/src/org/apache/xalan/extensions/ExtensionHandler.java b/src/org/apache/xalan/extensions/ExtensionHandler.java
index 8c5bf2bfd..96653b19c 100644
--- a/src/org/apache/xalan/extensions/ExtensionHandler.java
+++ b/src/org/apache/xalan/extensions/ExtensionHandler.java
@@ -30,7 +30,7 @@ import javax.xml.transform.TransformerException;
 import org.apache.xalan.templates.ElemTemplateElement;
 import org.apache.xalan.templates.Stylesheet;
 import org.apache.xalan.transformer.TransformerImpl;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 
 /**
  * Abstract base class for handling an extension namespace for XPath.
@@ -123,7 +123,7 @@ public abstract class ExtensionHandler
    * @throws TransformerException          if parsing trouble
    */
   public abstract Object callFunction(
-    FuncExtFunction extFunction, Vector args,
+    XSLConstructorStylesheetOrExtensionFunction extFunction, Vector args,
       ExpressionContext exprContext, TransformerImpl transformer) throws TransformerException;
 
   /**
diff --git a/src/org/apache/xalan/extensions/ExtensionHandlerExsltFunction.java b/src/org/apache/xalan/extensions/ExtensionHandlerExsltFunction.java
index 622682308..90a790141 100644
--- a/src/org/apache/xalan/extensions/ExtensionHandlerExsltFunction.java
+++ b/src/org/apache/xalan/extensions/ExtensionHandlerExsltFunction.java
@@ -38,7 +38,7 @@ import org.apache.xalan.transformer.TransformerImpl;
 import org.apache.xml.utils.QName;
 import org.apache.xpath.ExpressionNode;
 import org.apache.xpath.XPathContext;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.objects.XObject;
 import org.apache.xpath.objects.XString;
 
@@ -176,7 +176,7 @@ public class ExtensionHandlerExsltFunction extends ExtensionHandler
    * @return the return value of the function evaluation.
    * @throws TransformerException
    */
-  public Object callFunction(FuncExtFunction extFunction,
+  public Object callFunction(XSLConstructorStylesheetOrExtensionFunction extFunction,
                              Vector args,
                              ExpressionContext exprContext,
                              TransformerImpl transformer)
diff --git a/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java b/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java
index 33cdccd4a..0390e5cae 100644
--- a/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java
+++ b/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java
@@ -42,7 +42,7 @@ import org.apache.xml.dtm.ref.DTMNodeList;
 import org.apache.xml.utils.StringVector;
 import org.apache.xml.utils.SystemIDResolver;
 import org.apache.xpath.XPathProcessorException;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.objects.XObject;
 
 /**
@@ -336,7 +336,7 @@ public class ExtensionHandlerGeneral extends ExtensionHandler
    * @return the return value of the function evaluation.
    * @throws TransformerException
    */
-  public Object callFunction(FuncExtFunction extFunction,
+  public Object callFunction(XSLConstructorStylesheetOrExtensionFunction extFunction,
                              Vector args,
                              ExpressionContext exprContext,
                              TransformerImpl transformer)
diff --git a/src/org/apache/xalan/extensions/ExtensionHandlerJavaClass.java b/src/org/apache/xalan/extensions/ExtensionHandlerJavaClass.java
index 784579fb5..af01d2a88 100644
--- a/src/org/apache/xalan/extensions/ExtensionHandlerJavaClass.java
+++ b/src/org/apache/xalan/extensions/ExtensionHandlerJavaClass.java
@@ -34,7 +34,7 @@ import org.apache.xalan.templates.ElemTemplateElement;
 import org.apache.xalan.templates.Stylesheet;
 import org.apache.xalan.trace.ExtensionEvent;
 import org.apache.xalan.transformer.TransformerImpl;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.objects.XObject;
 
 /**
@@ -432,7 +432,7 @@ public class ExtensionHandlerJavaClass extends ExtensionHandlerJava
    * @return the return value of the function evaluation.
    * @throws TransformerException
    */
-  public Object callFunction(FuncExtFunction extFunction,
+  public Object callFunction(XSLConstructorStylesheetOrExtensionFunction extFunction,
                              Vector args,
                              ExpressionContext exprContext,
                              TransformerImpl transformer)
diff --git a/src/org/apache/xalan/extensions/ExtensionHandlerJavaPackage.java b/src/org/apache/xalan/extensions/ExtensionHandlerJavaPackage.java
index f27417c82..7d4de5085 100644
--- a/src/org/apache/xalan/extensions/ExtensionHandlerJavaPackage.java
+++ b/src/org/apache/xalan/extensions/ExtensionHandlerJavaPackage.java
@@ -33,10 +33,11 @@ import org.apache.xalan.res.XSLMessages;
 import org.apache.xalan.res.XSLTErrorResources;
 import org.apache.xalan.templates.ElemTemplateElement;
 import org.apache.xalan.templates.Stylesheet;
-import org.apache.xalan.templates.XSConstructorFunctionUtil;
 import org.apache.xalan.trace.ExtensionEvent;
 import org.apache.xalan.transformer.TransformerImpl;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLFunctionService;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.objects.XObject;
 
 /**
@@ -423,33 +424,41 @@ public class ExtensionHandlerJavaPackage extends ExtensionHandlerJava
   }
 
   /**
-   * Process a call to an XPath extension function
+   * Process a call to either of following kinds of functions called from 
+   * within XPath expressions:
+   * 1) XPath 3.1 constructor function, called with syntax prefix:type_name(..)
+   * 2) XSL stylesheet function, specified with syntax xsl:function
+   * 3) XPath extension function, defined within Xalan-J's extensions function
+   *    library by Xalan-J implementation. 
    *
-   * @param extFunction The XPath extension function
-   * @param args The arguments of the function call.
-   * @param exprContext The context in which this expression is being executed.
-   * @return the return value of the function evaluation.
+   * @param funcObj                         an XPath constructor function, or stylesheet function
+   * @param args                            the arguments of the function call
+   * @param exprContext                     the context in which this expression is being executed
+   * @return                                the return value of the function evaluation
    * @throws TransformerException
    */
-  public Object callFunction(FuncExtFunction extFunction,
+  public Object callFunction(XSLConstructorStylesheetOrExtensionFunction funcObj,
                              Vector args,
                              ExpressionContext exprContext,
                              TransformerImpl transformer) throws TransformerException
   {
       
-      Object funcEvalResult = null;
-      
-          XObject evalResult = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn
-                                                                          (exprContext.getXPathContext(), extFunction, transformer);
-          if (evalResult != null) {
-             funcEvalResult = evalResult;
-          }
-          else {
-             funcEvalResult = callFunction(extFunction.getFunctionName(), args, extFunction.getMethodKey(), 
-                                                                                                     exprContext);    
-          }
-      
-      return funcEvalResult;
+	  Object funcEvalResult = null;
+	  
+	  XPathContext xctxt = transformer.getXPathContext();
+	  
+	  XSLFunctionService xslFunctionService = xctxt.getXSLFunctionService();
+
+	  XObject evalResult = xslFunctionService.callFunction(funcObj, transformer, xctxt);
+	  
+	  if (evalResult != null) {
+		  funcEvalResult = evalResult;
+	  }
+	  else {
+		  funcEvalResult = callFunction(funcObj.getFunctionName(), args, funcObj.getMethodKey(), exprContext);    
+	  }
+
+	  return funcEvalResult;
       
   }
 
diff --git a/src/org/apache/xalan/extensions/ExtensionsTable.java b/src/org/apache/xalan/extensions/ExtensionsTable.java
index 76e5804aa..99d4e1e7d 100644
--- a/src/org/apache/xalan/extensions/ExtensionsTable.java
+++ b/src/org/apache/xalan/extensions/ExtensionsTable.java
@@ -28,7 +28,7 @@ import org.apache.xalan.res.XSLTErrorResources;
 import org.apache.xalan.templates.StylesheetRoot;
 import org.apache.xalan.transformer.TransformerImpl;
 import org.apache.xpath.XPathProcessorException;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 
 /**
  * Class holding a table registered extension namespace handlers
@@ -206,7 +206,7 @@ public class ExtensionsTable
    *
    * @throws javax.xml.transform.TransformerException
    */
-  public Object extFunction(FuncExtFunction extFunction, Vector argVec, 
+  public Object extFunction(XSLConstructorStylesheetOrExtensionFunction extFunction, Vector argVec, 
                             ExpressionContext exprContext, TransformerImpl transformer)
          throws javax.xml.transform.TransformerException
   {
diff --git a/src/org/apache/xalan/templates/AbsPathChecker.java b/src/org/apache/xalan/templates/AbsPathChecker.java
index 620645762..4736b5f87 100644
--- a/src/org/apache/xalan/templates/AbsPathChecker.java
+++ b/src/org/apache/xalan/templates/AbsPathChecker.java
@@ -24,7 +24,7 @@ import org.apache.xpath.ExpressionOwner;
 import org.apache.xpath.XPathVisitor;
 import org.apache.xpath.axes.LocPathIterator;
 import org.apache.xpath.functions.FuncCurrent;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.functions.Function;
 import org.apache.xpath.operations.Variable;
 
@@ -60,7 +60,7 @@ public class AbsPathChecker extends XPathVisitor
 	public boolean visitFunction(ExpressionOwner owner, Function func)
 	{
 		if((func instanceof FuncCurrent) ||
-		   (func instanceof FuncExtFunction))
+		   (func instanceof XSLConstructorStylesheetOrExtensionFunction))
 			m_isAbs = false;
 		return true;
 	}
diff --git a/src/org/apache/xalan/templates/ElemFunction.java b/src/org/apache/xalan/templates/ElemFunction.java
index f9577581f..a37e4e761 100644
--- a/src/org/apache/xalan/templates/ElemFunction.java
+++ b/src/org/apache/xalan/templates/ElemFunction.java
@@ -70,9 +70,7 @@ import xml.xpath31.processor.types.XSTime;
 import xml.xpath31.processor.types.XSYearMonthDuration;
 
 /**
- * Implementation of XSLT xsl:function element.
- * 
- * Ref : https://www.w3.org/TR/xslt-30/#stylesheet-functions
+ * Implementation of XSLT 2.0+ xsl:function element.
  *
  * @author Mukul Gandhi <mu...@apache.org>
  * 
@@ -129,12 +127,12 @@ public class ElemFunction extends ElemTemplate
   }
 
   /**
-   * This method evaluates the xsl:function call, and returns the result
-   * to the caller of this function.
+   * This method computes the result of xsl:function call, and returns 
+   * result to the caller of this function.
    */
-  public XObject executeXslFunction(TransformerImpl transformer, 
-                                                             ResultSequence argSequence) throws TransformerException {
-      XObject result = null;
+  public XObject evaluateXslFunction(TransformerImpl transformer, ResultSequence argSequence) throws TransformerException {
+      
+	  XObject result = null;
       
       XPathContext xctxt = transformer.getXPathContext();            
       
@@ -143,7 +141,7 @@ public class ElemFunction extends ElemTemplate
       String funcLocalName = m_name.getLocalName();
       String funcNameSpaceUri = m_name.getNamespaceURI();
       
-      // Validate few of the information of xsl:function's xsl:param declarations         
+      // Validate few of the information of xsl:function's xsl:param declarations      
       Map<QName, Integer> xslParamMap = new HashMap<QName, Integer>();
       int idx = 0;
       PrefixResolver prefixResolver = xctxt.getNamespaceContext();
@@ -208,12 +206,10 @@ public class ElemFunction extends ElemTemplate
                currVal = nextVal;  
             }
          }
-      }
-      
-      // end, Validate few of the information of xsl:function's xsl:param declarations            
+      }            
       
       if (xslParamMap.size() > 0) {
-          // Assign all of the xsl:function parameter value mappings to xpath context's
+          // Add all of the xsl:function parameter value mappings to xpath context's
           // variable stack, after which the XSL instructions after xsl:param declarations
           // can dereference those parameters.                   
           
@@ -269,19 +265,17 @@ public class ElemFunction extends ElemTemplate
           }                    
       }            
       
-      int nodeDtmHandle = transformer.transformToGlobalRTF(this);
-      
-      NodeList nodeList = (new XRTreeFrag(nodeDtmHandle, xctxt, this)).convertToNodeset();     
-      
-      result = new XNodeSetForDOM(nodeList, xctxt);
+      // Get xsl:function's result, before processing with "as" attribute
+      result = getXslFunctionResult(transformer, xctxt);
                         
       XObject funcResultConvertedVal = result;
       
       String funcAsAttrStrVal = getAs();
       
-      if (funcAsAttrStrVal != null) {         
+      if (funcAsAttrStrVal != null) {
+    	 // Process xsl:function's evaluation result with "as" attribute
          try {
-            funcResultConvertedVal = preprocessXslFunctionOrAVariableResult((XNodeSetForDOM)result, funcAsAttrStrVal, xctxt, null);
+            funcResultConvertedVal = preprocessXslFunctionOrAVariableResult(result, funcAsAttrStrVal, xctxt, null);
             
             if (funcResultConvertedVal == null) {
                 funcResultConvertedVal = SequenceTypeSupport.convertXdmValueToAnotherType(result, funcAsAttrStrVal, null, xctxt);
@@ -341,19 +335,21 @@ public class ElemFunction extends ElemTemplate
   }
   
   /**
-   * This method helps to implement xsl:function and xsl:variable instructions,
-   * when the XSL child contents of xsl:function or xsl:variable instructions contain 
+   * This method supports to implement xsl:function/xsl:variable instructions,
+   * when the XSL child contents of xsl:function/xsl:variable instructions contain 
    * xsl:sequence instruction(s).
    * 
-   * Given an initial result of computation of, XSL child contents of a xsl:function or xsl:variable
-   * instructions, and the function's or variable's expected data type, cast an input data
-   * value to the supplied expected data type.
+   * Given an initial result of computation of, XSL child contents of a xsl:function/xsl:variable
+   * instruction, and xsl:function or xsl:variable's expected data type, cast an input data
+   * value to the specified expected data type.
    */
-  public ResultSequence preprocessXslFunctionOrAVariableResult(XNodeSetForDOM xNodeSetForDOM,
-                                                                                     String sequenceTypeXPathExprStr,
-                                                                                     XPathContext xctxt, QName varQName) throws TransformerException {
+  public ResultSequence preprocessXslFunctionOrAVariableResult(XObject initialEvalResult,
+                                                               String sequenceTypeXPathExprStr,
+                                                               XPathContext xctxt, QName varQName) throws TransformerException {
      ResultSequence resultSequence = null;
      
+     XNodeSetForDOM xNodeSetForDOM = (XNodeSetForDOM)initialEvalResult;
+     
      DTMNodeList dtmNodeList = (DTMNodeList)(xNodeSetForDOM.object());
      
      final int contextNode = xctxt.getContextNode(); 
@@ -427,6 +423,31 @@ public class ElemFunction extends ElemTemplate
      return new ElemFunction();  
   }
   
+  /**
+   * Evaluate xsl:function's child contents to produce xsl:function's result, before 
+   * the function's result is processed with function's "as" attribute.
+   * 
+   * This method is implemented similarly to how, xsl:variable instruction's value
+   * is determined from xsl:variable's child contents. Any xsl:param prefix elements 
+   * present within xsl:function element, are processed according to xsl:variable 
+   * instruction's semantics (the class ElemParam extends the class ElemVariable). 
+   * 
+   * @param transformer				org.apache.xalan.transformer.TransformerImpl object
+   * @param xctxt           		xpath context object
+   * @return                		result of xsl:function's evaluation  
+   * @throws TransformerException
+   */
+  private XObject getXslFunctionResult(TransformerImpl transformer, XPathContext xctxt) throws TransformerException {		
+	  XObject result = null;
+
+	  int nodeDtmHandle = transformer.transformToGlobalRTF(this);
+	  NodeList nodeList = (new XRTreeFrag(nodeDtmHandle, xctxt, this)).convertToNodeset();     
+
+	  result = new XNodeSetForDOM(nodeList, xctxt);
+
+	  return result;
+  }
+  
   /**
    * Given Xalan-J's integer code value of, an XML Schema built-in data type and a 
    * string representation of a data value, construct Xalan-J's typed data object 
diff --git a/src/org/apache/xalan/templates/ElemSequence.java b/src/org/apache/xalan/templates/ElemSequence.java
index 9a1c05ca9..b98ecaf94 100644
--- a/src/org/apache/xalan/templates/ElemSequence.java
+++ b/src/org/apache/xalan/templates/ElemSequence.java
@@ -35,8 +35,10 @@ import org.apache.xpath.axes.LocPathIterator;
 import org.apache.xpath.axes.SelfIteratorNoPredicate;
 import org.apache.xpath.compiler.XPathParser;
 import org.apache.xpath.composite.SequenceTypeData;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
+import org.apache.xpath.functions.XSLFunctionBuilder;
 import org.apache.xpath.functions.Function;
+import org.apache.xpath.functions.XSLFunctionService;
 import org.apache.xpath.objects.XPathInlineFunction;
 import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XBoolean;
@@ -186,9 +188,10 @@ public class ElemSequence extends ElemTemplateElement
     	  
         selectExpression = m_selectPattern.getExpression();
         
-        if (selectExpression instanceof FuncExtFunction) {
-            XObject evalResult = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(xctxt, 
-                                                                                                selectExpression, transformer);
+        if (selectExpression instanceof XSLConstructorStylesheetOrExtensionFunction) {
+        	XSLConstructorStylesheetOrExtensionFunction xpathFunc = (XSLConstructorStylesheetOrExtensionFunction)selectExpression;
+        	XSLFunctionService xslFunctionService = xctxt.getXSLFunctionService();
+            XObject evalResult = xslFunctionService.callFunction(xpathFunc, transformer, xctxt);
             if (evalResult != null) {
                xslSequenceVal = evalResult;    
             }
@@ -202,12 +205,10 @@ public class ElemSequence extends ElemTemplateElement
             xslSequenceVal = selectExpression.execute(xctxt);
         }
         else if (selectExpression instanceof Operation) {
-            Operation opn = (Operation)selectExpression;
-            XObject leftOperand = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
-                                                                                           xctxt, opn.getLeftOperand(), transformer);
-            XObject rightOperand = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
-                                                                                           xctxt, opn.getRightOperand(), transformer);
-            xslSequenceVal = opn.operate(leftOperand, rightOperand);
+            Operation xpathOperation = (Operation)selectExpression;            
+            XObject leftOperand = (xpathOperation.getLeftOperand()).execute(xctxt);
+            XObject rightOperand = (xpathOperation.getRightOperand()).execute(xctxt);
+            xslSequenceVal = xpathOperation.operate(leftOperand, rightOperand);
         }
         else if (selectExpression instanceof SelfIteratorNoPredicate) {
             xslSequenceVal = xctxt.getXPath3ContextItem();
diff --git a/src/org/apache/xalan/templates/ElemValueOf.java b/src/org/apache/xalan/templates/ElemValueOf.java
index 95bfcb8d7..21bfac52b 100644
--- a/src/org/apache/xalan/templates/ElemValueOf.java
+++ b/src/org/apache/xalan/templates/ElemValueOf.java
@@ -35,8 +35,9 @@ import org.apache.xpath.XPathContext;
 import org.apache.xpath.axes.LocPathIterator;
 import org.apache.xpath.composite.XPathIfExpr;
 import org.apache.xpath.composite.XPathLetExpr;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.functions.Function;
+import org.apache.xpath.functions.XSLFunctionService;
 import org.apache.xpath.functions.XPathDynamicFunctionCall;
 import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XNodeSet;
@@ -318,9 +319,10 @@ public class ElemValueOf extends ElemTemplateElement {
                   (new XString(strValue)).dispatchCharactersEvents(rth);
               }
               else {
-                  if (expr instanceof FuncExtFunction) {                      
-                      XObject evalResult = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn
-                                                                                          (xctxt, expr, transformer);
+                  if (expr instanceof XSLConstructorStylesheetOrExtensionFunction) {
+                	  XSLConstructorStylesheetOrExtensionFunction xpathFunc = (XSLConstructorStylesheetOrExtensionFunction)expr;
+                	  XSLFunctionService xslFunctionService = xctxt.getXSLFunctionService();
+                      XObject evalResult = xslFunctionService.callFunction(xpathFunc, transformer, xctxt);
                       if (evalResult != null) {
                           String strValue = null;
                           
diff --git a/src/org/apache/xalan/templates/ElemVariable.java b/src/org/apache/xalan/templates/ElemVariable.java
index e4a7b3a85..fba1250a4 100644
--- a/src/org/apache/xalan/templates/ElemVariable.java
+++ b/src/org/apache/xalan/templates/ElemVariable.java
@@ -36,8 +36,9 @@ 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.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.functions.Function;
+import org.apache.xpath.functions.XSLFunctionService;
 import org.apache.xpath.objects.XPathInlineFunction;
 import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XNodeSet;
@@ -346,9 +347,10 @@ public class ElemVariable extends ElemTemplateElement
       if (m_selectPattern != null) {          
         selectExpression = m_selectPattern.getExpression();
         
-        if (selectExpression instanceof FuncExtFunction) {        	
-            XObject evalResult = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(xctxt, 
-                                                                                      selectExpression, transformer);
+        if (selectExpression instanceof XSLConstructorStylesheetOrExtensionFunction) {        	
+        	XSLConstructorStylesheetOrExtensionFunction xpathFunc = (XSLConstructorStylesheetOrExtensionFunction)selectExpression;
+        	XSLFunctionService xslFunctionService = xctxt.getXSLFunctionService();
+            XObject evalResult = xslFunctionService.callFunction(xpathFunc, transformer, xctxt);
             
             QName asAttrQName = null;
             
@@ -358,11 +360,11 @@ public class ElemVariable extends ElemTemplateElement
             }
             
             if (evalResult != null) {
-            	String funcName = ((FuncExtFunction)selectExpression).getFunctionName();
-            	String funcNamespace = ((FuncExtFunction)selectExpression).getNamespace();
+            	String funcName = ((XSLConstructorStylesheetOrExtensionFunction)selectExpression).getFunctionName();
+            	String funcNamespace = ((XSLConstructorStylesheetOrExtensionFunction)selectExpression).getNamespace();
             	
             	String evalResultStrValue = (evalResult instanceof XSString) ? ((XSString)evalResult).stringValue() : null;            	
-            	if (m_asAttr != null && !(XSConstructorFunctionUtil.XS_VALID_TRUE).equals(evalResultStrValue)) {           	     
+            	if (m_asAttr != null && !(XSLFunctionService.XS_VALID_TRUE).equals(evalResultStrValue)) {           	     
                    evalResult = SequenceTypeSupport.convertXdmValueToAnotherType(evalResult, m_asAttr, null, xctxt);
                    if (evalResult == null) {
                 	  String xpathPatternStr = m_selectPattern.getPatternString();
@@ -370,11 +372,11 @@ public class ElemVariable extends ElemTemplateElement
                 	  		                                               + "match the expected sequence type " + m_asAttr + ".", srcLocator); 
                    }
                 }
-            	else if (m_asAttr != null && (XSConstructorFunctionUtil.XS_VALID_TRUE).equals(evalResultStrValue)) {
+            	else if (m_asAttr != null && (XSLFunctionService.XS_VALID_TRUE).equals(evalResultStrValue)) {
             	   String typeName = asAttrQName.getLocalName();
             	   String typeNamespace = asAttrQName.getNamespace();
             	   if (funcName.equals(typeName) && typeNamespace.equals(funcNamespace)) {            		  
-            	      XObject valToBeValidated = (((FuncExtFunction)selectExpression).getArg(0)).execute(xctxt);
+            	      XObject valToBeValidated = (((XSLConstructorStylesheetOrExtensionFunction)selectExpression).getArg(0)).execute(xctxt);
             	      evalResult = valToBeValidated; 
             	   }
             	   else {
@@ -383,8 +385,8 @@ public class ElemVariable extends ElemTemplateElement
                  	  		                                               + "match the expected sequence type " + m_asAttr + ".", srcLocator); 
             	   }
             	}
-            	else if (m_asAttr == null && (XSConstructorFunctionUtil.XS_VALID_TRUE).equals(evalResultStrValue)) {
-            	   XObject valToBeValidated = (((FuncExtFunction)selectExpression).getArg(0)).execute(xctxt);
+            	else if (m_asAttr == null && (XSLFunctionService.XS_VALID_TRUE).equals(evalResultStrValue)) {
+            	   XObject valToBeValidated = (((XSLConstructorStylesheetOrExtensionFunction)selectExpression).getArg(0)).execute(xctxt);
           	       evalResult = valToBeValidated; 	
             	}
                 
@@ -436,14 +438,13 @@ public class ElemVariable extends ElemTemplateElement
             return evalResult; 
         }
         else if (selectExpression instanceof Operation) {
-            Operation opn = (Operation)selectExpression;
-            XObject leftOperand = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
-                                                                                 xctxt, opn.getLeftOperand(), transformer);
-            XObject rightOperand = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
-                                                                                 xctxt, opn.getRightOperand(), transformer);
+        	Operation xpathOperation = (Operation)selectExpression;            
+            XObject leftOperand = (xpathOperation.getLeftOperand()).execute(xctxt);
+            XObject rightOperand = (xpathOperation.getRightOperand()).execute(xctxt);
+            
             XObject evalResult = null;
             try {
-               evalResult = opn.operate(leftOperand, rightOperand);
+               evalResult = xpathOperation.operate(leftOperand, rightOperand);
             }
             catch (TransformerException ex) {
                throw new TransformerException(ex.getMessage(), srcLocator); 
@@ -601,23 +602,22 @@ public class ElemVariable extends ElemTemplateElement
         }
       }
       else if (null == getFirstChildElem()) {
-         var = XString.EMPTYSTRING;
+          var = XString.EMPTYSTRING;
       }
       else {
-        int rootNodeHandleOfRtf;
-        
-	    if (m_parentNode instanceof Stylesheet) {
-	       // Global variable
-		   rootNodeHandleOfRtf = transformer.transformToGlobalRTF(this);
-	    }
-		else {
-		   rootNodeHandleOfRtf = transformer.transformToRTF(this);
-		}
-		
-		// With XSLT 3.0, RTFs are treated as XDM node sets
-		NodeList nodeList = (new XRTreeFrag(rootNodeHandleOfRtf, xctxt, this)).convertToNodeset();		
-		
-		var = new XNodeSetForDOM(nodeList, xctxt);
+    	  int rootNodeHandleOfRtf;
+
+    	  if (m_parentNode instanceof Stylesheet) {
+    		  // Global variable
+    		  rootNodeHandleOfRtf = transformer.transformToGlobalRTF(this);
+    	  }
+    	  else {
+    		  rootNodeHandleOfRtf = transformer.transformToRTF(this);
+    	  }
+
+    	  NodeList nodeList = (new XRTreeFrag(rootNodeHandleOfRtf, xctxt, this)).convertToNodeset();		
+
+    	  var = new XNodeSetForDOM(nodeList, xctxt);
       }
     }
     finally {      
@@ -630,8 +630,7 @@ public class ElemVariable extends ElemTemplateElement
           
           try {
              ElemFunction elemFunction = ElemFunction.getXSLFunctionService();
-             variableConvertedVal = elemFunction.preprocessXslFunctionOrAVariableResult((XNodeSetForDOM)var, 
-                                                                                                m_asAttr, xctxt, m_qname);
+             variableConvertedVal = elemFunction.preprocessXslFunctionOrAVariableResult(var, m_asAttr, xctxt, m_qname);
           }
           catch (TransformerException ex) {
              throw new TransformerException(ex.getMessage(), srcLocator); 
diff --git a/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java b/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java
deleted file mode 100644
index 39747834b..000000000
--- a/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.templates;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.HashMap;
-
-import javax.xml.XMLConstants;
-import javax.xml.transform.SourceLocator;
-import javax.xml.transform.TransformerException;
-
-import org.apache.xalan.transformer.TransformerImpl;
-import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
-import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
-import org.apache.xerces.impl.dv.xs.XSSimpleTypeDecl;
-import org.apache.xerces.impl.xs.XMLSchemaLoader;
-import org.apache.xerces.xs.XSModel;
-import org.apache.xml.utils.QName;
-import org.apache.xpath.Expression;
-import org.apache.xpath.ExpressionNode;
-import org.apache.xpath.XPathContext;
-import org.apache.xpath.compiler.Keywords;
-import org.apache.xpath.functions.FuncExtFunction;
-import org.apache.xpath.objects.ResultSequence;
-import org.apache.xpath.objects.XObject;
-import org.apache.xpath.types.XSByte;
-import org.apache.xpath.types.XSNegativeInteger;
-import org.apache.xpath.types.XSNonNegativeInteger;
-import org.apache.xpath.types.XSNonPositiveInteger;
-import org.apache.xpath.types.XSPositiveInteger;
-import org.apache.xpath.types.XSShort;
-import org.apache.xpath.types.XSUnsignedByte;
-import org.apache.xpath.types.XSUnsignedInt;
-import org.apache.xpath.types.XSUnsignedLong;
-import org.apache.xpath.types.XSUnsignedShort;
-import org.w3c.dom.DOMConfiguration;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.bootstrap.DOMImplementationRegistry;
-import org.w3c.dom.ls.DOMImplementationLS;
-import org.w3c.dom.ls.LSSerializer;
-
-import xml.xpath31.processor.types.XSAnyURI;
-import xml.xpath31.processor.types.XSBoolean;
-import xml.xpath31.processor.types.XSDate;
-import xml.xpath31.processor.types.XSDateTime;
-import xml.xpath31.processor.types.XSDayTimeDuration;
-import xml.xpath31.processor.types.XSDecimal;
-import xml.xpath31.processor.types.XSDouble;
-import xml.xpath31.processor.types.XSDuration;
-import xml.xpath31.processor.types.XSFloat;
-import xml.xpath31.processor.types.XSInt;
-import xml.xpath31.processor.types.XSInteger;
-import xml.xpath31.processor.types.XSLong;
-import xml.xpath31.processor.types.XSNormalizedString;
-import xml.xpath31.processor.types.XSQName;
-import xml.xpath31.processor.types.XSString;
-import xml.xpath31.processor.types.XSTime;
-import xml.xpath31.processor.types.XSToken;
-import xml.xpath31.processor.types.XSYearMonthDuration;
-
-/**
- * A utility class that primarily supports, evaluations of XSLT stylesheet
- * function calls (for the stylesheet functions, defined with syntax 
- * xsl:function), and XPath 3.1 constructor function calls.  
- * 
- * @author Mukul Gandhi <mu...@apache.org>
- * 
- * @xsl.usage advanced
- */
-public class XSConstructorFunctionUtil {
-	
-	// The following class field declarations specify constants used by implementation
-	// within this class, and also within few other parts of Xalan-J's XSLT 3.0 
-	// implementation.				
-	
-	public static final String UTF_16 = "UTF-16";
-	
-	public static final String UTF_8 = "UTF-8";
-	
-	public static final String XML_DOM_FORMAT_PRETTY_PRINT = "format-pretty-print";
-	
-	public static final String XS_VALID_TRUE = "XS_VALID_TRUE";
-    
-    /**
-     * We use this method, primarily to evaluate XSLT stylesheet function calls (for the
-     * stylesheet functions, defined with syntax xsl:function), and XPath 3.1 constructor
-     * function calls (having syntax with form xs:type_name(..)).
-     * 
-     *  Xalan-J's extension function handling mechanism, treats at a syntactic level,
-     *  function calls belonging to non-null XML namespaces as calls to extension functions.
-     *  
-     *  Currently, XPath function calls having XML namespaces
-     *  http://www.w3.org/2005/xpath-functions, http://www.w3.org/2005/xpath-functions/math
-     *  within function names, are treated as XPath built-in functions by Xalan-J. All other
-     *  XPath function calls having other non-null XML namespaces are handling by Xalan-J's
-     *  extension function handling mechanism.
-     */
-    public static XObject processFuncExtFunctionOrXPathOpn(XPathContext xctxt, Expression expr, 
-                                                           TransformerImpl transformer) throws TransformerException {        
-        XObject evalResult = null;
-        
-        SourceLocator srcLocator = xctxt.getSAXLocator();
-        
-        StylesheetRoot stylesheetRoot = null;
-        
-        FuncExtFunction funcExtFunction = null;
-        String funcName = null;
-        String funcNamespace = null;
-        
-        try {        
-	        if (expr instanceof FuncExtFunction) {
-	            funcExtFunction = (FuncExtFunction)expr;	            
-	            funcName = funcExtFunction.getFunctionName();
-	            funcNamespace = funcExtFunction.getNamespace();
-	            
-	            ExpressionNode expressionNode = expr.getExpressionOwner();
-	            ExpressionNode stylesheetRootNode = null;
-	            while (expressionNode != null) {
-	                stylesheetRootNode = expressionNode;
-	                expressionNode = expressionNode.exprGetParent();                     
-	            }
-	            
-	            stylesheetRoot = (StylesheetRoot)stylesheetRootNode;
-	            
-	            if (transformer == null) {
-	               transformer = stylesheetRoot.getTransformerImpl();  
-	            }
-	            
-	            TemplateList templateList = stylesheetRoot.getTemplateListComposed();
-	            
-	            ElemTemplate elemTemplate = templateList.getTemplate(new QName(funcNamespace, funcName));
-	                        
-	            if ((elemTemplate != null) && (elemTemplate instanceof ElemFunction)) {
-	                // Handle call to XSLT stylesheet function definition, specified with syntax 
-	                // xsl:function.                
-	                ResultSequence argSequence = new ResultSequence();
-	                for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                    XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                    argSequence.add(argVal);
-	                }
-	                
-	                evalResult = ((ElemFunction)elemTemplate).executeXslFunction(transformer, argSequence);
-	            }            
-	            else if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(funcExtFunction.getNamespace())) {                
-	                // Handle call to XPath 3.1 constructor function, having syntax with form
-	                // xs:type_name(..). 
-	                ResultSequence argSequence = new ResultSequence();
-	                ResultSequence evalResultSequence = null;
-	                
-	                switch (funcExtFunction.getFunctionName()) {
-	                    case Keywords.XS_STRING :                        
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSString(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSString()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_NORMALIZED_STRING :                        
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSNormalizedString(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSNormalizedString()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_TOKEN :                        
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSToken(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSToken()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_DECIMAL :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSDecimal(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSDecimal()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_FLOAT :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSFloat(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSFloat()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;                
-	                    case Keywords.XS_DOUBLE :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSDouble(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSDouble()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;                
-	                    case Keywords.XS_INTEGER :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSInteger()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0); 
-	                        
-	                        break;
-	                    case Keywords.XS_NON_POSITIVE_INTEGER :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSNonPositiveInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSNonPositiveInteger()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0); 
-	                        
-	                        break;
-	                    case Keywords.XS_NEGATIVE_INTEGER :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSNegativeInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSNegativeInteger()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0); 
-	                        
-	                        break;
-	                    case Keywords.XS_NON_NEGATIVE_INTEGER :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSNonNegativeInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSNonNegativeInteger()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0); 
-	                        
-	                        break;
-	                    case Keywords.XS_POSITIVE_INTEGER :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSPositiveInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSPositiveInteger()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0); 
-	                        
-	                        break;
-	                    case Keywords.XS_LONG :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSLong(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSLong()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_INT :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSInt(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSInt()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_SHORT :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSShort(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSShort()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_BYTE :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSByte(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSByte()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_UNSIGNED_LONG :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSUnsignedLong(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSUnsignedLong()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_UNSIGNED_INT :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSUnsignedInt(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSUnsignedInt()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_UNSIGNED_SHORT :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSUnsignedShort(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSUnsignedShort()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_UNSIGNED_BYTE :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSUnsignedByte(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSUnsignedByte()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.FUNC_BOOLEAN_STRING :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            String argStrVal = XslTransformEvaluationHelper.getStrVal(argVal);
-	                            Boolean boolVal = Boolean.valueOf(("0".equals(argStrVal) || "false".equals(argStrVal)) ? 
-	                                                                                                     "false" : "true");
-	                            argSequence.add(new XSBoolean(boolVal));
-	                        }
-	    
-	                        evalResultSequence = (new XSBoolean()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_DATE :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(XSDate.parseDate(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSDate()).constructor(argSequence); 
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_DATETIME :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(XSDateTime.parseDateTime(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSDateTime()).constructor(argSequence); 
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_DURATION :
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            String strVal = XslTransformEvaluationHelper.getStrVal(argVal);
-	                            XSDuration xsDuration = XSDuration.parseDuration(strVal);
-	                            if (xsDuration != null) {
-	                               argSequence.add(xsDuration);
-	                               evalResultSequence = (new XSDuration()).constructor(argSequence); 
-	                               evalResult = evalResultSequence.item(0);
-	                            }
-	                            else {
-	                               throw new TransformerException("FORG0001 : An incorrectly formatted xs:duration value '" + 
-	                                                                                               strVal + "' is present in the input.", srcLocator); 
-	                            }
-	                        }
-	                        
-	                        break;
-	                    case Keywords.XS_YEAR_MONTH_DURATION :                   
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            String strVal = XslTransformEvaluationHelper.getStrVal(argVal);
-	                            XSDuration xsDuration = XSYearMonthDuration.parseYearMonthDuration(strVal);
-	                            if (xsDuration != null) {
-	                               argSequence.add(xsDuration);
-	                               evalResultSequence = (new XSYearMonthDuration()).constructor(argSequence); 
-	                               evalResult = evalResultSequence.item(0);
-	                            }
-	                            else {
-	                               throw new TransformerException("FORG0001 : An incorrectly formatted xs:yearMonthDuration value '" + 
-	                                                                                                strVal + "' is present in the input.", srcLocator); 
-	                            }
-	                        }
-	                        
-	                        break;
-	                    case Keywords.XS_DAY_TIME_DURATION :                 
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            String strVal = XslTransformEvaluationHelper.getStrVal(argVal);
-	                            XSDuration xsDuration = XSDayTimeDuration.parseDayTimeDuration(strVal);
-	                            if (xsDuration != null) {
-	                               argSequence.add(xsDuration);
-	                               evalResultSequence = (new XSDayTimeDuration()).constructor(argSequence); 
-	                               evalResult = evalResultSequence.item(0);
-	                            }
-	                            else {
-	                               throw new TransformerException("FORG0001 : An incorrectly formatted xs:dayTimeDuration value '" + 
-	                                                                                                strVal + "' is present in the input.", srcLocator); 
-	                            }                            
-	                        }
-	                        
-	                        break;
-	                    case Keywords.XS_TIME :                 
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            String strVal = XslTransformEvaluationHelper.getStrVal(argVal);
-	                            XSTime xsTime = XSTime.parseTime(strVal);
-	                            if (xsTime != null) {
-	                               argSequence.add(xsTime);
-	                               evalResultSequence = (new XSTime()).constructor(argSequence); 
-	                               evalResult = evalResultSequence.item(0);
-	                            }
-	                            else {
-	                               throw new TransformerException("FORG0001 : An incorrectly formatted xs:time value '" + 
-	                                                                                                         strVal + "' is present in the input.", srcLocator); 
-	                            }                            
-	                        }
-	                        
-	                        break;
-	                    case Keywords.XS_ANY_URI :                        
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            argSequence.add(new XSAnyURI(XslTransformEvaluationHelper.getStrVal(argVal)));
-	                        }
-	    
-	                        evalResultSequence = (new XSAnyURI()).constructor(argSequence);
-	                        evalResult = evalResultSequence.item(0);
-	                        
-	                        break;
-	                    case Keywords.XS_QNAME :
-	                    	XSQName xsQName = new XSQName();
-	                        for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
-	                            XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
-	                            String argStrVal = XslTransformEvaluationHelper.getStrVal(argVal);
-	                            if (idx == 0) {
-	                            	xsQName.setPrefix(argStrVal);	
-	                            }
-	                            else if (idx == 1) {
-	                            	xsQName.setLocalPart(argStrVal);
-	                            }
-	                            else {
-	                            	xsQName.setNamespaceUri(argStrVal);
-	                            }
-	                        }
-	                        
-	                        evalResult = xsQName;
-	                        
-	                        break;
-	                    default:
-	                       // no op
-	                  }
-	             }	             
-	        }
-	        else {
-	           evalResult = expr.execute(xctxt);   
-	        }
-        }
-        catch (TransformerException ex) {
-            throw new TransformerException(ex.getMessage(), srcLocator); 
-        }
-        
-        if ((evalResult == null) && (funcNamespace != null) && !(XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(funcNamespace) || 
-        		                                                (Constants.S_EXTENSIONS_JAVA_URL).equals(funcNamespace))) {
-        	HashMap stylesheetAvailableElems = stylesheetRoot.getAvailableElements();
-        	if (stylesheetAvailableElems.containsKey(new QName(Constants.S_XSLNAMESPACEURL, Constants.ELEMNAME_IMPORT_SCHEMA_STRING))) {
-        	   Node elemTemplateElem = stylesheetRoot.getFirstChildElem();
-        	   
-        	   while (elemTemplateElem != null && !(Constants.ELEMNAME_IMPORT_SCHEMA_STRING).equals(elemTemplateElem.getLocalName())) {   
-        		   elemTemplateElem = elemTemplateElem.getNextSibling();
-        	   }
-        	   
-        	   if ((Constants.ELEMNAME_IMPORT_SCHEMA_STRING).equals(elemTemplateElem.getLocalName())) {
-        		   NodeList nodeList = elemTemplateElem.getChildNodes();
-        		   Node xsSchemaTopMostNode = nodeList.item(0);
-        		   
-        		   // We shall attempt to use here, XercesJ's XMLSchemaLoader object
-        		   // instance to try constructing an XSModel object instance (which
-        		   // is a compiled representation of an XML Schema document).
-        		   XMLSchemaLoader xsLoader = new XMLSchemaLoader();
-        		   
-        		   XSModel xsModel = null;
-        		   
-        		   if (xsSchemaTopMostNode == null) {
-        			   // We shall attempt here to construct, an XML Schema XSModel instance via schema document 
-        			   // uri referred by an attribute value 'schema-location'. 
-        			   NamedNodeMap importSchemaNodeAttributes = ((Element)elemTemplateElem).getAttributes();        			   
-        			   
-        			   if (importSchemaNodeAttributes != null) {
-	        			   Node attrNode1 = importSchemaNodeAttributes.item(0);
-	        			   Node attrNode2 = importSchemaNodeAttributes.item(1);	        			   	        			   	        			   
-	        			   
-	        			   try {
-		        			   if (attrNode1 != null) {
-		        				   URI inpUri = new URI(attrNode1.getNodeValue());
-		        				   String stylesheetSystemId = srcLocator.getSystemId();
-		        				   
-		        				   if (!inpUri.isAbsolute() && (stylesheetSystemId != null)) {
-		        			          URI resolvedUri = (new URI(stylesheetSystemId)).resolve(inpUri);
-		        			          URL url = resolvedUri.toURL(); 
-		        			          if (!"namespace".equals(attrNode1.getNodeName())) {
-		        			             xsModel = xsLoader.loadURI(url.toString());
-		        			          }
-		        			       }
-		        			   }
-	        			   
-	        			       if (attrNode2 != null && xsModel == null) {
-	        			    	   URI inpUri = new URI(attrNode2.getNodeValue());
-		        				   String stylesheetSystemId = srcLocator.getSystemId();
-		        				   
-		        				   if (!inpUri.isAbsolute() && (stylesheetSystemId != null)) {
-		        			          URI resolvedUri = (new URI(stylesheetSystemId)).resolve(inpUri);
-		        			          URL url = resolvedUri.toURL();
-		        			          if ("schema-location".equals(attrNode2.getNodeName())) {
-		        			             xsModel = xsLoader.loadURI(url.toString());
-		        			          }
-		        			       }	        				  
-	        			       }
-	        			       
-	        			       if (xsModel != null) {
-		        			       XSSimpleTypeDecl xsSimpleTypeDecl = (XSSimpleTypeDecl)(xsModel.getTypeDefinition(funcName, funcNamespace));
-			        	           
-			        	           XObject xsSimpleTypeInpObj = (funcExtFunction.getArg(0)).execute(xctxt);
-			        	           xsSimpleTypeDecl.validate(xsSimpleTypeInpObj.str(), null, null);
-			        	           
-			        	           evalResult = new XSString(XS_VALID_TRUE);
-	        			       }
-	        			       else {
-	        			    	   throw new javax.xml.transform.TransformerException("FODC0005 : While analyzing xsl:import-schema instruction, a compiled "
-	        			    	   		                                                      + "representation of a an XML Schema document cannot be built. "
-	        			    	   		                                                      + "Please check the stylesheet context to resolve.", srcLocator);
-	        			       }
-	        			   }
-	        			   catch (URISyntaxException ex) {
-	        				   throw new javax.xml.transform.TransformerException("FODC0005 : The uri analyzed, while processing xsl:import-schema "
-	        				   		                                                          + "instruction is not a valid absolute uri, "
-                                                                                              + "or cannot be resolved to an absolute uri.", srcLocator);   
-	        			   }
-	        			   catch (MalformedURLException ex) {
-	        				   throw new javax.xml.transform.TransformerException("FODC0005 : The uri analyzed, while processing xsl:import-schema "
-	        				   		                                                          + "instruction is not a valid absolute uri, "
-                                                                                              + "or cannot be resolved to an absolute uri.", srcLocator); 
-	        			   }
-	        			   catch (InvalidDatatypeValueException ex) {
-	        				   throw new TransformerException(ex.getMessage(), srcLocator);
-	        			   }
-        			   }
-        		   }
-        		   else {
-        			   // We shall attempt here to construct, an XML Schema XSModel instance via lexical 
-        			   // schema document information available as child contents of an element node 
-        			   // xsl:import-schema.
-        			   String xsSchemaStr = null;
-        			   
-	        		   try {
-	        		       DOMImplementationLS domImplLS = (DOMImplementationLS)((DOMImplementationRegistry.
-	        		    		                                                                        newInstance()).getDOMImplementation("LS"));
-	        		       LSSerializer lsSerializer = domImplLS.createLSSerializer();
-	        	           DOMConfiguration domConfig = lsSerializer.getDomConfig();
-	        	           domConfig.setParameter(XML_DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE);
-	        	           xsSchemaStr = lsSerializer.writeToString((Document)xsSchemaTopMostNode);
-	        	           xsSchemaStr = xsSchemaStr.replaceFirst(UTF_16, UTF_8);
-	        	           xsSchemaStr = xsSchemaStr.replaceFirst("schema", "schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"");
-	        	           
-	        	           String xsFileName = "xalan_1_" + System.currentTimeMillis() + ".xsd";
-	        	           BufferedWriter buffWriter = new BufferedWriter(new FileWriter(xsFileName));
-	        	           buffWriter.write(xsSchemaStr);	            	           
-	        	           buffWriter.close();	            	           	            	           
-
-	        	           xsModel = xsLoader.loadURI(xsFileName);
-	        	           
-	        	           // The purpose of temporary file created here has been achieved. We could delete this file now.
-	        	           (new File(xsFileName)).delete();
-	        	           
-	        	           XSSimpleTypeDecl xsSimpleTypeDecl = (XSSimpleTypeDecl)(xsModel.getTypeDefinition(funcName, funcNamespace));
-	        	           
-	        	           XObject xsSimpleTypeInpObj = (funcExtFunction.getArg(0)).execute(xctxt);
-	        	           xsSimpleTypeDecl.validate(xsSimpleTypeInpObj.str(), null, null);
-	        	           
-	        	           evalResult = new XSString(XS_VALID_TRUE); 
-	        		   }
-	        		   catch (InvalidDatatypeValueException ex) {
-	        			   throw new TransformerException(ex.getMessage(), srcLocator); 
-	        		   }
-	        		   catch (Exception ex) {
-	        			   throw new TransformerException(ex.getMessage(), srcLocator);
-	        		   }
-        		   }
-        	   }
-        	}
-        }
-
-        return evalResult;
-        
-    }
-    
-}
diff --git a/src/org/apache/xalan/transformer/TransformerImpl.java b/src/org/apache/xalan/transformer/TransformerImpl.java
index 75e585a88..3fec3237d 100644
--- a/src/org/apache/xalan/transformer/TransformerImpl.java
+++ b/src/org/apache/xalan/transformer/TransformerImpl.java
@@ -90,7 +90,7 @@ import org.apache.xpath.Arg;
 import org.apache.xpath.ExtensionsProvider;
 import org.apache.xpath.VariableStack;
 import org.apache.xpath.XPathContext;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.objects.XObject;
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
@@ -481,7 +481,7 @@ public class TransformerImpl extends Transformer
                                         getXPathContext().getExpressionContext());   
   }
 
-  public Object extFunction(FuncExtFunction extFunction, Vector argVec)
+  public Object extFunction(XSLConstructorStylesheetOrExtensionFunction extFunction, Vector argVec)
             throws javax.xml.transform.TransformerException
   {
     return getExtensionsTable().extFunction(extFunction, argVec,
diff --git a/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java b/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java
index 3571e31af..bfb6fa566 100644
--- a/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java
+++ b/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java
@@ -27,7 +27,6 @@ import java.util.List;
 import javax.xml.transform.TransformerException;
 
 import org.apache.xalan.templates.XMLNSDecl;
-import org.apache.xalan.templates.XSConstructorFunctionUtil;
 import org.apache.xml.dtm.DTM;
 import org.apache.xml.dtm.DTMIterator;
 import org.apache.xml.dtm.DTMManager;
@@ -39,6 +38,7 @@ import org.apache.xpath.axes.LocPathIterator;
 import org.apache.xpath.composite.XPathForExpr;
 import org.apache.xpath.composite.XPathSequenceConstructor;
 import org.apache.xpath.functions.Function;
+import org.apache.xpath.functions.XSLFunctionService;
 import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XNodeSet;
 import org.apache.xpath.objects.XNumber;
@@ -469,9 +469,9 @@ public class XslTransformEvaluationHelper {
     			newInstance()).getDOMImplementation("LS"));
     	LSSerializer lsSerializer = domImplLS.createLSSerializer();
     	DOMConfiguration domConfig = lsSerializer.getDomConfig();
-    	domConfig.setParameter(XSConstructorFunctionUtil.XML_DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE);
+    	domConfig.setParameter(XSLFunctionService.XML_DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE);
     	resultStr = lsSerializer.writeToString(node);
-    	resultStr = resultStr.replaceFirst(XSConstructorFunctionUtil.UTF_16, XSConstructorFunctionUtil.UTF_8);
+    	resultStr = resultStr.replaceFirst(XSLFunctionService.UTF_16, XSLFunctionService.UTF_8);
 
     	return resultStr;
     }
diff --git a/src/org/apache/xpath/ExtensionsProvider.java b/src/org/apache/xpath/ExtensionsProvider.java
index 8a7b32c7c..80ee7a245 100644
--- a/src/org/apache/xpath/ExtensionsProvider.java
+++ b/src/org/apache/xpath/ExtensionsProvider.java
@@ -22,7 +22,7 @@ package org.apache.xpath;
 
 import java.util.Vector;
 
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 
 /**
  * Interface that XPath objects can call to obtain access to an 
@@ -54,7 +54,7 @@ public interface ExtensionsProvider
   /**
    * Execute the extension function.
    */
-  public Object extFunction(FuncExtFunction extFunction, 
+  public Object extFunction(XSLConstructorStylesheetOrExtensionFunction extFunction, 
                             Vector argVec)
             throws javax.xml.transform.TransformerException;
 }
diff --git a/src/org/apache/xpath/XPathContext.java b/src/org/apache/xpath/XPathContext.java
index b1bffb9b9..f631e349e 100644
--- a/src/org/apache/xpath/XPathContext.java
+++ b/src/org/apache/xpath/XPathContext.java
@@ -54,6 +54,8 @@ import org.apache.xml.utils.SAXSourceLocator;
 import org.apache.xml.utils.XMLString;
 import org.apache.xpath.axes.SubContextList;
 import org.apache.xpath.compiler.FunctionTable;
+import org.apache.xpath.functions.XSLFunctionService;
+import org.apache.xpath.functions.XSLFunctionBuilder;
 import org.apache.xpath.objects.DTMXRTreeFrag;
 import org.apache.xpath.objects.XObject;
 import org.apache.xpath.objects.XString;
@@ -1495,4 +1497,8 @@ public class XPathContext extends DTMManager // implements ExpressionContext
 	  return m_default_collation;
   }
   
+  public XSLFunctionService getXSLFunctionService() {
+	  return XSLFunctionBuilder.getXSLFunctionService(); 
+  }
+  
 }
diff --git a/src/org/apache/xpath/axes/FilterExprWalker.java b/src/org/apache/xpath/axes/FilterExprWalker.java
index 9673c2f6e..38e7ce409 100644
--- a/src/org/apache/xpath/axes/FilterExprWalker.java
+++ b/src/org/apache/xpath/axes/FilterExprWalker.java
@@ -69,7 +69,7 @@ public class FilterExprWalker extends AxesWalker
     switch (stepType)
     {
     case OpCodes.OP_FUNCTION :
-    case OpCodes.OP_EXTFUNCTION :
+    case OpCodes.OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION :
     	m_mustHardReset = true;
     case OpCodes.OP_GROUP :
     case OpCodes.OP_VARIABLE :
diff --git a/src/org/apache/xpath/axes/UnionPathIterator.java b/src/org/apache/xpath/axes/UnionPathIterator.java
index c356f6977..4339bcd42 100644
--- a/src/org/apache/xpath/axes/UnionPathIterator.java
+++ b/src/org/apache/xpath/axes/UnionPathIterator.java
@@ -348,7 +348,7 @@ public class UnionPathIterator extends LocPathIterator
       switch (steptype)
       {
       case OpCodes.OP_VARIABLE :
-      case OpCodes.OP_EXTFUNCTION :
+      case OpCodes.OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION :
       case OpCodes.OP_FUNCTION :
       case OpCodes.OP_GROUP :
         loadLocationPaths(compiler, compiler.getNextOpPos(opPos), count + 1);
diff --git a/src/org/apache/xpath/axes/WalkerFactory.java b/src/org/apache/xpath/axes/WalkerFactory.java
index 5117d489f..3da3b81f6 100644
--- a/src/org/apache/xpath/axes/WalkerFactory.java
+++ b/src/org/apache/xpath/axes/WalkerFactory.java
@@ -334,7 +334,7 @@ public class WalkerFactory
       return Axis.DESCENDANT;
     case OpCodes.FROM_SELF :
       return Axis.SELF;
-    case OpCodes.OP_EXTFUNCTION :
+    case OpCodes.OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION :
     case OpCodes.OP_FUNCTION :
     case OpCodes.OP_GROUP :
     case OpCodes.OP_VARIABLE :
@@ -480,7 +480,7 @@ public class WalkerFactory
     switch (stepType)
     {
     case OpCodes.OP_VARIABLE :
-    case OpCodes.OP_EXTFUNCTION :
+    case OpCodes.OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION :
     case OpCodes.OP_FUNCTION :
     case OpCodes.OP_GROUP :
       argLen = compiler.getArgLength(opPos);
@@ -589,7 +589,7 @@ public class WalkerFactory
       case OpCodes.FROM_PRECEDING_SIBLINGS :
       case OpCodes.FROM_PARENT :
       case OpCodes.OP_VARIABLE :
-      case OpCodes.OP_EXTFUNCTION :
+      case OpCodes.OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION :
       case OpCodes.OP_FUNCTION :
       case OpCodes.OP_GROUP :
       case OpCodes.FROM_NAMESPACE :
@@ -688,7 +688,7 @@ public class WalkerFactory
       switch (stepType)
       {
       case OpCodes.OP_VARIABLE :
-      case OpCodes.OP_EXTFUNCTION :
+      case OpCodes.OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION :
       case OpCodes.OP_FUNCTION :
       case OpCodes.OP_GROUP :
         analysisResult |= BIT_FILTER;
@@ -992,7 +992,7 @@ public class WalkerFactory
     switch (stepType)
     {
     case OpCodes.OP_VARIABLE :
-    case OpCodes.OP_EXTFUNCTION :
+    case OpCodes.OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION :
     case OpCodes.OP_FUNCTION :
     case OpCodes.OP_GROUP :
       prevIsOneStepDown = false;
@@ -1002,7 +1002,7 @@ public class WalkerFactory
       switch (stepType)
       {
       case OpCodes.OP_VARIABLE :
-      case OpCodes.OP_EXTFUNCTION :
+      case OpCodes.OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION :
       case OpCodes.OP_FUNCTION :
       case OpCodes.OP_GROUP :
         expr = compiler.compile(opPos);
@@ -1133,7 +1133,7 @@ public class WalkerFactory
     switch (stepType)
     {
     case OpCodes.OP_VARIABLE :
-    case OpCodes.OP_EXTFUNCTION :
+    case OpCodes.OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION :
     case OpCodes.OP_FUNCTION :
     case OpCodes.OP_GROUP :
       argLen = compiler.getArgLength(opPos);
@@ -1183,7 +1183,7 @@ public class WalkerFactory
     switch (stepType)
     {
     case OpCodes.OP_VARIABLE :
-    case OpCodes.OP_EXTFUNCTION :
+    case OpCodes.OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION :
     case OpCodes.OP_FUNCTION :
     case OpCodes.OP_GROUP :
       prevIsOneStepDown = false;
@@ -1683,7 +1683,7 @@ public class WalkerFactory
       case OpCodes.FROM_PRECEDING_SIBLINGS :
       case OpCodes.FROM_PARENT :
       case OpCodes.OP_VARIABLE :
-      case OpCodes.OP_EXTFUNCTION :
+      case OpCodes.OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION :
       case OpCodes.OP_FUNCTION :
       case OpCodes.OP_GROUP :
       case OpCodes.FROM_NAMESPACE :
diff --git a/src/org/apache/xpath/compiler/Compiler.java b/src/org/apache/xpath/compiler/Compiler.java
index 6ab321e27..89ccb208f 100644
--- a/src/org/apache/xpath/compiler/Compiler.java
+++ b/src/org/apache/xpath/compiler/Compiler.java
@@ -41,7 +41,7 @@ import org.apache.xpath.compiler.XPathParser.XPathSequenceConsFuncArgs;
 import org.apache.xpath.composite.XPathArrayConstructor;
 import org.apache.xpath.composite.XPathForExpr;
 import org.apache.xpath.composite.XPathSequenceConstructor;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.functions.FuncExtFunctionAvailable;
 import org.apache.xpath.functions.Function;
 import org.apache.xpath.functions.WrongNumberArgsException;
@@ -254,8 +254,8 @@ public class Compiler extends OpMap
       expr = numberlit(opPos); break;
     case OpCodes.OP_ARGUMENT :
       expr = arg(opPos); break;
-    case OpCodes.OP_EXTFUNCTION :
-      expr = compileExtension(opPos); break;
+    case OpCodes.OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION :
+      expr = compileConstructorStylesheetOrExtensionFunction(opPos); break;
     case OpCodes.OP_FUNCTION :
       expr = compileFunction(opPos); break;
     case OpCodes.OP_INLINE_FUNCTION :
@@ -1605,15 +1605,15 @@ private static final boolean DEBUG = false;
   }
   
   /**
-   * Compile an extension function.
+   * Compile an XPath constructor, XSL stylesheet or an extension function.
    * 
    * @param opPos The current position in the m_opMap array.
    *
-   * @return reference to {@link org.apache.xpath.functions.FuncExtFunction} instance.
+   * @return reference to {@link org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction} instance.
    *
    * @throws TransformerException if a error occurs creating the Expression.
    */
-  private Expression compileExtension(int opPos)
+  private Expression compileConstructorStylesheetOrExtensionFunction(int opPos)
           throws TransformerException
   {
 
@@ -1634,7 +1634,7 @@ private static final boolean DEBUG = false;
     // can cache the object needed to invoke it.  This way, we only pay the
     // reflection overhead on the first call.
 
-    Function extension = new FuncExtFunction(ns, funcName, String.valueOf(getNextMethodId()));
+    Function funcObj = new XSLConstructorStylesheetOrExtensionFunction(ns, funcName, String.valueOf(getNextMethodId()));
 
     try
     {
@@ -1644,7 +1644,7 @@ private static final boolean DEBUG = false;
       {
         int nextOpPos = getNextOpPos(opPos);
 
-        extension.setArg(this.compile(opPos), i);
+        funcObj.setArg(this.compile(opPos), i);
 
         opPos = nextOpPos;
 
@@ -1656,7 +1656,7 @@ private static final boolean DEBUG = false;
       ;  // should never happen
     }
 
-    return extension;
+    return funcObj;
   }
 
   /**
diff --git a/src/org/apache/xpath/compiler/OpCodes.java b/src/org/apache/xpath/compiler/OpCodes.java
index 3d52b18a5..393447465 100644
--- a/src/org/apache/xpath/compiler/OpCodes.java
+++ b/src/org/apache/xpath/compiler/OpCodes.java
@@ -345,7 +345,7 @@ public class OpCodes
   public static final int OP_GROUP = 23;
 
   /**
-   * [OP_EXTFUNCTION] (Extension function.)
+   * [OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION] (constructor, stylesheet or extension function)
    * [length]
    * [index to namespace token]
    * [index to function name token]
@@ -360,7 +360,7 @@ public class OpCodes
    *  XObject
    * @xsl.usage advanced
    */
-  public static final int OP_EXTFUNCTION = 24;
+  public static final int OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION = 24;
 
   /**
    * [OP_FUNCTION]
diff --git a/src/org/apache/xpath/compiler/XPathParser.java b/src/org/apache/xpath/compiler/XPathParser.java
index 84205f91e..c0a2f3681 100644
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ b/src/org/apache/xpath/compiler/XPathParser.java
@@ -3802,30 +3802,13 @@ public class XPathParser
          nextToken();
          consumeExpected(':');
          
-         // int funcTok = getFunctionToken(m_token, FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI);
-         Object funcTokenObj = m_functionTable.getFunctionId(m_token);
-         int funcTok = Integer.valueOf(funcTokenObj.toString());
+         int funcTok = getFunctionToken(m_token, FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI);
 
          if (-1 == funcTok)
          {
            error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
                  new Object[] {"{" + FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI + "}" + m_token + "()"});
-         }
-         else if ((FunctionTable.XPATH_MATH_FUNC_IDS_ARR).contains(Integer.valueOf(funcTok))) {
-             funcTok = -1;
-             error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
-                   new Object[] {"{" + FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI + "}" + m_token + "()"});  
-         }
-         else if ((FunctionTable.XPATH_ARRAY_FUNC_IDS_ARR).contains(Integer.valueOf(funcTok))) {
-             funcTok = -1;
-             error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
-                   new Object[] {"{" + FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI + "}" + m_token + "()"});  
-         }
-         else if ((FunctionTable.XPATH_MAP_FUNC_IDS_ARR).contains(Integer.valueOf(funcTok))) {
-             funcTok = -1;
-             error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
-                   new Object[] {"{" + FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI + "}" + m_token + "()"});  
-         }
+         }         
 
          switch (funcTok)
          {
@@ -3854,12 +3837,7 @@ public class XPathParser
          {
            error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
                  new Object[] {"{" + FunctionTable.XPATH_BUILT_IN_MATH_FUNCS_NS_URI + "}" + m_token + "()"});
-         }
-         else if (!(FunctionTable.XPATH_MATH_FUNC_IDS_ARR).contains(Integer.valueOf(funcTok))) {
-             funcTok = -1;
-             error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
-                   new Object[] {"{" + FunctionTable.XPATH_BUILT_IN_MATH_FUNCS_NS_URI + "}" + m_token + "()"});  
-         }
+         }         
 
          switch (funcTok)
          {
@@ -3888,12 +3866,7 @@ public class XPathParser
          {
              error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
                  new Object[] {"{" + FunctionTable.XPATH_BUILT_IN_MAP_FUNCS_NS_URI + "}" + m_token + "()"});
-         }
-         else if (!(FunctionTable.XPATH_MAP_FUNC_IDS_ARR).contains(Integer.valueOf(funcTok))) {
-             funcTok = -1;
-             error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
-                   new Object[] {"{" + FunctionTable.XPATH_BUILT_IN_ARRAY_FUNCS_NS_URI + "}" + m_token + "()"});  
-         }
+         }         
 
          switch (funcTok)
          {
@@ -3922,12 +3895,7 @@ public class XPathParser
          {
            error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
                  new Object[] {"{" + FunctionTable.XPATH_BUILT_IN_ARRAY_FUNCS_NS_URI + "}" + m_token + "()"});
-         }
-         else if (!(FunctionTable.XPATH_ARRAY_FUNC_IDS_ARR).contains(Integer.valueOf(funcTok))) {
-             funcTok = -1;
-             error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
-                   new Object[] {"{" + FunctionTable.XPATH_BUILT_IN_ARRAY_FUNCS_NS_URI + "}" + m_token + "()"});  
-         }
+         }         
 
          switch (funcTok)
          {
@@ -3946,7 +3914,7 @@ public class XPathParser
          nextToken();
       }
       else {  
-        appendOp(4, OpCodes.OP_EXTFUNCTION);
+        appendOp(4, OpCodes.OP_CONSTRUCTOR_STYLESHEET_EXT_FUNCTION);
 
         m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH + 1, m_queueMark - 1);
 
@@ -3962,26 +3930,11 @@ public class XPathParser
     {
       int funcTok = getFunctionToken(m_token, FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI);
 
-      if (funcTok == -1)
+      if (-1 == funcTok)
       {
           error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
               new Object[]{"{" + FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI + "}" + m_token + "()"});
-      }
-      else if ((FunctionTable.XPATH_MATH_FUNC_IDS_ARR).contains(Integer.valueOf(funcTok))) {
-          funcTok = -1;
-          error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
-                new Object[] {"{" + FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI + "}" + m_token + "()"});  
       }      
-      else if ((FunctionTable.XPATH_MAP_FUNC_IDS_ARR).contains(Integer.valueOf(funcTok))) {
-          funcTok = -1;
-          error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
-                new Object[] {"{" + FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI + "}" + m_token + "()"});  
-      }
-      else if ((FunctionTable.XPATH_ARRAY_FUNC_IDS_ARR).contains(Integer.valueOf(funcTok))) {
-          funcTok = -1;
-          error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
-                new Object[] {"{" + FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI + "}" + m_token + "()"});  
-      }
 
       switch (funcTok)
       {
diff --git a/src/org/apache/xpath/functions/FuncDaysFromDuration.java b/src/org/apache/xpath/functions/FuncDaysFromDuration.java
index abfc042a4..19a7f2584 100644
--- a/src/org/apache/xpath/functions/FuncDaysFromDuration.java
+++ b/src/org/apache/xpath/functions/FuncDaysFromDuration.java
@@ -53,7 +53,7 @@ public class FuncDaysFromDuration extends FunctionOneArg {
               return resultSeq;
            }
             
-           XSDuration xsDuration = (XSDuration)(((FuncExtFunction)arg0).execute(xctxt));
+           XSDuration xsDuration = (XSDuration)(((XSLConstructorStylesheetOrExtensionFunction)arg0).execute(xctxt));
             
            int days = xsDuration.days();
            if (xsDuration.negative()) {
diff --git a/src/org/apache/xpath/functions/FuncHoursFromDuration.java b/src/org/apache/xpath/functions/FuncHoursFromDuration.java
index 2d347ae66..67e4ad95b 100644
--- a/src/org/apache/xpath/functions/FuncHoursFromDuration.java
+++ b/src/org/apache/xpath/functions/FuncHoursFromDuration.java
@@ -53,7 +53,7 @@ public class FuncHoursFromDuration extends FunctionOneArg {
               return resultSeq;
            }
             
-           XSDuration xsDuration = (XSDuration)(((FuncExtFunction)arg0).execute(xctxt));
+           XSDuration xsDuration = (XSDuration)(((XSLConstructorStylesheetOrExtensionFunction)arg0).execute(xctxt));
             
            int hours = xsDuration.hours();
            if (xsDuration.negative()) {
diff --git a/src/org/apache/xpath/functions/FuncMinutesFromDuration.java b/src/org/apache/xpath/functions/FuncMinutesFromDuration.java
index c1e4d5894..a47861dab 100644
--- a/src/org/apache/xpath/functions/FuncMinutesFromDuration.java
+++ b/src/org/apache/xpath/functions/FuncMinutesFromDuration.java
@@ -53,7 +53,7 @@ public class FuncMinutesFromDuration extends FunctionOneArg {
               return resultSeq;
            }
             
-           XSDuration xsDuration = (XSDuration)(((FuncExtFunction)arg0).execute(xctxt));
+           XSDuration xsDuration = (XSDuration)(((XSLConstructorStylesheetOrExtensionFunction)arg0).execute(xctxt));
             
            int minutes = xsDuration.minutes();
            if (xsDuration.negative()) {
diff --git a/src/org/apache/xpath/functions/FuncMonthsFromDuration.java b/src/org/apache/xpath/functions/FuncMonthsFromDuration.java
index 0602ba92c..30d238ea2 100644
--- a/src/org/apache/xpath/functions/FuncMonthsFromDuration.java
+++ b/src/org/apache/xpath/functions/FuncMonthsFromDuration.java
@@ -53,7 +53,7 @@ public class FuncMonthsFromDuration extends FunctionOneArg {
               return resultSeq;
            }
             
-           XSDuration xsDuration = (XSDuration)(((FuncExtFunction)arg0).execute(xctxt));
+           XSDuration xsDuration = (XSDuration)(((XSLConstructorStylesheetOrExtensionFunction)arg0).execute(xctxt));
             
            int month = xsDuration.month();
            if (xsDuration.negative()) {
diff --git a/src/org/apache/xpath/functions/FuncNot.java b/src/org/apache/xpath/functions/FuncNot.java
index 41adafbc9..2c579343b 100644
--- a/src/org/apache/xpath/functions/FuncNot.java
+++ b/src/org/apache/xpath/functions/FuncNot.java
@@ -20,11 +20,9 @@
  */
 package org.apache.xpath.functions;
 
-import org.apache.xalan.templates.XSConstructorFunctionUtil;
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.objects.XBoolean;
 import org.apache.xpath.objects.XObject;
-import org.apache.xpath.operations.Operation;
 
 /**
  * Execute the not() function.
@@ -45,15 +43,8 @@ public class FuncNot extends FunctionOneArg
    * @throws javax.xml.transform.TransformerException
    */
   public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
-  {
-      if (m_arg0 instanceof Operation) {
-             XObject result = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
-                                                                                    xctxt, m_arg0, null);
-             return result.bool() ? XBoolean.S_FALSE : XBoolean.S_TRUE; 
-      }
-      else {
-          return m_arg0.execute(xctxt).bool() ? XBoolean.S_FALSE : XBoolean.S_TRUE;
-      }
+  {      
+     return m_arg0.execute(xctxt).bool() ? XBoolean.S_FALSE : XBoolean.S_TRUE;
   }
   
 }
diff --git a/src/org/apache/xpath/functions/FuncSecondsFromDuration.java b/src/org/apache/xpath/functions/FuncSecondsFromDuration.java
index f7b93d586..c3fa96a4f 100644
--- a/src/org/apache/xpath/functions/FuncSecondsFromDuration.java
+++ b/src/org/apache/xpath/functions/FuncSecondsFromDuration.java
@@ -53,7 +53,7 @@ public class FuncSecondsFromDuration extends FunctionOneArg {
               return resultSeq;
            }
             
-           XSDuration xsDuration = (XSDuration)(((FuncExtFunction)arg0).execute(xctxt));
+           XSDuration xsDuration = (XSDuration)(((XSLConstructorStylesheetOrExtensionFunction)arg0).execute(xctxt));
             
            double seconds = xsDuration.seconds();
            if (xsDuration.negative()) {
diff --git a/src/org/apache/xpath/functions/FuncYearsFromDuration.java b/src/org/apache/xpath/functions/FuncYearsFromDuration.java
index b295b4d4e..65c84f5fa 100644
--- a/src/org/apache/xpath/functions/FuncYearsFromDuration.java
+++ b/src/org/apache/xpath/functions/FuncYearsFromDuration.java
@@ -53,7 +53,7 @@ public class FuncYearsFromDuration extends FunctionOneArg {
               return resultSeq;
            }
             
-           XSDuration xsDuration = (XSDuration)(((FuncExtFunction)arg0).execute(xctxt));
+           XSDuration xsDuration = (XSDuration)(((XSLConstructorStylesheetOrExtensionFunction)arg0).execute(xctxt));
             
            int year = xsDuration.year();
            if (xsDuration.negative()) {
diff --git a/src/org/apache/xpath/functions/FuncExtFunction.java b/src/org/apache/xpath/functions/XSLConstructorStylesheetOrExtensionFunction.java
similarity index 83%
rename from src/org/apache/xpath/functions/FuncExtFunction.java
rename to src/org/apache/xpath/functions/XSLConstructorStylesheetOrExtensionFunction.java
index f35cc4131..e489970c8 100644
--- a/src/org/apache/xpath/functions/FuncExtFunction.java
+++ b/src/org/apache/xpath/functions/XSLConstructorStylesheetOrExtensionFunction.java
@@ -25,7 +25,6 @@ import java.util.Vector;
 import javax.xml.transform.TransformerException;
 
 import org.apache.xalan.res.XSLMessages;
-import org.apache.xalan.templates.XSConstructorFunctionUtil;
 import org.apache.xpath.Expression;
 import org.apache.xpath.ExpressionNode;
 import org.apache.xpath.ExpressionOwner;
@@ -38,12 +37,12 @@ import org.apache.xpath.res.XPATHErrorResources;
 import org.apache.xpath.res.XPATHMessages;
 
 /**
- * An object of this class represents an extension call expression.  When
- * the expression executes, it calls ExtensionsTable#extFunction, and then
- * converts the result to the appropriate XObject.
+ * An object of this class represents an XPath constructor function, 
+ * XSL stylesheet function or Xalan-J's extension function.
+ * 
  * @xsl.usage advanced
  */
-public class FuncExtFunction extends Function
+public class XSLConstructorStylesheetOrExtensionFunction extends Function
 {
     static final long serialVersionUID = 5196115554693708718L;
 
@@ -165,7 +164,7 @@ public class FuncExtFunction extends Function
    *                  ExtensionsTable#extFunction in order to allow caching
    *                  of the method.
    */
-  public FuncExtFunction(java.lang.String namespace,
+  public XSLConstructorStylesheetOrExtensionFunction(java.lang.String namespace,
                          java.lang.String extensionName, Object methodKey)
   {
     //try{throw new Exception("FuncExtFunction() " + namespace + " " + extensionName);} catch (Exception e){e.printStackTrace();}
@@ -194,46 +193,43 @@ public class FuncExtFunction extends Function
     XObject result = null;
     
     try {
-       // Attempting to resolve this function call, as XSLT stylesheet function call (i.e, for
-       // functions defined with XSLT stylesheet element xsl:function), or as XPath 3.1 
-       // constructor function call (i.e, function calls with syntax xs:type_name(..), where the 
-       // XML namespace prefix 'xs' is bound to XML namespace uri http://www.w3.org/2001/XMLSchema).
-       result = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
-                                                                        xctxt, this, null);
+       // Attempting to make a call to an XPath constructor function, or an XSL 
+       // stylesheet function.
+       XSLFunctionService xslFunctionService = xctxt.getXSLFunctionService();
+       result = xslFunctionService.callFunction(this, null, xctxt);
     } 
     catch (TransformerException ex) {        
        throw new TransformerException(ex.getMessage(), xctxt.getSAXLocator());
-    }
-       
-    if (result != null) {
-       return result;
-    }
+    }           
     
-    Vector argVec = new Vector();
-    int nArgs = m_argVec.size();
+    if (result == null) {
+    	// Attempting to make a call to an XPath extension function
+    	Vector argVec = new Vector();
+    	int nArgs = m_argVec.size();
 
-    for (int i = 0; i < nArgs; i++)
-    {
-      Expression arg = (Expression) m_argVec.elementAt(i);
-      
-      XObject xobj = arg.execute(xctxt);
-      /*
-       * Should cache the arguments for func:function
-       */
-      xobj.allowDetachToRelease(false); 
-      argVec.addElement(xobj);
-    }
-    //dml
-    ExtensionsProvider extProvider = (ExtensionsProvider)xctxt.getOwnerObject();
-    Object val = extProvider.extFunction(this, argVec);
+    	for (int i = 0; i < nArgs; i++)
+    	{
+    		Expression arg = (Expression) m_argVec.elementAt(i);
 
-    if (null != val)
-    {
-      result = XObject.create(val, xctxt);
-    }
-    else
-    {
-      result = new XNull();
+    		XObject xobj = arg.execute(xctxt);
+    		/*
+    		 * Should cache the arguments for func:function
+    		 */
+    		xobj.allowDetachToRelease(false); 
+    		argVec.addElement(xobj);
+    	}
+    	//dml
+    	ExtensionsProvider extProvider = (ExtensionsProvider)xctxt.getOwnerObject();
+    	Object val = extProvider.extFunction(this, argVec);
+
+    	if (null != val)
+    	{
+    		result = XObject.create(val, xctxt);
+    	}
+    	else
+    	{
+    		result = new XNull();
+    	}
     }
 
     return result;
@@ -291,7 +287,7 @@ public class FuncExtFunction extends Function
      */
     public void setExpression(Expression exp)
     {
-    	exp.exprSetParent(FuncExtFunction.this);
+    	exp.exprSetParent(XSLConstructorStylesheetOrExtensionFunction.this);
     	m_exp = exp;
     }
   }
diff --git a/src/org/apache/xpath/functions/XSLFunctionBuilder.java b/src/org/apache/xpath/functions/XSLFunctionBuilder.java
new file mode 100644
index 000000000..35baa6078
--- /dev/null
+++ b/src/org/apache/xpath/functions/XSLFunctionBuilder.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.functions;
+
+/**
+ * A class that provides a wrapper to instantiate, an object of 
+ * class XSLFunctionService that supports evaluation of XPath
+ * constructor function calls and XSL stylesheet function calls.
+ *
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class XSLFunctionBuilder {
+	
+	public static XSLFunctionService getXSLFunctionService() {
+	   return new XSLFunctionService();	
+	}
+
+}
diff --git a/src/org/apache/xpath/functions/XSLFunctionService.java b/src/org/apache/xpath/functions/XSLFunctionService.java
new file mode 100644
index 000000000..6336df0b9
--- /dev/null
+++ b/src/org/apache/xpath/functions/XSLFunctionService.java
@@ -0,0 +1,642 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.functions;
+
+import java.io.StringReader;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.HashMap;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.templates.Constants;
+import org.apache.xalan.templates.ElemFunction;
+import org.apache.xalan.templates.ElemTemplate;
+import org.apache.xalan.templates.StylesheetRoot;
+import org.apache.xalan.templates.TemplateList;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xerces.dom.DOMInputImpl;
+import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
+import org.apache.xerces.impl.dv.xs.XSSimpleTypeDecl;
+import org.apache.xerces.impl.xs.XSLoaderImpl;
+import org.apache.xerces.xs.XSModel;
+import org.apache.xerces.xs.XSTypeDefinition;
+import org.apache.xml.utils.QName;
+import org.apache.xpath.ExpressionNode;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.compiler.Keywords;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.types.XSByte;
+import org.apache.xpath.types.XSNegativeInteger;
+import org.apache.xpath.types.XSNonNegativeInteger;
+import org.apache.xpath.types.XSNonPositiveInteger;
+import org.apache.xpath.types.XSPositiveInteger;
+import org.apache.xpath.types.XSShort;
+import org.apache.xpath.types.XSUnsignedByte;
+import org.apache.xpath.types.XSUnsignedInt;
+import org.apache.xpath.types.XSUnsignedLong;
+import org.apache.xpath.types.XSUnsignedShort;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSSerializer;
+
+import xml.xpath31.processor.types.XSAnyURI;
+import xml.xpath31.processor.types.XSBoolean;
+import xml.xpath31.processor.types.XSDate;
+import xml.xpath31.processor.types.XSDateTime;
+import xml.xpath31.processor.types.XSDayTimeDuration;
+import xml.xpath31.processor.types.XSDecimal;
+import xml.xpath31.processor.types.XSDouble;
+import xml.xpath31.processor.types.XSDuration;
+import xml.xpath31.processor.types.XSFloat;
+import xml.xpath31.processor.types.XSInt;
+import xml.xpath31.processor.types.XSInteger;
+import xml.xpath31.processor.types.XSLong;
+import xml.xpath31.processor.types.XSNormalizedString;
+import xml.xpath31.processor.types.XSQName;
+import xml.xpath31.processor.types.XSString;
+import xml.xpath31.processor.types.XSTime;
+import xml.xpath31.processor.types.XSToken;
+import xml.xpath31.processor.types.XSYearMonthDuration;
+
+/**
+ * An object of this class supports evaluation of an XPath 
+ * constructor function call, or an XSL stylesheet function 
+ * call.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class XSLFunctionService {
+	
+	// Class fields, specifying constant values used by this 
+	// implementation.				
+	
+	public static final String UTF_16 = "UTF-16";
+	
+	public static final String UTF_8 = "UTF-8";
+	
+	public static final String XML_DOM_FORMAT_PRETTY_PRINT = "format-pretty-print";
+	
+	public static final String XS_VALID_TRUE = "XS_VALID_TRUE";
+    
+	/**
+	 * Process a call to an XPath constructor function, or an XSL 
+	 * stylesheet function.
+	 * 
+	 * @param transformerImpl             xsl transformation implementation object
+	 * @param xpathExpr                   xpath expression object
+	 * @param xctxt                       xpath context object
+	 * @return                            evaluation result of an XPath function call 
+	 *                                    handled by this method.
+	 * @throws TransformerException
+	 */
+    public XObject callFunction(XSLConstructorStylesheetOrExtensionFunction xpathExpr,
+    		                    TransformerImpl transformerImpl,
+    		                    XPathContext xctxt) throws TransformerException {        
+    	
+    	XObject evalResult = null;
+
+    	SourceLocator srcLocator = xctxt.getSAXLocator();
+
+    	StylesheetRoot stylesheetRoot = null;
+
+    	try {        
+    		XSLConstructorStylesheetOrExtensionFunction funcObj = xpathExpr;
+    		
+    		String funcName = funcObj.getFunctionName();
+    		String funcNamespace = funcObj.getNamespace();
+    		
+    		if (!(Constants.S_EXTENSIONS_JAVA_URL).equals(funcNamespace)) {
+    			// Both XPath constructor (prefix:typeName) and XSL stylesheet function 
+    			// calls (xsl:function), are syntactically similar to Xalan-J XPath 
+    			// extension function calls (prefix:functionName). All the code within 
+    			// this code-block, need not run, when an XSL stylesheet specifies an 
+    			// Xalan-J XPath extension function.
+    			ExpressionNode expressionNode = xpathExpr.getExpressionOwner();
+    			ExpressionNode stylesheetRootNode = null;
+    			while (expressionNode != null) {
+    				stylesheetRootNode = expressionNode;
+    				expressionNode = expressionNode.exprGetParent();                     
+    			}
+
+    			stylesheetRoot = (StylesheetRoot)stylesheetRootNode;
+
+    			if (transformerImpl == null) {
+    				transformerImpl = stylesheetRoot.getTransformerImpl();  
+    			}
+
+    			TemplateList templateList = stylesheetRoot.getTemplateListComposed();
+
+    			ElemTemplate elemTemplate = templateList.getTemplate(new QName(funcNamespace, funcName));
+
+    			if ((elemTemplate != null) && (elemTemplate instanceof ElemFunction)) {
+    				// Evaluate XSL stylesheet function call
+    				ResultSequence argSequence = new ResultSequence();
+    				for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    					XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    					argSequence.add(argVal);
+    				}
+
+    				evalResult = ((ElemFunction)elemTemplate).evaluateXslFunction(transformerImpl, argSequence);
+    			}            
+    			else if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(funcNamespace)) {                
+    				// Evaluate XPath constructor function call, for schema types 
+    				// in XML Schema namespace.
+    				ResultSequence argSequence = new ResultSequence();
+    				ResultSequence evalResultSequence = null;
+
+    				switch (funcName) {
+    				case Keywords.XS_STRING :                        
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSString(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSString()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_NORMALIZED_STRING :                        
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSNormalizedString(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSNormalizedString()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_TOKEN :                        
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSToken(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSToken()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_DECIMAL :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSDecimal(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSDecimal()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_FLOAT :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSFloat(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSFloat()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;                
+    				case Keywords.XS_DOUBLE :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSDouble(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSDouble()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;                
+    				case Keywords.XS_INTEGER :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSInteger()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0); 
+
+    					break;
+    				case Keywords.XS_NON_POSITIVE_INTEGER :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSNonPositiveInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSNonPositiveInteger()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0); 
+
+    					break;
+    				case Keywords.XS_NEGATIVE_INTEGER :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSNegativeInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSNegativeInteger()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0); 
+
+    					break;
+    				case Keywords.XS_NON_NEGATIVE_INTEGER :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSNonNegativeInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSNonNegativeInteger()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0); 
+
+    					break;
+    				case Keywords.XS_POSITIVE_INTEGER :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSPositiveInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSPositiveInteger()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0); 
+
+    					break;
+    				case Keywords.XS_LONG :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSLong(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSLong()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_INT :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSInt(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSInt()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_SHORT :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSShort(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSShort()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_BYTE :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSByte(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSByte()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_UNSIGNED_LONG :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSUnsignedLong(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSUnsignedLong()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_UNSIGNED_INT :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSUnsignedInt(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSUnsignedInt()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_UNSIGNED_SHORT :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSUnsignedShort(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSUnsignedShort()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_UNSIGNED_BYTE :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSUnsignedByte(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSUnsignedByte()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.FUNC_BOOLEAN_STRING :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						String argStrVal = XslTransformEvaluationHelper.getStrVal(argVal);
+    						Boolean boolVal = Boolean.valueOf(("0".equals(argStrVal) || "false".equals(argStrVal)) ? 
+    								"false" : "true");
+    						argSequence.add(new XSBoolean(boolVal));
+    					}
+
+    					evalResultSequence = (new XSBoolean()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_DATE :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(XSDate.parseDate(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSDate()).constructor(argSequence); 
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_DATETIME :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(XSDateTime.parseDateTime(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSDateTime()).constructor(argSequence); 
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_DURATION :
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						String strVal = XslTransformEvaluationHelper.getStrVal(argVal);
+    						XSDuration xsDuration = XSDuration.parseDuration(strVal);
+    						if (xsDuration != null) {
+    							argSequence.add(xsDuration);
+    							evalResultSequence = (new XSDuration()).constructor(argSequence); 
+    							evalResult = evalResultSequence.item(0);
+    						}
+    						else {
+    							throw new TransformerException("FORG0001 : An incorrectly formatted xs:duration value '" + 
+    									                                            strVal + "' is present in the input.", srcLocator); 
+    						}
+    					}
+
+    					break;
+    				case Keywords.XS_YEAR_MONTH_DURATION :                   
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						String strVal = XslTransformEvaluationHelper.getStrVal(argVal);
+    						XSDuration xsDuration = XSYearMonthDuration.parseYearMonthDuration(strVal);
+    						if (xsDuration != null) {
+    							argSequence.add(xsDuration);
+    							evalResultSequence = (new XSYearMonthDuration()).constructor(argSequence); 
+    							evalResult = evalResultSequence.item(0);
+    						}
+    						else {
+    							throw new TransformerException("FORG0001 : An incorrectly formatted xs:yearMonthDuration value '" + 
+    									                                            strVal + "' is present in the input.", srcLocator); 
+    						}
+    					}
+
+    					break;
+    				case Keywords.XS_DAY_TIME_DURATION :                 
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						String strVal = XslTransformEvaluationHelper.getStrVal(argVal);
+    						XSDuration xsDuration = XSDayTimeDuration.parseDayTimeDuration(strVal);
+    						if (xsDuration != null) {
+    							argSequence.add(xsDuration);
+    							evalResultSequence = (new XSDayTimeDuration()).constructor(argSequence); 
+    							evalResult = evalResultSequence.item(0);
+    						}
+    						else {
+    							throw new TransformerException("FORG0001 : An incorrectly formatted xs:dayTimeDuration value '" + 
+    									                                             strVal + "' is present in the input.", srcLocator); 
+    						}                            
+    					}
+
+    					break;
+    				case Keywords.XS_TIME :                 
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						String strVal = XslTransformEvaluationHelper.getStrVal(argVal);
+    						XSTime xsTime = XSTime.parseTime(strVal);
+    						if (xsTime != null) {
+    							argSequence.add(xsTime);
+    							evalResultSequence = (new XSTime()).constructor(argSequence); 
+    							evalResult = evalResultSequence.item(0);
+    						}
+    						else {
+    							throw new TransformerException("FORG0001 : An incorrectly formatted xs:time value '" + 
+    									                                             strVal + "' is present in the input.", srcLocator); 
+    						}                            
+    					}
+
+    					break;
+    				case Keywords.XS_ANY_URI :                        
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						argSequence.add(new XSAnyURI(XslTransformEvaluationHelper.getStrVal(argVal)));
+    					}
+
+    					evalResultSequence = (new XSAnyURI()).constructor(argSequence);
+    					evalResult = evalResultSequence.item(0);
+
+    					break;
+    				case Keywords.XS_QNAME :
+    					XSQName xsQName = new XSQName();
+    					for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+    						XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+    						String argStrVal = XslTransformEvaluationHelper.getStrVal(argVal);
+    						if (idx == 0) {
+    							xsQName.setPrefix(argStrVal);	
+    						}
+    						else if (idx == 1) {
+    							xsQName.setLocalPart(argStrVal);
+    						}
+    						else {
+    							xsQName.setNamespaceUri(argStrVal);
+    						}
+    					}
+
+    					evalResult = xsQName;
+
+    					break;
+    				default:
+    					// no op
+    				}
+    			}
+    			else {
+    				// We check and evaluate below, XPath constructor function calls to 
+    				// XML Schema user-defined simple types.
+    				HashMap stylesheetAvailableElems = stylesheetRoot.getAvailableElements();
+
+    				if (stylesheetAvailableElems.containsKey(new QName(Constants.S_XSLNAMESPACEURL, 
+    						                                           Constants.ELEMNAME_IMPORT_SCHEMA_STRING))) {
+    					Node elemTemplateElem = stylesheetRoot.getFirstChildElem();
+
+    					while (elemTemplateElem != null && !(Constants.ELEMNAME_IMPORT_SCHEMA_STRING).equals(elemTemplateElem.getLocalName())) {   
+    						elemTemplateElem = elemTemplateElem.getNextSibling();
+    					}
+
+    					NodeList nodeList = elemTemplateElem.getChildNodes();
+    					Node xsSchemaTopMostNode = nodeList.item(0);
+
+    					XSModel xsModel = null;        		   
+    					XSLoaderImpl xsLoader = new XSLoaderImpl();
+
+    					if (xsSchemaTopMostNode != null) {
+    						// xsl:import-schema instruction's child contents, has 
+    						// XML Schema document available as string.
+    						String xmlSchemaDocumentStr = null;
+
+    						try {
+    							DOMImplementationLS domImplLS = (DOMImplementationLS)((DOMImplementationRegistry.newInstance()).getDOMImplementation("LS"));
+    							LSSerializer lsSerializer = domImplLS.createLSSerializer();
+    							DOMConfiguration domConfig = lsSerializer.getDomConfig();
+    							domConfig.setParameter(XML_DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE);
+    							xmlSchemaDocumentStr = lsSerializer.writeToString((Document)xsSchemaTopMostNode);
+    							xmlSchemaDocumentStr = xmlSchemaDocumentStr.replaceFirst(UTF_16, UTF_8);
+    							xmlSchemaDocumentStr = xmlSchemaDocumentStr.replaceFirst("schema", "schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"");
+
+    							DOMInputImpl lsInput = new DOMInputImpl();
+    							lsInput.setCharacterStream(new StringReader(xmlSchemaDocumentStr));
+
+    							xsModel = xsLoader.load(lsInput);    						
+
+    							if (xsModel != null) {
+    								XSTypeDefinition xsTypeDefinition = xsModel.getTypeDefinition(funcName, funcNamespace);
+    								if (xsTypeDefinition != null) {
+    									XSSimpleTypeDecl xsSimpleTypeDecl = (XSSimpleTypeDecl)xsTypeDefinition;
+    									XObject xsSimpleTypeInpObj = (funcObj.getArg(0)).execute(xctxt);
+    									xsSimpleTypeDecl.validate(XslTransformEvaluationHelper.getStrVal(xsSimpleTypeInpObj), null, null);
+    									evalResult = new XSString(XS_VALID_TRUE);
+    								}
+    								else {
+    									throw new javax.xml.transform.TransformerException("FODC0005 : There's no in-scope schema type definition available "
+    											                                                       + "with name {" + funcNamespace + "}:" + funcName + ".", srcLocator);							
+    								}	    							    						
+    							}
+    							else {
+    								throw new javax.xml.transform.TransformerException("FODC0005 : While processing xsl:import-schema instruction, a compiled "
+    										                                                           + "representation of an XML Schema document could not be built.", srcLocator);
+    							}
+    						}
+    						catch (InvalidDatatypeValueException ex) {
+    							throw new TransformerException(ex.getMessage(), srcLocator); 
+    						}
+    						catch (Exception ex) {
+    							throw new TransformerException(ex.getMessage(), srcLocator);
+    						} 
+    					}
+    					else {
+    						// Use an XML Schema document available, at the uri specified by xsl:import-schema 
+    						// element's attribute 'schema-location'.
+    						NamedNodeMap importSchemaNodeAttributes = ((Element)elemTemplateElem).getAttributes();        			   
+
+    						if (importSchemaNodeAttributes != null) {
+    							Node attrNode1 = importSchemaNodeAttributes.item(0);
+    							Node attrNode2 = importSchemaNodeAttributes.item(1);	        			   	        			   	        			   
+
+    							try {
+    								if (attrNode1 != null) {
+    									URI inpUri = new URI(attrNode1.getNodeValue());
+    									String stylesheetSystemId = srcLocator.getSystemId();
+
+    									if (!inpUri.isAbsolute() && (stylesheetSystemId != null)) {
+    										URI resolvedUri = (new URI(stylesheetSystemId)).resolve(inpUri);
+    										URL url = resolvedUri.toURL(); 
+    										if (!"namespace".equals(attrNode1.getNodeName())) {
+    											xsModel = xsLoader.loadURI(url.toString());
+    										}
+    									}
+    								}
+
+    								if (attrNode2 != null && xsModel == null) {
+    									URI inpUri = new URI(attrNode2.getNodeValue());
+    									String stylesheetSystemId = srcLocator.getSystemId();
+
+    									if (!inpUri.isAbsolute() && (stylesheetSystemId != null)) {
+    										URI resolvedUri = (new URI(stylesheetSystemId)).resolve(inpUri);
+    										URL url = resolvedUri.toURL();
+    										if ("schema-location".equals(attrNode2.getNodeName())) {
+    											xsModel = xsLoader.loadURI(url.toString());
+    										}
+    									}	        				  
+    								}
+
+    								if (xsModel != null) {
+    									XSTypeDefinition xsTypeDefinition = xsModel.getTypeDefinition(funcName, funcNamespace);
+    									if (xsTypeDefinition != null) {
+    										XSSimpleTypeDecl xsSimpleTypeDecl = (XSSimpleTypeDecl)xsTypeDefinition;
+    										XObject xsSimpleTypeInpObj = (funcObj.getArg(0)).execute(xctxt);
+    										xsSimpleTypeDecl.validate(XslTransformEvaluationHelper.getStrVal(xsSimpleTypeInpObj), null, null);
+    										evalResult = new XSString(XS_VALID_TRUE);
+    									}
+    									else {
+    										throw new javax.xml.transform.TransformerException("FODC0005 : There's no in-scope schema type definition available "
+    												                                                 + "with name {" + funcNamespace + "}:" + funcName + ".", srcLocator);							
+    									}
+    								}
+    								else {
+    									throw new javax.xml.transform.TransformerException("FODC0005 : While processing xsl:import-schema instruction, a compiled "
+    											                                                     + "representation of an XML Schema document could not be built.", srcLocator);
+    								}
+    							}
+    							catch (URISyntaxException ex) {
+    								throw new javax.xml.transform.TransformerException("FODC0005 : The schema uri specified with xsl:import-schema instruction "
+    										                                                         + "is not a valid absolute uri, or cannot be resolved to an absolute uri.", srcLocator);   
+    							}
+    							catch (MalformedURLException ex) {
+    								throw new javax.xml.transform.TransformerException("FODC0005 : The schema uri specified with xsl:import-schema instruction "
+    										                                                         + "is not a valid absolute uri, or cannot be resolved to an absolute uri.", srcLocator); 
+    							}
+    							catch (InvalidDatatypeValueException ex) {
+    								throw new TransformerException(ex.getMessage(), srcLocator);
+    							}
+    						}	            				 
+    					}	            			
+    				}
+    			}
+    		}
+    	}
+    	catch (TransformerException ex) {
+    		throw new TransformerException(ex.getMessage(), srcLocator); 
+    	}
+
+    	return evalResult;        
+    }
+    
+}
diff --git a/src/org/apache/xpath/jaxp/JAXPExtensionsProvider.java b/src/org/apache/xpath/jaxp/JAXPExtensionsProvider.java
index 9d025a3cc..5b4eacf1a 100644
--- a/src/org/apache/xpath/jaxp/JAXPExtensionsProvider.java
+++ b/src/org/apache/xpath/jaxp/JAXPExtensionsProvider.java
@@ -30,7 +30,7 @@ import javax.xml.xpath.XPathFunctionResolver;
 
 import org.apache.xalan.res.XSLMessages;
 import org.apache.xpath.ExtensionsProvider;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.objects.XNodeSet;
 import org.apache.xpath.objects.XObject;
 import org.apache.xpath.res.XPATHErrorResources;
@@ -155,7 +155,7 @@ public class JAXPExtensionsProvider implements ExtensionsProvider {
     /**
      * Execute the extension function.
      */
-    public Object extFunction(FuncExtFunction extFunction,
+    public Object extFunction(XSLConstructorStylesheetOrExtensionFunction extFunction,
                               Vector argVec)
         throws javax.xml.transform.TransformerException {
         try {
diff --git a/src/org/apache/xpath/operations/Operation.java b/src/org/apache/xpath/operations/Operation.java
index 802418271..957d2f41a 100644
--- a/src/org/apache/xpath/operations/Operation.java
+++ b/src/org/apache/xpath/operations/Operation.java
@@ -22,17 +22,17 @@ package org.apache.xpath.operations;
 
 import javax.xml.XMLConstants;
 
-import org.apache.xalan.templates.XSConstructorFunctionUtil;
 import org.apache.xpath.Expression;
 import org.apache.xpath.ExpressionOwner;
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.XPathVisitor;
 import org.apache.xpath.axes.SelfIteratorNoPredicate;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLFunctionService;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.objects.XObject;
 
 /**
- * The baseclass for a binary operation.
+ * The base class for an XPath binary operation.
  */
 public class Operation extends Expression implements ExpressionOwner
 {
@@ -115,10 +115,12 @@ public class Operation extends Expression implements ExpressionOwner
     
     XObject right = null;
     
-    if (m_left instanceof FuncExtFunction) {
-    	FuncExtFunction extFunction = (FuncExtFunction)m_left;
-    	if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(extFunction.getNamespace())) {
-    		left = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(xctxt, m_left, null); 
+    XSLFunctionService xslFunctionService = xctxt.getXSLFunctionService();
+    
+    if (m_left instanceof XSLConstructorStylesheetOrExtensionFunction) {
+    	XSLConstructorStylesheetOrExtensionFunction xpathFunc = (XSLConstructorStylesheetOrExtensionFunction)m_left;
+    	if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(xpathFunc.getNamespace())) {
+    		left = xslFunctionService.callFunction(xpathFunc, null, xctxt); 
     	}
     	else {
     		left = m_left.execute(xctxt, true);  
@@ -137,10 +139,10 @@ public class Operation extends Expression implements ExpressionOwner
     	left = m_left.execute(xctxt, true); 
     }
 
-    if (m_right instanceof FuncExtFunction) {
-    	FuncExtFunction extFunction = (FuncExtFunction)m_right;
-    	if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(extFunction.getNamespace())) {
-    		right = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(xctxt, m_right, null); 
+    if (m_right instanceof XSLConstructorStylesheetOrExtensionFunction) {
+    	XSLConstructorStylesheetOrExtensionFunction xpathFunc = (XSLConstructorStylesheetOrExtensionFunction)m_right;
+    	if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(xpathFunc.getNamespace())) {
+    		right = xslFunctionService.callFunction(xpathFunc, null, xctxt); 
     	}
     	else {
     		right = m_right.execute(xctxt, true);  
diff --git a/src/org/apache/xpath/operations/Range.java b/src/org/apache/xpath/operations/Range.java
index 794d79e0b..9a56aa99e 100644
--- a/src/org/apache/xpath/operations/Range.java
+++ b/src/org/apache/xpath/operations/Range.java
@@ -24,9 +24,9 @@ import java.math.BigInteger;
 
 import javax.xml.XMLConstants;
 
-import org.apache.xalan.templates.XSConstructorFunctionUtil;
 import org.apache.xpath.XPathContext;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLFunctionService;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XObject;
 
@@ -36,11 +36,6 @@ import xml.xpath31.processor.types.XSNumericType;
 /**
  * The XPath 3.1 range "to" operation.
  * 
- * An XPath range "to" expression can be used to construct a sequence of 
- * consecutive integers. Each of the operands of the XPath range "to" 
- * operator is converted as though it was an argument of a function 
- * with the expected parameter type xs:integer.
- * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
  * @xsl.usage advanced
@@ -68,10 +63,12 @@ public class Range extends Operation
       
       XObject expr2 = null;
       
-      if (m_left instanceof FuncExtFunction) {
-         FuncExtFunction extFunction = (FuncExtFunction)m_left;
-         if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(extFunction.getNamespace())) {
-            expr1 = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(xctxt, m_left, null); 
+      XSLFunctionService xslFunctionService = xctxt.getXSLFunctionService();
+      
+      if (m_left instanceof XSLConstructorStylesheetOrExtensionFunction) {
+         XSLConstructorStylesheetOrExtensionFunction xpathFunc = (XSLConstructorStylesheetOrExtensionFunction)m_left;
+         if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(xpathFunc.getNamespace())) {
+            expr1 = xslFunctionService.callFunction(xpathFunc, null, xctxt); 
          }
          else {
             expr1 = m_left.execute(xctxt, true);  
@@ -81,10 +78,10 @@ public class Range extends Operation
          expr1 = m_left.execute(xctxt, true); 
       }
           
-      if (m_right instanceof FuncExtFunction) {
-         FuncExtFunction extFunction = (FuncExtFunction)m_right;
-         if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(extFunction.getNamespace())) {
-            expr2 = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(xctxt, m_right, null); 
+      if (m_right instanceof XSLConstructorStylesheetOrExtensionFunction) {
+         XSLConstructorStylesheetOrExtensionFunction xpathFunc = (XSLConstructorStylesheetOrExtensionFunction)m_right;
+         if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(xpathFunc.getNamespace())) {
+            expr2 = xslFunctionService.callFunction(xpathFunc, null, xctxt); 
          }
          else {
             expr2 = m_right.execute(xctxt, true);  
diff --git a/src/org/apache/xpath/operations/SimpleMapOperator.java b/src/org/apache/xpath/operations/SimpleMapOperator.java
index 4b9ba1592..e1ded2377 100644
--- a/src/org/apache/xpath/operations/SimpleMapOperator.java
+++ b/src/org/apache/xpath/operations/SimpleMapOperator.java
@@ -18,14 +18,13 @@
 package org.apache.xpath.operations;
 
 import javax.xml.XMLConstants;
-import javax.xml.transform.SourceLocator;
 import javax.xml.transform.TransformerException;
 
-import org.apache.xalan.templates.XSConstructorFunctionUtil;
 import org.apache.xml.dtm.DTM;
 import org.apache.xml.dtm.DTMIterator;
 import org.apache.xpath.XPathContext;
-import org.apache.xpath.functions.FuncExtFunction;
+import org.apache.xpath.functions.XSLFunctionService;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
 import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XBoolean;
 import org.apache.xpath.objects.XNodeSet;
@@ -51,17 +50,16 @@ public class SimpleMapOperator extends Operation
 
    public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
    {
-       ResultSequence result = new ResultSequence();
-       
-       SourceLocator srcLocator = xctxt.getSAXLocator(); 
+       ResultSequence result = new ResultSequence();        
        
        XObject expr1 = null; 
                
-       if (m_left instanceof FuncExtFunction) {
-           FuncExtFunction extFunction = (FuncExtFunction)m_left;
-           if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(extFunction.getNamespace())) {
+       if (m_left instanceof XSLConstructorStylesheetOrExtensionFunction) {
+           XSLConstructorStylesheetOrExtensionFunction xpathFunc = (XSLConstructorStylesheetOrExtensionFunction)m_left;
+           if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(xpathFunc.getNamespace())) {
                try {
-                   expr1 = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(xctxt, m_left, null);
+            	   XSLFunctionService xslFunctionService = xctxt.getXSLFunctionService();
+                   expr1 = xslFunctionService.callFunction(xpathFunc, null, xctxt);
                }
                catch (TransformerException ex) {
                    throw ex; 


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