Index: c/samples/ExternalFunction/ExternalFunction.cpp
===================================================================
--- c/samples/ExternalFunction/ExternalFunction.cpp	(.../vendor/xml-xalan/1.10)	(revision 13764)
+++ c/samples/ExternalFunction/ExternalFunction.cpp	(.../trunk/3rdparty/xml-xalan)	(revision 13764)
@@ -15,9 +15,10 @@
  */
 
 #include <xalanc/Include/PlatformDefinitions.hpp>
+#include <crtdbg.h>
+#include <unicode/uclean.h>
 
 
-
 #include <cmath>
 #include <ctime>
 #if defined(XALAN_CLASSIC_IOSTREAMS)
@@ -33,13 +34,24 @@
 
 
 #include <xalanc/XalanTransformer/XalanTransformer.hpp>
+//#include <xalanc/XalanTransformer/XalanDynamicNodesetBuilder.hpp>
+#include <xalanc/XalanTransformer/XalanDocumentBuilder.hpp>
 
 
 
 #include <xalanc/XPath/Function.hpp>
 #include <xalanc/XPath/XObjectFactory.hpp>
+#include <xalanc/PlatformSupport/AttributesImpl.hpp>
+#include <xalanc/XalanDOM/XalanNamedNodeMap.hpp>
+#include <xalanc/XPath/XNodeSet.hpp>
+#include <xalanc/XPath/XObjectFactory.hpp>
 
 
+#include <xercesc/sax2/ContentHandler.hpp>
+#ifdef _MSC_VER
+#pragma warning(default: 4251)
+#endif
+XALAN_USING_XERCES(ContentHandler)
 
 XALAN_USING_XALAN(Function)
 XALAN_USING_XALAN(XPathExecutionContext)
@@ -48,6 +60,8 @@
 XALAN_USING_XALAN(XObjectPtr)
 XALAN_USING_XALAN(MemoryManagerType)
 XALAN_USING_XALAN(XalanCopyConstruct)
+XALAN_USING_XALAN(AttributesImpl)
+XALAN_USING_XALAN(XalanDocumentBuilder)
 
 // This class defines a function that will return the square root
 // of its argument.
@@ -328,12 +342,115 @@
 };
 
 
+// This class defines a function that runs the C function
+// asctime() using the current system time.
+class FunctionFoo : public Function
+{
+public:
 
+	/**
+	 * Execute an XPath function object.  The function must return a valid
+	 * object.  Extension functions should override this version of execute(),
+	 * rather than one of the other calls designed for a specific number of
+	 * arguments.
+	 *
+	 * @param executionContext executing context
+	 * @param context          current context node
+	 * @param args             vector of pointers to XObject arguments
+	 * @param locator		   Locator for the XPath expression that contains the function call
+	 * @return                 pointer to the result XObject
+	 */
+	virtual XObjectPtr
+	execute(
+			XPathExecutionContext&			executionContext,
+			XalanNode*						context,
+			const XObjectArgVectorType&		args,
+			const LocatorType*				locator) const
+	{
+/*		if (args.empty() == false)
+		{
+            XPathExecutionContext::GetAndReleaseCachedString	theGuard(executionContext);
+
+			executionContext.error(getError(theGuard.get()), context, locator);
+		}*/
+
+		XalanDocumentBuilder *theBuilder = executionContext.createDocumentBuilder();
+		if (!theBuilder) {
+			executionContext.error(XalanDOMString(L"XPathExecutionContext::createDocumentBuilder failed"));
+			return XObjectPtr();
+		}
+		ContentHandler *contentHandler = theBuilder->getContentHandler();
+		if (!contentHandler) {
+			executionContext.error(XalanDOMString(L"XalanDynamicNodeSetBuilder::getContentHandler failed"));
+			return XObjectPtr();
+		}
+		contentHandler->startDocument();
+
+		const XMLCh *emptyString = L"";
+		const AttributesImpl emptyAttributes;
+		contentHandler->startElement(emptyString, emptyString, L"sql", emptyAttributes);
+		contentHandler->startElement(emptyString, emptyString, L"metadata", emptyAttributes);
+		contentHandler->characters(L"0123456789", 10);
+		contentHandler->endElement(emptyString, emptyString, L"metadata");
+		contentHandler->endElement(emptyString, emptyString, L"sql");
+		contentHandler->endDocument();
+
+
+		// Put the document in a node-set
+		XPathExecutionContext::BorrowReturnMutableNodeRefList mnl(executionContext);
+		mnl->addNodeInDocOrder(theBuilder->getDocument(), executionContext);
+		assert(mnl->checkForDuplicates(executionContext.getMemoryManager()) == false);
+		mnl->setDocumentOrder();
+		return executionContext.getXObjectFactory().createNodeSet(mnl);
+	}
+
+	/**
+	 * Create a copy of the function object.
+	 *
+	 * @return pointer to the new object
+	 */
+	virtual FunctionFoo*
+	clone(MemoryManagerType&    theManager) const
+	{
+	    return XalanCopyConstruct(theManager, *this);
+	}
+
+protected:
+
+	/**
+	 * Get the error message to report when
+	 * the function is called with the wrong
+	 * number of arguments.
+	 *
+	 * @return function error message
+	 */
+	const XalanDOMString&
+	getError(XalanDOMString& theResult) const
+	{
+        theResult.assign("The foo() function accepts no arguments!");
+
+		return theResult;
+	}
+
+private:
+
+	// Not implemented...
+	FunctionFoo&
+	operator=(const FunctionFoo&);
+
+	bool
+	operator==(const FunctionFoo&) const;
+};
+
 int
 main(
 			int		argc,
 			char*	/* argv */[])
 {
+	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF| 
+				   /*_CRTDBG_DELAY_FREE_MEM_DF|*/_CRTDBG_LEAK_CHECK_DF);
+//	_CrtSetBreakAlloc(1082);
+
 	XALAN_USING_STD(cerr)
 	XALAN_USING_STD(endl)
 
@@ -397,6 +514,11 @@
 					XalanDOMString("cube"),
 					FunctionCube());
 
+				theXalanTransformer.installExternalFunction(
+					theNamespace,
+					XalanDOMString("foo"),
+					FunctionFoo());
+
 				// Do the transform.
 				theResult = theXalanTransformer.transform("foo.xml", "foo.xsl", "foo.out");
     
@@ -418,6 +540,7 @@
 		// Clean up the ICU, if it's integrated...
 		XalanTransformer::ICUCleanUp();
 	}
+	u_cleanup();
 
 	return theResult;
 }

