http://git-wip-us.apache.org/repos/asf/ode-console/blob/4ee2cbad/src/vendor/jquery.xpath.js
----------------------------------------------------------------------
diff --git a/src/vendor/jquery.xpath.js b/src/vendor/jquery.xpath.js
new file mode 100644
index 0000000..b2ccdb8
--- /dev/null
+++ b/src/vendor/jquery.xpath.js
@@ -0,0 +1,6352 @@
+/*
+ * jQuery XPath plugin v0.2.5
+ * https://github.com/ilinsky/jquery-xpath
+ * Copyright 2013, Sergey Ilinsky
+ * Dual licensed under the MIT and GPL licenses.
+ *
+ * Includes xpath.js - XPath 2.0 implementation in JavaScript
+ * https://github.com/ilinsky/xpath.js
+ * Copyright 2013, Sergey Ilinsky
+ * Dual licensed under the MIT and GPL licenses.
+ *
+ */
+(function () {
+
+
+var cString            = window.String,
+       cBoolean        = window.Boolean,
+       cNumber         = window.Number,
+       cObject         = window.Object,
+       cArray          = window.Array,
+       cRegExp         = window.RegExp,
+       cDate           = window.Date,
+       cFunction       = window.Function,
+       cMath           = window.Math,
+       cError          = window.Error,
+       cSyntaxError= window.SyntaxError,
+       cTypeError      = window.TypeError,
+       fIsNaN          = window.isNaN,
+       fIsFinite       = window.isFinite,
+       nNaN            = window.NaN,
+       nInfinity       = window.Infinity,
+               fString_trim    =(function() {
+               return cString.prototype.trim ? function(sValue) {return 
cString(sValue).trim();} : function(sValue) {
+                       return cString(sValue).replace(/^\s+|\s+$/g, '');
+               };
+       })(),
+       fArray_indexOf  =(function() {
+               return cArray.prototype.indexOf ? function(aValue, vItem) 
{return aValue.indexOf(vItem);} : function(aValue, vItem) {
+                       for (var nIndex = 0, nLength = aValue.length; nIndex < 
nLength; nIndex++)
+                               if (aValue[nIndex] === vItem)
+                                       return nIndex;
+                       return -1;
+               };
+       })();
+
+var sNS_XSD    = "http://www.w3.org/2001/XMLSchema";,
+       sNS_XPF = "http://www.w3.org/2005/xpath-functions";,
+       sNS_XNS = "http://www.w3.org/2000/xmlns/";,
+       sNS_XML = "http://www.w3.org/XML/1998/namespace";;
+
+
+function cException(sCode
+               , sMessage
+       ) {
+
+       this.code               = sCode;
+       this.message    =
+                                         sMessage ||
+                                         oException_messages[sCode];
+};
+
+cException.prototype   = new cError;
+
+
+var oException_messages        = {};
+oException_messages["XPDY0002"]        = "Evaluation of an expression relies 
on some part of the dynamic context that has not been assigned a value.";
+oException_messages["XPST0003"]        = "Expression is not a valid instance 
of the grammar";
+oException_messages["XPTY0004"]        = "Type is not appropriate for the 
context in which the expression occurs";
+oException_messages["XPST0008"]        = "Expression refers to an element 
name, attribute name, schema type name, namespace prefix, or variable name that 
is not defined in the static context";
+oException_messages["XPST0010"]        = "Axis not supported";
+oException_messages["XPST0017"]        = "Expanded QName and number of 
arguments in a function call do not match the name and arity of a function 
signature";
+oException_messages["XPTY0018"]        = "The result of the last step in a 
path expression contains both nodes and atomic values";
+oException_messages["XPTY0019"]        = "The result of a step (other than the 
last step) in a path expression contains an atomic value.";
+oException_messages["XPTY0020"]        = "In an axis step, the context item is 
not a node.";
+oException_messages["XPST0051"]        = "It is a static error if a QName that 
is used as an AtomicType in a SequenceType is not defined in the in-scope 
schema types as an atomic type.";
+oException_messages["XPST0081"]        = "A QName used in an expression 
contains a namespace prefix that cannot be expanded into a namespace URI by 
using the statically known namespaces.";
+oException_messages["FORG0001"]        = "Invalid value for cast/constructor.";
+oException_messages["FORG0003"]        = "fn:zero-or-one called with a 
sequence containing more than one item.";
+oException_messages["FORG0004"]        = "fn:one-or-more called with a 
sequence containing no items.";
+oException_messages["FORG0005"]        = "fn:exactly-one called with a 
sequence containing zero or more than one item.";
+oException_messages["FORG0006"]        = "Invalid argument type.";
+oException_messages["FODC0001"]        = "No context document.";
+oException_messages["FORX0001"]        = "Invalid regular expression flags.";
+oException_messages["FOCA0002"]        = "Invalid lexical value.";
+oException_messages["FOCH0002"]        = "Unsupported collation.";
+
+oException_messages["FONS0004"]        = "No namespace found for prefix.";
+
+
+function cLexer(sValue) {
+       var aMatch      = 
sValue.match(/\$?(?:(?![0-9-])(?:[\w-]+|\*):)?(?![0-9-])(?:[\w-]+|\*)|\(:|:\)|\/\/|\.\.|::|\d+(?:\.\d*)?(?:[eE][+-]?\d+)?|\.\d+(?:[eE][+-]?\d+)?|"[^"]*(?:""[^"]*)*"|'[^']*(?:''[^']*)*'|<<|>>|[!<>]=|(?![0-9-])[\w-]+:\*|\s+|./g);
+       if (aMatch) {
+               var nStack      = 0;
+               for (var nIndex = 0, nLength = aMatch.length; nIndex < nLength; 
nIndex++)
+                       if (aMatch[nIndex] == '(:')
+                               nStack++;
+                       else
+                       if (aMatch[nIndex] == ':)' && nStack)
+                               nStack--;
+                       else
+                       if (!nStack && !/^\s/.test(aMatch[nIndex]))
+                               this[this.length++]     = aMatch[nIndex];
+               if (nStack)
+                       throw new cException("XPST0003"
+                                       , "Unclosed comment"
+                       );
+       }
+};
+
+cLexer.prototype.index         = 0;
+cLexer.prototype.length        = 0;
+
+cLexer.prototype.reset = function() {
+       this.index      = 0;
+};
+
+cLexer.prototype.peek  = function(nOffset) {
+       return this[this.index +(nOffset || 0)] || '';
+};
+
+cLexer.prototype.next  = function(nOffset) {
+       return(this.index+= nOffset || 1) < this.length;
+};
+
+cLexer.prototype.back  = function(nOffset) {
+       return(this.index-= nOffset || 1) > 0;
+};
+
+cLexer.prototype.eof   = function() {
+       return this.index >= this.length;
+};
+
+
+function cDOMAdapter() {
+
+};
+
+cDOMAdapter.prototype.isNode           = function(oNode) {
+       return oNode &&!!oNode.nodeType;
+};
+
+cDOMAdapter.prototype.getProperty      = function(oNode, sName) {
+       return oNode[sName];
+};
+
+cDOMAdapter.prototype.isSameNode       = function(oNode, oNode2) {
+       return oNode == oNode2;
+};
+
+cDOMAdapter.prototype.compareDocumentPosition  = function(oNode, oNode2) {
+       return oNode.compareDocumentPosition(oNode2);
+};
+
+cDOMAdapter.prototype.lookupNamespaceURI       = function(oNode, sPrefix) {
+       return oNode.lookupNamespaceURI(sPrefix);
+};
+
+cDOMAdapter.prototype.getElementById   = function(oNode, sId) {
+       return oNode.getElementById(sId);
+};
+
+cDOMAdapter.prototype.getElementsByTagNameNS   = function(oNode, 
sNameSpaceURI, sLocalName) {
+       return oNode.getElementsByTagNameNS(sNameSpaceURI, sLocalName);
+};
+
+
+function cDynamicContext(oStaticContext, vItem, oScope, oDOMAdapter) {
+               this.staticContext      = oStaticContext;
+               this.item               = vItem;
+               this.scope              = oScope || {};
+       this.stack              = {};
+               this.DOMAdapter = oDOMAdapter || new cDOMAdapter;
+               var oDate       = new cDate,
+               nOffset = oDate.getTimezoneOffset();
+       this.dateTime   = new cXSDateTime(oDate.getFullYear(), oDate.getMonth() 
+ 1, oDate.getDate(), oDate.getHours(), oDate.getMinutes(), oDate.getSeconds() 
+ oDate.getMilliseconds() / 1000, -nOffset);
+       this.timezone   = new cXSDayTimeDuration(0, cMath.abs(~~(nOffset / 
60)), cMath.abs(nOffset % 60), 0, nOffset > 0);
+};
+
+cDynamicContext.prototype.item         = null;
+cDynamicContext.prototype.position     = 0;
+cDynamicContext.prototype.size         = 0;
+cDynamicContext.prototype.scope                = null;
+cDynamicContext.prototype.stack                = null; 
cDynamicContext.prototype.dateTime      = null;
+cDynamicContext.prototype.timezone     = null;
+cDynamicContext.prototype.staticContext        = null;
+
+cDynamicContext.prototype.pushVariable = function(sName, vValue) {
+       if (!this.stack.hasOwnProperty(sName))
+               this.stack[sName]       = [];
+       this.stack[sName].push(this.scope[sName]);
+       this.scope[sName] = vValue;
+};
+
+cDynamicContext.prototype.popVariable  = function(sName) {
+       if (this.stack.hasOwnProperty(sName)) {
+               this.scope[sName] = this.stack[sName].pop();
+               if (!this.stack[sName].length) {
+                       delete this.stack[sName];
+                       if (typeof this.scope[sName] == "undefined")
+                               delete this.scope[sName];
+               }
+       }
+};
+
+
+function cStaticContext() {
+       this.dataTypes  = {};
+       this.documents  = {};
+       this.functions  = {};
+       this.collations = {};
+       this.collections= {};
+};
+
+cStaticContext.prototype.baseURI       = null;
+cStaticContext.prototype.dataTypes     = null;
+cStaticContext.prototype.documents     = null;
+cStaticContext.prototype.functions     = null;
+cStaticContext.prototype.defaultFunctionNamespace      = null;
+cStaticContext.prototype.collations    = null;
+cStaticContext.prototype.defaultCollationName          = sNS_XPF + 
"/collation/codepoint";
+cStaticContext.prototype.collections   = null;
+cStaticContext.prototype.namespaceResolver     = null;
+cStaticContext.prototype.defaultElementNamespace       = null;
+
+var rStaticContext_uri = /^(?:\{([^\}]+)\})?(.+)$/;
+cStaticContext.prototype.setDataType           = function(sUri, fFunction) {
+       var aMatch      = sUri.match(rStaticContext_uri);
+       if (aMatch)
+               if (aMatch[1] != sNS_XSD)
+                       this.dataTypes[sUri]    = fFunction;
+};
+
+cStaticContext.prototype.getDataType           = function(sUri) {
+       var aMatch      = sUri.match(rStaticContext_uri);
+       if (aMatch)
+               return aMatch[1] == sNS_XSD ? 
hStaticContext_dataTypes[cRegExp.$2] : this.dataTypes[sUri];
+};
+
+cStaticContext.prototype.setDocument           = function(sUri, fFunction) {
+       this.documents[sUri]    = fFunction;
+};
+
+cStaticContext.prototype.setFunction           = function(sUri, fFunction) {
+       var aMatch      = sUri.match(rStaticContext_uri);
+       if (aMatch)
+               if (aMatch[1] != sNS_XPF)
+                       this.functions[sUri]    = fFunction;
+};
+
+cStaticContext.prototype.getFunction           = function(sUri) {
+       var aMatch      = sUri.match(rStaticContext_uri);
+       if (aMatch)
+               return aMatch[1] == sNS_XPF ? 
hStaticContext_functions[cRegExp.$2] : this.functions[sUri];
+};
+
+cStaticContext.prototype.setCollation          = function(sUri, fFunction) {
+       this.collations[sUri]   = fFunction;
+};
+
+cStaticContext.prototype.getCollation          = function(sUri) {
+       return this.collations[sUri];
+};
+
+
+cStaticContext.prototype.setCollection = function(sUri, fFunction) {
+       this.collections[sUri]  = fFunction;
+};
+
+cStaticContext.prototype.getURIForPrefix       = function(sPrefix) {
+       var oResolver   = this.namespaceResolver,
+               fResolver       = oResolver && oResolver.lookupNamespaceURI ? 
oResolver.lookupNamespaceURI : oResolver,
+               sNameSpaceURI;
+       if (fResolver instanceof cFunction && (sNameSpaceURI = 
fResolver.call(oResolver, sPrefix)))
+               return sNameSpaceURI;
+       if (sPrefix == 'fn')
+               return sNS_XPF;
+       if (sPrefix == 'xs')
+               return sNS_XSD;
+       if (sPrefix == "xml")
+               return sNS_XML;
+       if (sPrefix == "xmlns")
+               return sNS_XNS;
+               throw new cException("XPST0081"
+                               , "Prefix '" + sPrefix + "' has not been 
declared"
+       );
+};
+
+cStaticContext.js2xs   = function(vItem) {
+               if (typeof vItem == "boolean")
+               vItem   = new cXSBoolean(vItem);
+       else
+       if (typeof vItem == "number")
+               vItem   =(fIsNaN(vItem) ||!fIsFinite(vItem)) ? new 
cXSDouble(vItem) : fNumericLiteral_parseValue(cString(vItem));
+       else
+               vItem   = new cXSString(cString(vItem));
+               return vItem;
+};
+
+cStaticContext.xs2js   = function(vItem) {
+       if (vItem instanceof cXSBoolean)
+               vItem   = vItem.valueOf();
+       else
+       if (fXSAnyAtomicType_isNumeric(vItem))
+               vItem   = vItem.valueOf();
+       else
+               vItem   = vItem.toString();
+               return vItem;
+};
+
+var hStaticContext_functions   = {},
+       hStaticContext_signatures       = {},
+       hStaticContext_dataTypes        = {},
+       hStaticContext_operators        = {};
+
+function fStaticContext_defineSystemFunction(sName, aParameters, fFunction) {
+               hStaticContext_functions[sName] = fFunction;
+               hStaticContext_signatures[sName]        = aParameters;
+};
+
+function fStaticContext_defineSystemDataType(sName, fFunction) {
+               hStaticContext_dataTypes[sName] = fFunction;
+};
+
+
+function cExpression(sExpression, oStaticContext) {
+       var oLexer      = new cLexer(sExpression),
+               oExpr   = fExpr_parse(oLexer, oStaticContext);
+               if (!oLexer.eof())
+               throw new cException("XPST0003"
+                               , "Unexpected token beyond end of query"
+               );
+               if (!oExpr)
+               throw new cException("XPST0003"
+                               , "Expected expression"
+               );
+       this.internalExpression = oExpr;
+};
+
+cExpression.prototype.internalExpression       = null;
+
+cExpression.prototype.evaluate = function(oContext) {
+       return this.internalExpression.evaluate(oContext);
+};
+
+
+function cStringCollator() {
+
+};
+
+cStringCollator.prototype.equals       = function(sValue1, sValue2) {
+       throw "Not implemented";
+};
+
+cStringCollator.prototype.compare      = function(sValue1, sValue2) {
+       throw "Not implemented";
+};
+
+
+function cXSConstants(){};
+
+cXSConstants.ANYSIMPLETYPE_DT          = 1;
+cXSConstants.STRING_DT                         = 2;
+cXSConstants.BOOLEAN_DT                                = 3;
+cXSConstants.DECIMAL_DT                                = 4;
+cXSConstants.FLOAT_DT                          = 5;
+cXSConstants.DOUBLE_DT                         = 6;
+cXSConstants.DURATION_DT                       = 7;
+cXSConstants.DATETIME_DT                       = 8;
+cXSConstants.TIME_DT                           = 9;
+cXSConstants.DATE_DT                           = 10;
+cXSConstants.GYEARMONTH_DT                     = 11;
+cXSConstants.GYEAR_DT                          = 12;
+cXSConstants.GMONTHDAY_DT                      = 13;
+cXSConstants.GDAY_DT                           = 14;
+cXSConstants.GMONTH_DT                         = 15;
+cXSConstants.HEXBINARY_DT                      = 16;
+cXSConstants.BASE64BINARY_DT           = 17;
+cXSConstants.ANYURI_DT                         = 18;
+cXSConstants.QNAME_DT                          = 19;
+cXSConstants.NOTATION_DT                       = 20;
+cXSConstants.NORMALIZEDSTRING_DT       = 21;
+cXSConstants.TOKEN_DT                          = 22;
+cXSConstants.LANGUAGE_DT                       = 23;
+cXSConstants.NMTOKEN_DT                                = 24;
+cXSConstants.NAME_DT                           = 25;
+cXSConstants.NCNAME_DT                         = 26;
+cXSConstants.ID_DT                                     = 27;
+cXSConstants.IDREF_DT                          = 28;
+cXSConstants.ENTITY_DT                         = 29;
+cXSConstants.INTEGER_DT                                = 30;
+cXSConstants.NONPOSITIVEINTEGER_DT     = 31;
+cXSConstants.NEGATIVEINTEGER_DT                = 32;
+cXSConstants.LONG_DT                           = 33;
+cXSConstants.INT_DT                                    = 34;
+cXSConstants.SHORT_DT                          = 35;
+cXSConstants.BYTE_DT                           = 36;
+cXSConstants.NONNEGATIVEINTEGER_DT     = 37;
+cXSConstants.UNSIGNEDLONG_DT           = 38;
+cXSConstants.UNSIGNEDINT_DT                    = 39;
+cXSConstants.UNSIGNEDSHORT_DT          = 40;
+cXSConstants.UNSIGNEDBYTE_DT           = 41;
+cXSConstants.POSITIVEINTEGER_DT                = 42;
+cXSConstants.LISTOFUNION_DT                    = 43;
+cXSConstants.LIST_DT                           = 44;
+cXSConstants.UNAVAILABLE_DT                    = 45;
+
+cXSConstants.DATETIMESTAMP_DT          = 46;
+cXSConstants.DAYMONTHDURATION_DT       = 47;
+cXSConstants.DAYTIMEDURATION_DT                = 48;
+cXSConstants.PRECISIONDECIMAL_DT       = 49;
+cXSConstants.ANYATOMICTYPE_DT          = 50;
+cXSConstants.ANYTYPE_DT                                = 51;
+
+cXSConstants.XT_YEARMONTHDURATION_DT=-1;
+cXSConstants.XT_UNTYPEDATOMIC_DT       =-2;
+
+
+function cExpr() {
+       this.items      = [];
+};
+
+cExpr.prototype.items  = null;
+
+function fExpr_parse (oLexer, oStaticContext) {
+       var oItem;
+       if (oLexer.eof() ||!(oItem = fExprSingle_parse(oLexer, oStaticContext)))
+               return;
+
+               var oExpr       = new cExpr;
+       oExpr.items.push(oItem);
+       while (oLexer.peek() == ',') {
+               oLexer.next();
+               if (oLexer.eof() ||!(oItem = fExprSingle_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected expression"
+                       );
+               oExpr.items.push(oItem);
+       }
+       return oExpr;
+};
+
+cExpr.prototype.evaluate       = function(oContext) {
+       var oSequence   = [];
+       for (var nIndex = 0, nLength = this.items.length; nIndex < nLength; 
nIndex++)
+               oSequence       = 
hStaticContext_operators["concatenate"].call(oContext, oSequence, 
this.items[nIndex].evaluate(oContext));
+       return oSequence;
+};
+
+
+function cExprSingle() {
+
+};
+
+function fExprSingle_parse (oLexer, oStaticContext) {
+       if (!oLexer.eof())
+               return fIfExpr_parse(oLexer, oStaticContext)
+                       || fForExpr_parse(oLexer, oStaticContext)
+                       || fQuantifiedExpr_parse(oLexer, oStaticContext)
+                       || fOrExpr_parse(oLexer, oStaticContext);
+};
+
+
+function cForExpr() {
+       this.bindings   = [];
+       this.returnExpr = null;
+};
+
+cForExpr.prototype.bindings            = null;
+cForExpr.prototype.returnExpr  = null;
+
+function fForExpr_parse (oLexer, oStaticContext) {
+       if (oLexer.peek() == "for" && oLexer.peek(1).substr(0, 1) == '$') {
+               oLexer.next();
+
+               var oForExpr    = new cForExpr,
+                       oExpr;
+               do {
+                       oForExpr.bindings.push(fSimpleForBinding_parse(oLexer, 
oStaticContext));
+               }
+               while (oLexer.peek() == ',' && oLexer.next());
+
+               if (oLexer.peek() != "return")
+                       throw new cException("XPST0003"
+                                       , "Expected 'return' token in for 
expression"
+                       );
+
+               oLexer.next();
+               if (oLexer.eof() ||!(oExpr = fExprSingle_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected return statement operand in 
for expression"
+                       );
+
+               oForExpr.returnExpr     = oExpr;
+               return oForExpr;
+       }
+};
+
+cForExpr.prototype.evaluate    = function (oContext) {
+       var oSequence   = [];
+       (function(oSelf, nBinding) {
+               var oBinding    = oSelf.bindings[nBinding++],
+                       oSequence1      = oBinding.inExpr.evaluate(oContext),
+                       sUri    = (oBinding.namespaceURI ? '{' + 
oBinding.namespaceURI + '}' : '') + oBinding.localName;
+               for (var nIndex = 0, nLength = oSequence1.length; nIndex < 
nLength; nIndex++) {
+                       oContext.pushVariable(sUri, oSequence1[nIndex]);
+                       if (nBinding < oSelf.bindings.length)
+                               arguments.callee(oSelf, nBinding);
+                       else
+                               oSequence       = 
oSequence.concat(oSelf.returnExpr.evaluate(oContext));
+                       oContext.popVariable(sUri);
+               }
+       })(this, 0);
+
+       return oSequence;
+};
+
+function cSimpleForBinding(sPrefix, sLocalName, sNameSpaceURI, oInExpr) {
+       this.prefix                     = sPrefix;
+       this.localName          = sLocalName;
+       this.namespaceURI       = sNameSpaceURI;
+       this.inExpr             = oInExpr;
+};
+
+cSimpleForBinding.prototype.prefix                     = null;
+cSimpleForBinding.prototype.localName          = null;
+cSimpleForBinding.prototype.namespaceURI       = null;
+cSimpleForBinding.prototype.inExpr             = null;
+
+function fSimpleForBinding_parse (oLexer, oStaticContext) {
+       var aMatch      = oLexer.peek().substr(1).match(rNameTest);
+       if (!aMatch)
+               throw new cException("XPST0003"
+                               , "Expected binding in for expression"
+               );
+
+       if (aMatch[1] == '*' || aMatch[2] == '*')
+               throw new cException("XPST0003"
+                               , "Illegal use of wildcard in for expression 
binding variable name"
+               );
+
+       oLexer.next();
+       if (oLexer.peek() != "in")
+               throw new cException("XPST0003"
+                               , "Expected 'in' token in for expression 
binding"
+               );
+
+       oLexer.next();
+       var oExpr;
+       if (oLexer.eof() ||!(oExpr = fExprSingle_parse(oLexer, oStaticContext)))
+               throw new cException("XPST0003"
+                               , "Expected in statement operand in for 
expression binding"
+               );
+
+       return new cSimpleForBinding(aMatch[1] || null, aMatch[2], aMatch[1] ? 
oStaticContext.getURIForPrefix(aMatch[1]) : null, oExpr);
+};
+
+
+function cIfExpr(oCondExpr, oThenExpr, oElseExpr) {
+       this.condExpr   = oCondExpr;
+       this.thenExpr           = oThenExpr;
+       this.elseExpr           = oElseExpr;
+};
+
+cIfExpr.prototype.condExpr     = null;
+cIfExpr.prototype.thenExpr     = null;
+cIfExpr.prototype.elseExpr     = null;
+
+function fIfExpr_parse (oLexer, oStaticContext) {
+       var oCondExpr,
+               oThenExpr,
+               oElseExpr;
+       if (oLexer.peek() == "if" && oLexer.peek(1) == '(') {
+               oLexer.next(2);
+                               if (oLexer.eof() ||!(oCondExpr = 
fExpr_parse(oLexer, oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected if statement operand in 
conditional expression"
+                       );
+                               if (oLexer.peek() != ')')
+                       throw new cException("XPST0003"
+                                       , "Expected ')' token in for expression"
+                       );
+
+               oLexer.next();
+               if (oLexer.peek() != "then")
+                       throw new cException("XPST0003"
+                                       , "Expected 'then' token in conditional 
if expression"
+                       );
+
+               oLexer.next();
+               if (oLexer.eof() ||!(oThenExpr = fExprSingle_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected then statement operand in 
condional expression"
+                       );
+
+               if (oLexer.peek() != "else")
+                       throw new cException("XPST0003"
+                                       , "Expected 'else' token in conditional 
if expression"
+                       );
+
+               oLexer.next();
+               if (oLexer.eof() ||!(oElseExpr = fExprSingle_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected else statement operand in 
condional expression"
+                       );
+                               return new cIfExpr(oCondExpr, oThenExpr, 
oElseExpr);
+       }
+};
+
+cIfExpr.prototype.evaluate     = function (oContext) {
+       return this[fFunction_sequence_toEBV(this.condExpr.evaluate(oContext), 
oContext) ? "thenExpr" : "elseExpr"].evaluate(oContext);
+};
+
+
+function cQuantifiedExpr(sQuantifier) {
+       this.quantifier         = sQuantifier;
+       this.bindings           = [];
+       this.satisfiesExpr      = null;
+};
+
+cQuantifiedExpr.prototype.bindings             = null;
+cQuantifiedExpr.prototype.quantifier   = null;
+cQuantifiedExpr.prototype.satisfiesExpr        = null;
+
+function fQuantifiedExpr_parse (oLexer, oStaticContext) {
+       var sQuantifier = oLexer.peek();
+       if ((sQuantifier == "some" || sQuantifier == "every") && 
oLexer.peek(1).substr(0, 1) == '$') {
+               oLexer.next();
+
+               var oQuantifiedExpr     = new cQuantifiedExpr(sQuantifier),
+                       oExpr;
+               do {
+                       
oQuantifiedExpr.bindings.push(fSimpleQuantifiedBinding_parse(oLexer, 
oStaticContext));
+               }
+               while (oLexer.peek() == ',' && oLexer.next());
+
+               if (oLexer.peek() != "satisfies")
+                       throw new cException("XPST0003"
+                                       , "Expected 'satisfies' token in 
quantified expression"
+                       );
+
+               oLexer.next();
+               if (oLexer.eof() ||!(oExpr = fExprSingle_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected satisfies statement operand 
in quantified expression"
+                       );
+
+               oQuantifiedExpr.satisfiesExpr   = oExpr;
+               return oQuantifiedExpr;
+       }
+};
+
+cQuantifiedExpr.prototype.evaluate     = function (oContext) {
+               var bEvery      = this.quantifier == "every",
+               bResult = bEvery ? true : false;
+       (function(oSelf, nBinding) {
+               var oBinding    = oSelf.bindings[nBinding++],
+                       oSequence1      = oBinding.inExpr.evaluate(oContext),
+                       sUri    = (oBinding.namespaceURI ? '{' + 
oBinding.namespaceURI + '}' : '') + oBinding.localName;
+               for (var nIndex = 0, nLength = oSequence1.length; (nIndex < 
nLength) && (bEvery ? bResult :!bResult); nIndex++) {
+                       oContext.pushVariable(sUri, oSequence1[nIndex]);
+                       if (nBinding < oSelf.bindings.length)
+                               arguments.callee(oSelf, nBinding);
+                       else
+                               bResult = 
fFunction_sequence_toEBV(oSelf.satisfiesExpr.evaluate(oContext), oContext);
+                       oContext.popVariable(sUri);
+               }
+       })(this, 0);
+
+       return [new cXSBoolean(bResult)];
+};
+
+
+
+function cSimpleQuantifiedBinding(sPrefix, sLocalName, sNameSpaceURI, oInExpr) 
{
+       this.prefix                     = sPrefix;
+       this.localName          = sLocalName;
+       this.namespaceURI       = sNameSpaceURI;
+       this.inExpr             = oInExpr;
+};
+
+cSimpleQuantifiedBinding.prototype.prefix              = null;
+cSimpleQuantifiedBinding.prototype.localName   = null;
+cSimpleQuantifiedBinding.prototype.namespaceURI        = null;
+cSimpleQuantifiedBinding.prototype.inExpr      = null;
+
+function fSimpleQuantifiedBinding_parse (oLexer, oStaticContext) {
+       var aMatch      = oLexer.peek().substr(1).match(rNameTest);
+       if (!aMatch)
+               throw new cException("XPST0003"
+                               , "Expected binding in quantified expression"
+               );
+
+       if (aMatch[1] == '*' || aMatch[2] == '*')
+               throw new cException("XPST0003"
+                               , "Illegal use of wildcard in quantified 
expression binding variable name"
+               );
+
+       oLexer.next();
+       if (oLexer.peek() != "in")
+               throw new cException("XPST0003"
+                               , "Expected 'in' token in quantified expression 
binding"
+               );
+
+       oLexer.next();
+       var oExpr;
+       if (oLexer.eof() ||!(oExpr = fExprSingle_parse(oLexer, oStaticContext)))
+               throw new cException("XPST0003"
+                               , "Expected in statement operand in quantified 
expression binding"
+               );
+
+       return new cSimpleQuantifiedBinding(aMatch[1] || null, aMatch[2], 
aMatch[1] ? oStaticContext.getURIForPrefix(aMatch[1]) : null, oExpr);
+};
+
+
+function cComparisonExpr(oLeft, oRight, sOperator) {
+       this.left       = oLeft;
+       this.right      = oRight;
+       this.operator   = sOperator;
+};
+
+cComparisonExpr.prototype.left = null;
+cComparisonExpr.prototype.right        = null;
+cComparisonExpr.prototype.operator     = null;
+
+function fComparisonExpr_parse (oLexer, oStaticContext) {
+       var oExpr,
+               oRight;
+       if (oLexer.eof() ||!(oExpr = fRangeExpr_parse(oLexer, oStaticContext)))
+               return;
+       if (!(oLexer.peek() in hComparisonExpr_operators))
+               return oExpr;
+
+               var sOperator   = oLexer.peek();
+       oLexer.next();
+       if (oLexer.eof() ||!(oRight = fRangeExpr_parse(oLexer, oStaticContext)))
+               throw new cException("XPST0003"
+                               , "Expected second operand in comparison 
expression"
+               );
+       return new cComparisonExpr(oExpr, oRight, sOperator);
+};
+
+cComparisonExpr.prototype.evaluate     = function (oContext) {
+       var oResult     = hComparisonExpr_operators[this.operator](this, 
oContext);
+       return oResult == null ? [] : [oResult];
+};
+
+function fComparisonExpr_GeneralComp(oExpr, oContext) {
+       var oLeft       = 
fFunction_sequence_atomize(oExpr.left.evaluate(oContext), oContext);
+       if (!oLeft.length)
+               return new cXSBoolean(false);
+
+       var oRight      = 
fFunction_sequence_atomize(oExpr.right.evaluate(oContext), oContext);
+       if (!oRight.length)
+               return new cXSBoolean(false);
+
+       var bResult     = false;
+       for (var nLeftIndex = 0, nLeftLength = oLeft.length, bLeft, vLeft; 
(nLeftIndex < nLeftLength) &&!bResult; nLeftIndex++) {
+               for (var nRightIndex = 0, nRightLength = oRight.length, bRight, 
vRight; (nRightIndex < nRightLength) &&!bResult; nRightIndex++) {
+
+                       vLeft   = oLeft[nLeftIndex];
+                       vRight  = oRight[nRightIndex];
+
+                       bLeft   = vLeft instanceof cXSUntypedAtomic;
+                       bRight  = vRight instanceof cXSUntypedAtomic;
+
+                       if (bLeft && bRight) {
+                                                               vLeft   = 
cXSString.cast(vLeft);
+                               vRight  = cXSString.cast(vRight);
+                       }
+                       else {
+                                                               if (bLeft) {
+                                                                               
if (vRight instanceof cXSDayTimeDuration)
+                                               vLeft   = 
cXSDayTimeDuration.cast(vLeft);
+                                       else
+                                       if (vRight instanceof 
cXSYearMonthDuration)
+                                               vLeft   = 
cXSYearMonthDuration.cast(vLeft);
+                                       else
+                                                                               
if (vRight.primitiveKind)
+                                               vLeft   = 
hStaticContext_dataTypes[vRight.primitiveKind].cast(vLeft);
+                               }
+                               else
+                               if (bRight) {
+                                                                               
if (vLeft instanceof cXSDayTimeDuration)
+                                               vRight  = 
cXSDayTimeDuration.cast(vRight);
+                                       else
+                                       if (vLeft instanceof 
cXSYearMonthDuration)
+                                               vRight  = 
cXSYearMonthDuration.cast(vRight);
+                                       else
+                                                                               
if (vLeft.primitiveKind)
+                                               vRight  = 
hStaticContext_dataTypes[vLeft.primitiveKind].cast(vRight);
+                               }
+
+                                                               if (vLeft 
instanceof cXSAnyURI)
+                                       vLeft   = cXSString.cast(vLeft);
+                               if (vRight instanceof cXSAnyURI)
+                                       vRight  = cXSString.cast(vRight);
+                       }
+
+                       bResult = 
hComparisonExpr_ValueComp_operators[hComparisonExpr_GeneralComp_map[oExpr.operator]](vLeft,
 vRight, oContext).valueOf();
+               }
+       }
+       return new cXSBoolean(bResult);
+};
+
+var hComparisonExpr_GeneralComp_map    = {
+       '=':    'eq',
+       '!=':   'ne',
+       '>':    'gt',
+       '<':    'lt',
+       '>=':   'ge',
+       '<=':   'le'
+};
+
+function fComparisonExpr_ValueComp(oExpr, oContext) {
+       var oLeft       = 
fFunction_sequence_atomize(oExpr.left.evaluate(oContext), oContext);
+       if (!oLeft.length)
+               return null;
+               fFunctionCall_assertSequenceCardinality(oContext, oLeft, '?'
+                       , "first operand of '" + oExpr.operator + "'"
+       );
+
+       var oRight      = 
fFunction_sequence_atomize(oExpr.right.evaluate(oContext), oContext);
+       if (!oRight.length)
+               return null;
+               fFunctionCall_assertSequenceCardinality(oContext, oRight, '?'
+                       , "second operand of '" + oExpr.operator + "'"
+       );
+
+       var vLeft       = oLeft[0],
+               vRight  = oRight[0];
+
+               if (vLeft instanceof cXSUntypedAtomic)
+               vLeft   = cXSString.cast(vLeft);
+       if (vRight instanceof cXSUntypedAtomic)
+               vRight  = cXSString.cast(vRight);
+
+               if (vLeft instanceof cXSAnyURI)
+               vLeft   = cXSString.cast(vLeft);
+       if (vRight instanceof cXSAnyURI)
+               vRight  = cXSString.cast(vRight);
+
+               return 
hComparisonExpr_ValueComp_operators[oExpr.operator](vLeft, vRight, oContext);
+};
+
+var hComparisonExpr_ValueComp_operators        = {};
+hComparisonExpr_ValueComp_operators['eq']      = function(oLeft, oRight, 
oContext) {
+       var sOperator   = '';
+
+       if (fXSAnyAtomicType_isNumeric(oLeft)) {
+               if (fXSAnyAtomicType_isNumeric(oRight))
+                       sOperator       = "numeric-equal";
+       }
+       else
+       if (oLeft instanceof cXSBoolean) {
+               if (oRight instanceof cXSBoolean)
+                       sOperator       = "boolean-equal";
+       }
+       else
+       if (oLeft instanceof cXSString) {
+               if (oRight instanceof cXSString)
+                       return 
hStaticContext_operators["numeric-equal"].call(oContext, 
hStaticContext_functions["compare"].call(oContext, oLeft, oRight), new 
cXSInteger(0));
+       }
+       else
+       if (oLeft instanceof cXSDate) {
+               if (oRight instanceof cXSDate)
+                       sOperator       = "date-equal";
+       }
+       else
+       if (oLeft instanceof cXSTime) {
+               if (oRight instanceof cXSTime)
+                       sOperator       = "time-equal";
+       }
+       else
+       if (oLeft instanceof cXSDateTime) {
+               if (oRight instanceof cXSDateTime)
+                       sOperator       = "dateTime-equal";
+       }
+       else
+       if (oLeft instanceof cXSDuration) {
+               if (oRight instanceof cXSDuration)
+                       sOperator       = "duration-equal";
+       }
+       else
+       if (oLeft instanceof cXSGYearMonth) {
+               if (oRight instanceof cXSGYearMonth)
+                       sOperator       = "gYearMonth-equal";
+       }
+       else
+       if (oLeft instanceof cXSGYear) {
+               if (oRight instanceof cXSGYear)
+                       sOperator       = "gYear-equal";
+       }
+       else
+       if (oLeft instanceof cXSGMonthDay) {
+               if (oRight instanceof cXSGMonthDay)
+                       sOperator       = "gMonthDay-equal";
+       }
+       else
+       if (oLeft instanceof cXSGMonth) {
+               if (oRight instanceof cXSGMonth)
+                       sOperator       = "gMonth-equal";
+       }
+       else
+       if (oLeft instanceof cXSGDay) {
+               if (oRight instanceof cXSGDay)
+                       sOperator       = "gDay-equal";
+       }
+               else
+       if (oLeft instanceof cXSQName) {
+               if (oRight instanceof cXSQName)
+                       sOperator       = "QName-equal";
+       }
+       else
+       if (oLeft instanceof cXSHexBinary) {
+               if (oRight instanceof cXSHexBinary)
+                       sOperator       = "hexBinary-equal";
+       }
+       else
+       if (oLeft instanceof cXSBase64Binary) {
+               if (oRight instanceof cXSBase64Binary)
+                       sOperator       = "base64Binary-equal";
+       }
+
+               if (sOperator)
+               return hStaticContext_operators[sOperator].call(oContext, 
oLeft, oRight);
+
+               throw new cException("XPTY0004"
+                       , "Cannot compare values of given types"
+       );      };
+hComparisonExpr_ValueComp_operators['ne']      = function(oLeft, oRight, 
oContext) {
+       return new cXSBoolean(!hComparisonExpr_ValueComp_operators['eq'](oLeft, 
oRight, oContext).valueOf());
+};
+hComparisonExpr_ValueComp_operators['gt']      = function(oLeft, oRight, 
oContext) {
+       var sOperator   = '';
+
+       if (fXSAnyAtomicType_isNumeric(oLeft)) {
+               if (fXSAnyAtomicType_isNumeric(oRight))
+                       sOperator       = "numeric-greater-than";
+       }
+       else
+       if (oLeft instanceof cXSBoolean) {
+               if (oRight instanceof cXSBoolean)
+                       sOperator       = "boolean-greater-than";
+       }
+       else
+       if (oLeft instanceof cXSString) {
+               if (oRight instanceof cXSString)
+                       return 
hStaticContext_operators["numeric-greater-than"].call(oContext, 
hStaticContext_functions["compare"].call(oContext, oLeft, oRight), new 
cXSInteger(0));
+       }
+       else
+       if (oLeft instanceof cXSDate) {
+               if (oRight instanceof cXSDate)
+                       sOperator       = "date-greater-than";
+       }
+       else
+       if (oLeft instanceof cXSTime) {
+               if (oRight instanceof cXSTime)
+                       sOperator       = "time-greater-than";
+       }
+       else
+       if (oLeft instanceof cXSDateTime) {
+               if (oRight instanceof cXSDateTime)
+                       sOperator       = "dateTime-greater-than";
+       }
+       else
+       if (oLeft instanceof cXSYearMonthDuration) {
+               if (oRight instanceof cXSYearMonthDuration)
+                       sOperator       = "yearMonthDuration-greater-than";
+       }
+       else
+       if (oLeft instanceof cXSDayTimeDuration) {
+               if (oRight instanceof cXSDayTimeDuration)
+                       sOperator       = "dayTimeDuration-greater-than";
+       }
+
+               if (sOperator)
+               return hStaticContext_operators[sOperator].call(oContext, 
oLeft, oRight);
+
+               throw new cException("XPTY0004"
+                       , "Cannot compare values of given types"
+       );      };
+hComparisonExpr_ValueComp_operators['lt']      = function(oLeft, oRight, 
oContext) {
+       var sOperator   = '';
+
+       if (fXSAnyAtomicType_isNumeric(oLeft)) {
+               if (fXSAnyAtomicType_isNumeric(oRight))
+                       sOperator       = "numeric-less-than";
+       }
+       else
+       if (oLeft instanceof cXSBoolean) {
+               if (oRight instanceof cXSBoolean)
+                       sOperator       = "boolean-less-than";
+       }
+       else
+       if (oLeft instanceof cXSString) {
+               if (oRight instanceof cXSString)
+                       return 
hStaticContext_operators["numeric-less-than"].call(oContext, 
hStaticContext_functions["compare"].call(oContext, oLeft, oRight), new 
cXSInteger(0));
+       }
+       else
+       if (oLeft instanceof cXSDate) {
+               if (oRight instanceof cXSDate)
+                       sOperator       = "date-less-than";
+       }
+       else
+       if (oLeft instanceof cXSTime) {
+               if (oRight instanceof cXSTime)
+                       sOperator       = "time-less-than";
+       }
+       else
+       if (oLeft instanceof cXSDateTime) {
+               if (oRight instanceof cXSDateTime)
+                       sOperator       = "dateTime-less-than";
+       }
+       else
+       if (oLeft instanceof cXSYearMonthDuration) {
+               if (oRight instanceof cXSYearMonthDuration)
+                       sOperator       = "yearMonthDuration-less-than";
+       }
+       else
+       if (oLeft instanceof cXSDayTimeDuration) {
+               if (oRight instanceof cXSDayTimeDuration)
+                       sOperator       = "dayTimeDuration-less-than";
+       }
+
+               if (sOperator)
+               return hStaticContext_operators[sOperator].call(oContext, 
oLeft, oRight);
+
+               throw new cException("XPTY0004"
+                       , "Cannot compare values of given types"
+       );      };
+hComparisonExpr_ValueComp_operators['ge']      = function(oLeft, oRight, 
oContext) {
+       var sOperator   = '';
+
+       if (fXSAnyAtomicType_isNumeric(oLeft)) {
+               if (fXSAnyAtomicType_isNumeric(oRight))
+                       return 
hStaticContext_operators["numeric-greater-than"].call(oContext, oLeft, oRight) 
|| hStaticContext_operators["numeric-equal"].call(oContext, oLeft, oRight);
+       }
+       else
+       if (oLeft instanceof cXSBoolean) {
+               if (oRight instanceof cXSBoolean)
+                       sOperator       = "boolean-less-than";
+       }
+       else
+       if (oLeft instanceof cXSString) {
+               if (oRight instanceof cXSString)
+                       return 
hStaticContext_operators["numeric-greater-than"].call(oContext, 
hStaticContext_functions["compare"].call(oContext, oLeft, oRight), new 
cXSInteger(-1));
+       }
+       else
+       if (oLeft instanceof cXSDate) {
+               if (oRight instanceof cXSDate)
+                       sOperator       = "date-less-than";
+       }
+       else
+       if (oLeft instanceof cXSTime) {
+               if (oRight instanceof cXSTime)
+                       sOperator       = "time-less-than";
+       }
+       else
+       if (oLeft instanceof cXSDateTime) {
+               if (oRight instanceof cXSDateTime)
+                       sOperator       = "dateTime-less-than";
+       }
+       else
+       if (oLeft instanceof cXSYearMonthDuration) {
+               if (oRight instanceof cXSYearMonthDuration)
+                       sOperator       = "yearMonthDuration-less-than";
+       }
+       else
+       if (oLeft instanceof cXSDayTimeDuration) {
+               if (oRight instanceof cXSDayTimeDuration)
+                       sOperator       = "dayTimeDuration-less-than";
+       }
+
+               if (sOperator)
+               return new 
cXSBoolean(!hStaticContext_operators[sOperator].call(oContext, oLeft, 
oRight).valueOf());
+
+               throw new cException("XPTY0004"
+                       , "Cannot compare values of given types"
+       );      };
+hComparisonExpr_ValueComp_operators['le']      = function(oLeft, oRight, 
oContext) {
+       var sOperator   = '';
+
+       if (fXSAnyAtomicType_isNumeric(oLeft)) {
+               if (fXSAnyAtomicType_isNumeric(oRight))
+                       return 
hStaticContext_operators["numeric-less-than"].call(oContext, oLeft, oRight) || 
hStaticContext_operators["numeric-equal"].call(oContext, oLeft, oRight);
+       }
+       else
+       if (oLeft instanceof cXSBoolean) {
+               if (oRight instanceof cXSBoolean)
+                       sOperator       = "boolean-greater-than";
+       }
+       else
+       if (oLeft instanceof cXSString) {
+               if (oRight instanceof cXSString)
+                       return 
hStaticContext_operators["numeric-less-than"].call(oContext, 
hStaticContext_functions["compare"].call(oContext, oLeft, oRight), new 
cXSInteger(1));
+       }
+       else
+       if (oLeft instanceof cXSDate) {
+               if (oRight instanceof cXSDate)
+                       sOperator       = "date-greater-than";
+       }
+       else
+       if (oLeft instanceof cXSTime) {
+               if (oRight instanceof cXSTime)
+                       sOperator       = "time-greater-than";
+       }
+       else
+       if (oLeft instanceof cXSDateTime) {
+               if (oRight instanceof cXSDateTime)
+                       sOperator       = "dateTime-greater-than";
+       }
+       else
+       if (oLeft instanceof cXSYearMonthDuration) {
+               if (oRight instanceof cXSYearMonthDuration)
+                       sOperator       = "yearMonthDuration-greater-than";
+       }
+       else
+       if (oLeft instanceof cXSDayTimeDuration) {
+               if (oRight instanceof cXSDayTimeDuration)
+                       sOperator       = "dayTimeDuration-greater-than";
+       }
+
+               if (sOperator)
+               return new 
cXSBoolean(!hStaticContext_operators[sOperator].call(oContext, oLeft, 
oRight).valueOf());
+
+               throw new cException("XPTY0004"
+                       , "Cannot compare values of given types"
+       );      };
+
+function fComparisonExpr_NodeComp(oExpr, oContext) {
+       var oLeft       = oExpr.left.evaluate(oContext);
+       if (!oLeft.length)
+               return null;
+               fFunctionCall_assertSequenceCardinality(oContext, oLeft, '?'
+                       , "first operand of '" + oExpr.operator + "'"
+       );
+               fFunctionCall_assertSequenceItemType(oContext, oLeft, cXTNode
+                       , "first operand of '" + oExpr.operator + "'"
+       );
+
+       var oRight      = oExpr.right.evaluate(oContext);
+       if (!oRight.length)
+               return null;
+               fFunctionCall_assertSequenceCardinality(oContext, oRight, '?'
+                       , "second operand of '" + oExpr.operator + "'"
+       );
+               fFunctionCall_assertSequenceItemType(oContext, oRight, cXTNode
+                       , "second operand of '" + oExpr.operator + "'"
+       );
+
+       return hComparisonExpr_NodeComp_operators[oExpr.operator](oLeft[0], 
oRight[0], oContext);
+};
+
+var hComparisonExpr_NodeComp_operators = {};
+hComparisonExpr_NodeComp_operators['is']       = function(oLeft, oRight, 
oContext) {
+       return hStaticContext_operators["is-same-node"].call(oContext, oLeft, 
oRight);
+};
+hComparisonExpr_NodeComp_operators['>>']       = function(oLeft, oRight, 
oContext) {
+       return hStaticContext_operators["node-after"].call(oContext, oLeft, 
oRight);
+};
+hComparisonExpr_NodeComp_operators['<<']       = function(oLeft, oRight, 
oContext) {
+       return hStaticContext_operators["node-before"].call(oContext, oLeft, 
oRight);
+};
+
+var hComparisonExpr_operators  = {
+               '=':    fComparisonExpr_GeneralComp,
+       '!=':   fComparisonExpr_GeneralComp,
+       '<':    fComparisonExpr_GeneralComp,
+       '<=':   fComparisonExpr_GeneralComp,
+       '>':    fComparisonExpr_GeneralComp,
+       '>=':   fComparisonExpr_GeneralComp,
+               'eq':   fComparisonExpr_ValueComp,
+       'ne':   fComparisonExpr_ValueComp,
+       'lt':   fComparisonExpr_ValueComp,
+       'le':   fComparisonExpr_ValueComp,
+       'gt':   fComparisonExpr_ValueComp,
+       'ge':   fComparisonExpr_ValueComp,
+               'is':   fComparisonExpr_NodeComp,
+       '>>':   fComparisonExpr_NodeComp,
+       '<<':   fComparisonExpr_NodeComp
+};
+
+
+function cAdditiveExpr(oExpr) {
+       this.left       = oExpr;
+       this.items      = [];
+};
+
+cAdditiveExpr.prototype.left   = null;
+cAdditiveExpr.prototype.items  = null;
+
+var hAdditiveExpr_operators    = {};
+hAdditiveExpr_operators['+']   = function(oLeft, oRight, oContext) {
+       var sOperator   = '',
+               bReverse        = false;
+
+       if (fXSAnyAtomicType_isNumeric(oLeft)) {
+               if (fXSAnyAtomicType_isNumeric(oRight))
+                       sOperator       = "numeric-add";
+       }
+       else
+       if (oLeft instanceof cXSDate) {
+               if (oRight instanceof cXSYearMonthDuration)
+                       sOperator       = "add-yearMonthDuration-to-date";
+               else
+               if (oRight instanceof cXSDayTimeDuration)
+                       sOperator       = "add-dayTimeDuration-to-date";
+       }
+       else
+       if (oLeft instanceof cXSYearMonthDuration) {
+               if (oRight instanceof cXSDate) {
+                       sOperator       = "add-yearMonthDuration-to-date";
+                       bReverse        = true;
+               }
+               else
+               if (oRight instanceof cXSDateTime) {
+                       sOperator       = "add-yearMonthDuration-to-dateTime";
+                       bReverse        = true;
+               }
+               else
+               if (oRight instanceof cXSYearMonthDuration)
+                       sOperator       = "add-yearMonthDurations";
+       }
+       else
+       if (oLeft instanceof cXSDayTimeDuration) {
+               if (oRight instanceof cXSDate) {
+                       sOperator       = "add-dayTimeDuration-to-date";
+                       bReverse        = true;
+               }
+               else
+               if (oRight instanceof cXSTime) {
+                       sOperator       = "add-dayTimeDuration-to-time";
+                       bReverse        = true;
+               }
+               else
+               if (oRight instanceof cXSDateTime) {
+                       sOperator       = "add-dayTimeDuration-to-dateTime";
+                       bReverse        = true;
+               }
+               else
+               if (oRight instanceof cXSDayTimeDuration)
+                       sOperator       = "add-dayTimeDurations";
+       }
+       else
+       if (oLeft instanceof cXSTime) {
+               if (oRight instanceof cXSDayTimeDuration)
+                       sOperator       = "add-dayTimeDuration-to-time";
+       }
+       else
+       if (oLeft instanceof cXSDateTime) {
+               if (oRight instanceof cXSYearMonthDuration)
+                       sOperator       = "add-yearMonthDuration-to-dateTime";
+               else
+               if (oRight instanceof cXSDayTimeDuration)
+                       sOperator       = "add-dayTimeDuration-to-dateTime";
+       }
+
+               if (sOperator)
+               return hStaticContext_operators[sOperator].call(oContext, 
bReverse ? oRight : oLeft, bReverse ? oLeft : oRight);
+
+               throw new cException("XPTY0004"
+                       , "Arithmetic operator is not defined for provided 
arguments"
+       );      };
+hAdditiveExpr_operators['-']   = function (oLeft, oRight, oContext) {
+       var sOperator   = '';
+
+       if (fXSAnyAtomicType_isNumeric(oLeft)) {
+               if (fXSAnyAtomicType_isNumeric(oRight))
+                       sOperator       = "numeric-subtract";
+       }
+       else
+       if (oLeft instanceof cXSDate) {
+               if (oRight instanceof cXSDate)
+                       sOperator       = "subtract-dates";
+               else
+               if (oRight instanceof cXSYearMonthDuration)
+                       sOperator       = 
"subtract-yearMonthDuration-from-date";
+               else
+               if (oRight instanceof cXSDayTimeDuration)
+                       sOperator       = "subtract-dayTimeDuration-from-date";
+       }
+       else
+       if (oLeft instanceof cXSTime) {
+               if (oRight instanceof cXSTime)
+                       sOperator       = "subtract-times";
+               else
+               if (oRight instanceof cXSDayTimeDuration)
+                       sOperator       = "subtract-dayTimeDuration-from-time";
+       }
+       else
+       if (oLeft instanceof cXSDateTime) {
+               if (oRight instanceof cXSDateTime)
+                       sOperator       = "subtract-dateTimes";
+               else
+               if (oRight instanceof cXSYearMonthDuration)
+                       sOperator       = 
"subtract-yearMonthDuration-from-dateTime";
+               else
+               if (oRight instanceof cXSDayTimeDuration)
+                       sOperator       = 
"subtract-dayTimeDuration-from-dateTime";
+       }
+       else
+       if (oLeft instanceof cXSYearMonthDuration) {
+               if (oRight instanceof cXSYearMonthDuration)
+                       sOperator       = "subtract-yearMonthDurations";
+       }
+       else
+       if (oLeft instanceof cXSDayTimeDuration) {
+               if (oRight instanceof cXSDayTimeDuration)
+                       sOperator       = "subtract-dayTimeDurations";
+       }
+
+               if (sOperator)
+               return hStaticContext_operators[sOperator].call(oContext, 
oLeft, oRight);
+
+               throw new cException("XPTY0004"
+                       , "Arithmetic operator is not defined for provided 
arguments"
+       );      };
+
+function fAdditiveExpr_parse (oLexer, oStaticContext) {
+       var oExpr;
+       if (oLexer.eof() ||!(oExpr = fMultiplicativeExpr_parse(oLexer, 
oStaticContext)))
+               return;
+       if (!(oLexer.peek() in hAdditiveExpr_operators))
+               return oExpr;
+
+               var oAdditiveExpr       = new cAdditiveExpr(oExpr),
+               sOperator;
+       while ((sOperator = oLexer.peek()) in hAdditiveExpr_operators) {
+               oLexer.next();
+               if (oLexer.eof() ||!(oExpr = fMultiplicativeExpr_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected second operand in additive 
expression"
+                       );
+               oAdditiveExpr.items.push([sOperator, oExpr]);
+       }
+       return oAdditiveExpr;
+};
+
+cAdditiveExpr.prototype.evaluate       = function (oContext) {
+       var oLeft       = 
fFunction_sequence_atomize(this.left.evaluate(oContext), oContext);
+
+       if (!oLeft.length)
+               return [];
+               fFunctionCall_assertSequenceCardinality(oContext, oLeft, '?'
+                       , "first operand of '" + this.items[0][0] + "'"
+       );
+
+       var vLeft       = oLeft[0];
+       if (vLeft instanceof cXSUntypedAtomic)
+               vLeft   = cXSDouble.cast(vLeft);        
+       for (var nIndex = 0, nLength = this.items.length, oRight, vRight; 
nIndex < nLength; nIndex++) {
+               oRight  = 
fFunction_sequence_atomize(this.items[nIndex][1].evaluate(oContext), oContext);
+
+               if (!oRight.length)
+                       return [];
+                               
fFunctionCall_assertSequenceCardinality(oContext, oRight, '?'
+                               , "first operand of '" + this.items[nIndex][0] 
+ "'"
+               );
+
+               vRight  = oRight[0];
+               if (vRight instanceof cXSUntypedAtomic)
+                       vRight  = cXSDouble.cast(vRight);       
+               vLeft   = hAdditiveExpr_operators[this.items[nIndex][0]](vLeft, 
vRight, oContext);
+       }
+       return [vLeft];
+};
+
+
+function cMultiplicativeExpr(oExpr) {
+       this.left       = oExpr;
+       this.items      = [];
+};
+
+cMultiplicativeExpr.prototype.left     = null;
+cMultiplicativeExpr.prototype.items    = null;
+
+var hMultiplicativeExpr_operators      = {};
+hMultiplicativeExpr_operators['*']             = function (oLeft, oRight, 
oContext) {
+       var sOperator   = '',
+               bReverse        = false;
+
+       if (fXSAnyAtomicType_isNumeric(oLeft)) {
+               if (fXSAnyAtomicType_isNumeric(oRight))
+                       sOperator       = "numeric-multiply";
+               else
+               if (oRight instanceof cXSYearMonthDuration) {
+                       sOperator       = "multiply-yearMonthDuration";
+                       bReverse        = true;
+               }
+               else
+               if (oRight instanceof cXSDayTimeDuration) {
+                       sOperator       = "multiply-dayTimeDuration";
+                       bReverse        = true;
+               }
+       }
+       else {
+               if (oLeft instanceof cXSYearMonthDuration) {
+                       if (fXSAnyAtomicType_isNumeric(oRight))
+                               sOperator       = "multiply-yearMonthDuration";
+               }
+               else
+               if (oLeft instanceof cXSDayTimeDuration) {
+                       if (fXSAnyAtomicType_isNumeric(oRight))
+                               sOperator       = "multiply-dayTimeDuration";
+               }
+       }
+
+               if (sOperator)
+               return hStaticContext_operators[sOperator].call(oContext, 
bReverse ? oRight : oLeft, bReverse ? oLeft : oRight);
+
+               throw new cException("XPTY0004"
+                       , "Arithmetic operator is not defined for provided 
arguments"
+       );      };
+hMultiplicativeExpr_operators['div']   = function (oLeft, oRight, oContext) {
+       var sOperator   = '';
+
+       if (fXSAnyAtomicType_isNumeric(oLeft)) {
+               if (fXSAnyAtomicType_isNumeric(oRight))
+                       sOperator       = "numeric-divide";
+       }
+       else
+       if (oLeft instanceof cXSYearMonthDuration) {
+               if (fXSAnyAtomicType_isNumeric(oRight))
+                       sOperator       = "divide-yearMonthDuration";
+               else
+               if (oRight instanceof cXSYearMonthDuration)
+                       sOperator       = 
"divide-yearMonthDuration-by-yearMonthDuration";
+       }
+       else
+       if (oLeft instanceof cXSDayTimeDuration) {
+               if (fXSAnyAtomicType_isNumeric(oRight))
+                       sOperator       = "divide-dayTimeDuration";
+               else
+               if (oRight instanceof cXSDayTimeDuration)
+                       sOperator       = 
"divide-dayTimeDuration-by-dayTimeDuration";
+       }
+               if (sOperator)
+               return hStaticContext_operators[sOperator].call(oContext, 
oLeft, oRight);
+
+               throw new cException("XPTY0004"
+                       , "Arithmetic operator is not defined for provided 
arguments"
+       );      };
+hMultiplicativeExpr_operators['idiv']  = function (oLeft, oRight, oContext) {
+       if (fXSAnyAtomicType_isNumeric(oLeft) && 
fXSAnyAtomicType_isNumeric(oRight))
+               return 
hStaticContext_operators["numeric-integer-divide"].call(oContext, oLeft, 
oRight);
+               throw new cException("XPTY0004"
+                       , "Arithmetic operator is not defined for provided 
arguments"
+       );      };
+hMultiplicativeExpr_operators['mod']   = function (oLeft, oRight, oContext) {
+       if (fXSAnyAtomicType_isNumeric(oLeft) && 
fXSAnyAtomicType_isNumeric(oRight))
+               return hStaticContext_operators["numeric-mod"].call(oContext, 
oLeft, oRight);
+               throw new cException("XPTY0004"
+                       , "Arithmetic operator is not defined for provided 
arguments"
+       );      };
+
+function fMultiplicativeExpr_parse (oLexer, oStaticContext) {
+       var oExpr;
+       if (oLexer.eof() ||!(oExpr = fUnionExpr_parse(oLexer, oStaticContext)))
+               return;
+       if (!(oLexer.peek() in hMultiplicativeExpr_operators))
+               return oExpr;
+
+               var oMultiplicativeExpr = new cMultiplicativeExpr(oExpr),
+               sOperator;
+       while ((sOperator = oLexer.peek()) in hMultiplicativeExpr_operators) {
+               oLexer.next();
+               if (oLexer.eof() ||!(oExpr = fUnionExpr_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected second operand in 
multiplicative expression"
+                       );
+               oMultiplicativeExpr.items.push([sOperator, oExpr]);
+       }
+       return oMultiplicativeExpr;
+};
+
+cMultiplicativeExpr.prototype.evaluate = function (oContext) {
+       var oLeft       = 
fFunction_sequence_atomize(this.left.evaluate(oContext), oContext);
+
+               if (!oLeft.length)
+               return [];
+               fFunctionCall_assertSequenceCardinality(oContext, oLeft, '?'
+                       , "first operand of '" + this.items[0][0] + "'"
+       );
+
+       var vLeft       = oLeft[0];
+       if (vLeft instanceof cXSUntypedAtomic)
+               vLeft   = cXSDouble.cast(vLeft);        
+       for (var nIndex = 0, nLength = this.items.length, oRight, vRight; 
nIndex < nLength; nIndex++) {
+               oRight  = 
fFunction_sequence_atomize(this.items[nIndex][1].evaluate(oContext), oContext);
+
+               if (!oRight.length)
+                       return [];
+                               
fFunctionCall_assertSequenceCardinality(oContext, oRight, '?'
+                               , "second operand of '" + this.items[nIndex][0] 
+ "'"
+               );
+
+               vRight  = oRight[0];
+               if (vRight instanceof cXSUntypedAtomic)
+                       vRight  = cXSDouble.cast(vRight);       
+               vLeft   = 
hMultiplicativeExpr_operators[this.items[nIndex][0]](vLeft, vRight, oContext);
+       }
+       return [vLeft];
+};
+
+
+function cUnaryExpr(sOperator, oExpr) {
+       this.operator   = sOperator;
+       this.expression = oExpr;
+};
+
+cUnaryExpr.prototype.operator  = null;
+cUnaryExpr.prototype.expression        = null;
+
+var hUnaryExpr_operators       = {};
+hUnaryExpr_operators['-']      = function(oRight, oContext) {
+       if (fXSAnyAtomicType_isNumeric(oRight))
+               return 
hStaticContext_operators["numeric-unary-minus"].call(oContext, oRight);
+               throw new cException("XPTY0004"
+                       , "Arithmetic operator is not defined for provided 
arguments"
+       );      };
+hUnaryExpr_operators['+']      = function(oRight, oContext) {
+       if (fXSAnyAtomicType_isNumeric(oRight))
+               return 
hStaticContext_operators["numeric-unary-plus"].call(oContext, oRight);
+               throw new cException("XPTY0004"
+                       , "Arithmetic operator is not defined for provided 
arguments"
+       );      };
+
+function fUnaryExpr_parse (oLexer, oStaticContext) {
+       if (oLexer.eof())
+               return;
+       if (!(oLexer.peek() in hUnaryExpr_operators))
+               return fValueExpr_parse(oLexer, oStaticContext);
+
+               var sOperator   = '+',
+               oExpr;
+       while (oLexer.peek() in hUnaryExpr_operators) {
+               if (oLexer.peek() == '-')
+                       sOperator       = sOperator == '-' ? '+' : '-';
+               oLexer.next();
+       }
+       if (oLexer.eof() ||!(oExpr = fValueExpr_parse(oLexer, oStaticContext)))
+               throw new cException("XPST0003"
+                               , "Expected operand in unary expression"
+               );
+       return new cUnaryExpr(sOperator, oExpr);
+};
+
+cUnaryExpr.prototype.evaluate  = function (oContext) {
+       var oRight      = 
fFunction_sequence_atomize(this.expression.evaluate(oContext), oContext);
+
+               if (!oRight.length)
+               return [];
+               fFunctionCall_assertSequenceCardinality(oContext, oRight, '?'
+                       , "second operand of '" + this.operator + "'"
+       );
+
+       var vRight      = oRight[0];
+       if (vRight instanceof cXSUntypedAtomic)
+               vRight  = cXSDouble.cast(vRight);       
+       return [hUnaryExpr_operators[this.operator](vRight, oContext)];
+};
+
+
+function cValueExpr() {
+
+};
+
+function fValueExpr_parse (oLexer, oStaticContext) {
+       return fPathExpr_parse(oLexer, oStaticContext);
+};
+
+
+function cOrExpr(oExpr) {
+       this.left       = oExpr;
+       this.items      = [];
+};
+
+cOrExpr.prototype.left = null;
+cOrExpr.prototype.items        = null;
+
+function fOrExpr_parse (oLexer, oStaticContext) {
+       var oExpr;
+       if (oLexer.eof() ||!(oExpr = fAndExpr_parse(oLexer, oStaticContext)))
+               return;
+       if (oLexer.peek() != "or")
+               return oExpr;
+
+               var oOrExpr     = new cOrExpr(oExpr);
+       while (oLexer.peek() == "or") {
+               oLexer.next();
+               if (oLexer.eof() ||!(oExpr = fAndExpr_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected second operand in logical 
expression"
+                       );
+               oOrExpr.items.push(oExpr);
+       }
+       return oOrExpr;
+};
+
+cOrExpr.prototype.evaluate     = function (oContext) {
+       var bValue      = 
fFunction_sequence_toEBV(this.left.evaluate(oContext), oContext);
+       for (var nIndex = 0, nLength = this.items.length; (nIndex < nLength) && 
!bValue; nIndex++)
+               bValue  = 
fFunction_sequence_toEBV(this.items[nIndex].evaluate(oContext), oContext);
+       return [new cXSBoolean(bValue)];
+};
+
+
+function cAndExpr(oExpr) {
+       this.left       = oExpr;
+       this.items      = [];
+};
+
+cAndExpr.prototype.left                = null;
+cAndExpr.prototype.items       = null;
+
+function fAndExpr_parse (oLexer, oStaticContext) {
+       var oExpr;
+       if (oLexer.eof() ||!(oExpr = fComparisonExpr_parse(oLexer, 
oStaticContext)))
+               return;
+       if (oLexer.peek() != "and")
+               return oExpr;
+
+               var oAndExpr    = new cAndExpr(oExpr);
+       while (oLexer.peek() == "and") {
+               oLexer.next();
+               if (oLexer.eof() ||!(oExpr = fComparisonExpr_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected second operand in logical 
expression"
+                       );
+               oAndExpr.items.push(oExpr);
+       }
+       return oAndExpr;
+};
+
+cAndExpr.prototype.evaluate    = function (oContext) {
+       var bValue      = 
fFunction_sequence_toEBV(this.left.evaluate(oContext), oContext);
+       for (var nIndex = 0, nLength = this.items.length; (nIndex < nLength) && 
bValue; nIndex++)
+               bValue  = 
fFunction_sequence_toEBV(this.items[nIndex].evaluate(oContext), oContext);
+       return [new cXSBoolean(bValue)];
+};
+
+
+function cStepExpr() {
+
+};
+
+cStepExpr.prototype.predicates = null;
+
+function fStepExpr_parse (oLexer, oStaticContext) {
+       if (!oLexer.eof())
+               return fFilterExpr_parse(oLexer, oStaticContext)
+                       || fAxisStep_parse(oLexer, oStaticContext);
+};
+
+function fStepExpr_parsePredicates (oLexer, oStaticContext, oStep) {
+       var oExpr;
+               while (oLexer.peek() == '[') {
+               oLexer.next();
+
+               if (oLexer.eof() ||!(oExpr = fExpr_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected expression in predicate"
+                       );
+
+               oStep.predicates.push(oExpr);
+
+               if (oLexer.peek() != ']')
+                       throw new cException("XPST0003"
+                                       , "Expected ']' token in predicate"
+                       );
+
+               oLexer.next();
+       }
+};
+
+cStepExpr.prototype.applyPredicates    = function(oSequence, oContext) {
+       var vContextItem        = oContext.item,
+               nContextPosition= oContext.position,
+               nContextSize    = oContext.size;
+               for (var nPredicateIndex = 0, oSequence1, nPredicateLength = 
this.predicates.length; nPredicateIndex < nPredicateLength; nPredicateIndex++) {
+               oSequence1      = oSequence;
+               oSequence       = [];
+               for (var nIndex = 0, oSequence2, nLength = oSequence1.length; 
nIndex < nLength; nIndex++) {
+                                               oContext.item           = 
oSequence1[nIndex];
+                       oContext.position       = nIndex + 1;
+                       oContext.size           = nLength;
+                                               oSequence2      = 
this.predicates[nPredicateIndex].evaluate(oContext);
+                                               if (oSequence2.length == 1 && 
fXSAnyAtomicType_isNumeric(oSequence2[0])) {
+                               if (oSequence2[0].valueOf() == nIndex + 1)
+                                       oSequence.push(oSequence1[nIndex]);
+                       }
+                       else
+                       if (fFunction_sequence_toEBV(oSequence2, oContext))
+                               oSequence.push(oSequence1[nIndex]);
+               }
+       }
+               oContext.item           = vContextItem;
+       oContext.position       = nContextPosition;
+       oContext.size           = nContextSize;
+               return oSequence;
+};
+
+
+function cAxisStep(sAxis, oTest) {
+       this.axis       = sAxis;
+       this.test       = oTest;
+       this.predicates = [];
+};
+
+cAxisStep.prototype    = new cStepExpr;
+
+cAxisStep.prototype.axis               = null;
+cAxisStep.prototype.test               = null;
+
+var hAxisStep_axises   = {};
+hAxisStep_axises["attribute"]                  = {};
+hAxisStep_axises["child"]                              = {};
+hAxisStep_axises["descendant"]                 = {};
+hAxisStep_axises["descendant-or-self"] = {};
+hAxisStep_axises["following"]                  = {};
+hAxisStep_axises["following-sibling"]  = {};
+hAxisStep_axises["self"]                               = {};
+hAxisStep_axises["ancestor"]                   = {};
+hAxisStep_axises["ancestor-or-self"]   = {};
+hAxisStep_axises["parent"]                             = {};
+hAxisStep_axises["preceding"]                  = {};
+hAxisStep_axises["preceding-sibling"]  = {};
+
+function fAxisStep_parse (oLexer, oStaticContext) {
+       var sAxis       = oLexer.peek(),
+               oExpr,
+               oStep;
+       if (oLexer.peek(1) == '::') {
+               if (!(sAxis in hAxisStep_axises))
+                       throw new cException("XPST0003"
+                                       , "Unknown axis name: " + sAxis
+                       );
+
+               oLexer.next(2);
+               if (oLexer.eof() ||!(oExpr = fNodeTest_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected node test expression in 
axis step"
+                       );
+                               oStep   = new cAxisStep(sAxis, oExpr);
+       }
+       else
+       if (sAxis == '..') {
+               oLexer.next();
+               oStep   = new cAxisStep("parent", new cKindTest("node"));
+       }
+       else
+       if (sAxis == '@') {
+               oLexer.next();
+               if (oLexer.eof() ||!(oExpr = fNodeTest_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected node test expression in 
axis step"
+                       );
+                               oStep   = new cAxisStep("attribute", oExpr);
+       }
+       else {
+               if (oLexer.eof() ||!(oExpr = fNodeTest_parse(oLexer, 
oStaticContext)))
+                       return;
+               oStep   = new cAxisStep(oExpr instanceof cKindTest && 
oExpr.name == "attribute" ? "attribute" : "child", oExpr);
+       }
+               fStepExpr_parsePredicates(oLexer, oStaticContext, oStep);
+
+       return oStep;
+};
+
+cAxisStep.prototype.evaluate   = function (oContext) {
+       var oItem       = oContext.item;
+
+       if (!oContext.DOMAdapter.isNode(oItem))
+               throw new cException("XPTY0020");
+
+       var oSequence   = [],
+               fGetProperty= oContext.DOMAdapter.getProperty,
+               nType           = fGetProperty(oItem, "nodeType");
+
+       switch (this.axis) {
+                               case "attribute":
+                       if (nType == 1)
+                               for (var aAttributes = fGetProperty(oItem, 
"attributes"), nIndex = 0, nLength = aAttributes.length; nIndex < nLength; 
nIndex++)
+                                       oSequence.push(aAttributes[nIndex]);
+                       break;
+
+               case "child":
+                       for (var oNode = fGetProperty(oItem, "firstChild"); 
oNode; oNode = fGetProperty(oNode, "nextSibling"))
+                               oSequence.push(oNode);
+                       break;
+
+               case "descendant-or-self":
+                       oSequence.push(oItem);
+                                       case "descendant":
+                       fAxisStep_getChildrenForward(fGetProperty(oItem, 
"firstChild"), oSequence, fGetProperty);
+                       break;
+
+               case "following":
+                                               for (var oParent = oItem, 
oSibling; oParent; oParent = fGetProperty(oParent, "parentNode"))
+                               if (oSibling = fGetProperty(oParent, 
"nextSibling"))
+                                       fAxisStep_getChildrenForward(oSibling, 
oSequence, fGetProperty);
+                       break;
+
+               case "following-sibling":
+                       for (var oNode = oItem; oNode = fGetProperty(oNode, 
"nextSibling");)
+                               oSequence.push(oNode);
+                       break;
+
+               case "self":
+                       oSequence.push(oItem);
+                       break;
+
+                               case "ancestor-or-self":
+                       oSequence.push(oItem);
+                                       case "ancestor":
+                       for (var oNode = nType == 2 ? fGetProperty(oItem, 
"ownerElement") : oItem; oNode = fGetProperty(oNode, "parentNode");)
+                               oSequence.push(oNode);
+                       break;
+
+               case "parent":
+                       var oParent     = nType == 2 ? fGetProperty(oItem, 
"ownerElement") : fGetProperty(oItem, "parentNode");
+                       if (oParent)
+                               oSequence.push(oParent);
+                       break;
+
+               case "preceding":
+                                               for (var oParent = oItem, 
oSibling; oParent; oParent = fGetProperty(oParent, "parentNode"))
+                               if (oSibling = fGetProperty(oParent, 
"previousSibling"))
+                                       fAxisStep_getChildrenBackward(oSibling, 
oSequence, fGetProperty);
+                       break;
+
+               case "preceding-sibling":
+                       for (var oNode = oItem; oNode = fGetProperty(oNode, 
"previousSibling");)
+                               oSequence.push(oNode);
+                       break;
+       }
+
+               if (oSequence.length && !(this.test instanceof cKindTest && 
this.test.name == "node")) {
+               var oSequence1  = oSequence;
+               oSequence       = [];
+               for (var nIndex = 0, nLength = oSequence1.length; nIndex < 
nLength; nIndex++) {
+                       if (this.test.test(oSequence1[nIndex], oContext))
+                               oSequence.push(oSequence1[nIndex]);
+               }
+       }
+
+               if (oSequence.length && this.predicates.length)
+               oSequence       = this.applyPredicates(oSequence, oContext);
+
+               switch (this.axis) {
+               case "ancestor":
+               case "ancestor-or-self":
+               case "parent":
+               case "preceding":
+               case "preceding-sibling":
+                       oSequence.reverse();
+       }
+
+       return oSequence;
+};
+
+function fAxisStep_getChildrenForward(oNode, oSequence, fGetProperty) {
+       for (var oChild; oNode; oNode = fGetProperty(oNode, "nextSibling")) {
+               oSequence.push(oNode);
+               if (oChild = fGetProperty(oNode, "firstChild"))
+                       fAxisStep_getChildrenForward(oChild, oSequence, 
fGetProperty);
+       }
+};
+
+function fAxisStep_getChildrenBackward(oNode, oSequence, fGetProperty) {
+       for (var oChild; oNode; oNode = fGetProperty(oNode, "previousSibling")) 
{
+               if (oChild = fGetProperty(oNode, "lastChild"))
+                       fAxisStep_getChildrenBackward(oChild, oSequence, 
fGetProperty);
+               oSequence.push(oNode);
+       }
+};
+
+
+function cPathExpr() {
+       this.items      = [];
+};
+
+cPathExpr.prototype.items      = null;
+
+function fPathExpr_parse (oLexer, oStaticContext) {
+       if (oLexer.eof())
+               return;
+       var sSingleSlash        = '/',
+               sDoubleSlash    = '/' + '/';
+
+       var oPathExpr   = new cPathExpr(),
+               sSlash  = oLexer.peek(),
+               oExpr;
+               if (sSlash == sDoubleSlash || sSlash == sSingleSlash) {
+               oLexer.next();
+               oPathExpr.items.push(new cFunctionCall(null, "root", sNS_XPF));
+                               if (sSlash == sDoubleSlash)
+                       oPathExpr.items.push(new 
cAxisStep("descendant-or-self", new cKindTest("node")));
+       }
+
+               if (oLexer.eof() ||!(oExpr = fStepExpr_parse(oLexer, 
oStaticContext))) {
+               if (sSlash == sSingleSlash)
+                       return oPathExpr.items[0];                      if 
(sSlash == sDoubleSlash)
+                       throw new cException("XPST0003"
+                                       , "Expected path step expression"
+                       );
+               return;
+       }
+       oPathExpr.items.push(oExpr);
+
+               while ((sSlash = oLexer.peek()) == sSingleSlash || sSlash == 
sDoubleSlash) {
+               if (sSlash == sDoubleSlash)
+                       oPathExpr.items.push(new 
cAxisStep("descendant-or-self", new cKindTest("node")));
+                               oLexer.next();
+               if (oLexer.eof() ||!(oExpr = fStepExpr_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected path step expression"
+                       );
+                               oPathExpr.items.push(oExpr);
+       }
+
+       if (oPathExpr.items.length == 1)
+               return oPathExpr.items[0];
+
+               return oPathExpr;
+};
+
+cPathExpr.prototype.evaluate   = function (oContext) {
+       var vContextItem        = oContext.item;
+               var oSequence   = [vContextItem];
+       for (var nItemIndex = 0, nItemLength = this.items.length, oSequence1; 
nItemIndex < nItemLength; nItemIndex++) {
+               oSequence1      = [];
+               for (var nIndex = 0, nLength = oSequence.length; nIndex < 
nLength; nIndex++) {
+                                               oContext.item   = 
oSequence[nIndex];
+                                               for (var nRightIndex = 0, 
oSequence2 = this.items[nItemIndex].evaluate(oContext), nRightLength = 
oSequence2.length; nRightIndex < nRightLength; nRightIndex++)
+                               if ((nItemIndex < nItemLength - 1) && 
!oContext.DOMAdapter.isNode(oSequence2[nRightIndex]))
+                                       throw new cException("XPTY0019");
+                               else
+                               if (fArray_indexOf(oSequence1, 
oSequence2[nRightIndex]) ==-1)
+                                       
oSequence1.push(oSequence2[nRightIndex]);
+               }
+               oSequence       = oSequence1;
+       };
+               oContext.item   = vContextItem;
+               return fFunction_sequence_order(oSequence, oContext);
+};
+
+
+function cNodeTest() {
+
+};
+
+function fNodeTest_parse (oLexer, oStaticContext) {
+       if (!oLexer.eof())
+               return fKindTest_parse(oLexer, oStaticContext)
+                       || fNameTest_parse(oLexer, oStaticContext);
+};
+
+
+function cKindTest(sName) {
+       this.name       = sName;
+       this.args       = [];
+};
+
+cKindTest.prototype    = new cNodeTest;
+
+cKindTest.prototype.name       = null;
+cKindTest.prototype.args       = null;
+
+var hKindTest_names    = {};
+hKindTest_names["document-node"]       = {};
+hKindTest_names["element"]                     = {};
+hKindTest_names["attribute"]           = {};
+hKindTest_names["processing-instruction"]      = {};
+hKindTest_names["comment"]                     = {};
+hKindTest_names["text"]                                = {};
+hKindTest_names["node"]                                = {};
+hKindTest_names["schema-element"]      = {};
+hKindTest_names["schema-attribute"]    = {};
+
+function fKindTest_parse (oLexer, oStaticContext) {
+       var sName       = oLexer.peek();
+       if (oLexer.peek(1) == '(') {
+                               if (!(sName in hKindTest_names))
+                       throw new cException("XPST0003"
+                                       , "Unknown '" + sName + "' kind test"
+                       );
+
+                               oLexer.next(2);
+                               var oTest       = new cKindTest(sName);
+               if (oLexer.peek() != ')') {
+                       if (sName == "document-node") {
+                                                       }
+                       else
+                       if (sName == "element") {
+                                                       }
+                       else
+                       if (sName == "attribute") {
+                                                       }
+                       else
+                       if (sName == "processing-instruction") {
+                                                       }
+                       else
+                       if (sName == "schema-attribute") {
+                                                       }
+                       else
+                       if (sName == "schema-element") {
+                                                       }
+               }
+               else {
+                       if (sName == "schema-attribute")
+                               throw new cException("XPST0003"
+                                               , "Expected attribute 
declaration in 'schema-attribute' kind test"
+                               );
+                       else
+                       if (sName == "schema-element")
+                               throw new cException("XPST0003"
+                                               , "Expected element declaration 
in 'schema-element' kind test"
+                               );
+               }
+
+               if (oLexer.peek() != ')')
+                       throw new cException("XPST0003"
+                                       , "Expected ')' token in kind test"
+                       );
+               oLexer.next();
+
+               return oTest;
+       }
+};
+
+cKindTest.prototype.test       = function (oNode, oContext) {
+       var fGetProperty        = oContext.DOMAdapter.getProperty,
+               nType   = oContext.DOMAdapter.isNode(oNode) ? 
fGetProperty(oNode, "nodeType") : 0;
+       switch (this.name) {
+                               case "node":                    return !!nType;
+               case "attribute":                               if (nType != 2) 
return false;   break;
+               case "document-node":   return nType == 9;
+               case "element":                 return nType == 1;
+               case "processing-instruction":  if (nType != 7) return false;   
break;
+               case "comment":                 return nType == 8;
+               case "text":                    return nType == 3 || nType == 4;
+
+                               case "schema-attribute":
+                       throw "KindTest '" + "schema-attribute" + "' not 
implemented";
+
+               case "schema-element":
+                       throw "KindTest '" + "schema-element" + "' not 
implemented";
+       }
+
+               if (nType == 2)
+               return fGetProperty(oNode, "prefix") != "xmlns" && 
fGetProperty(oNode, "localName") != "xmlns";
+       if (nType == 7)
+               return fGetProperty(oNode, "target") != "xml";
+
+       return true;
+};
+
+
+function cNameTest(sPrefix, sLocalName, sNameSpaceURI) {
+       this.prefix                     = sPrefix;
+       this.localName          = sLocalName;
+       this.namespaceURI       = sNameSpaceURI;
+};
+
+cNameTest.prototype    = new cNodeTest;
+
+cNameTest.prototype.prefix                     = null;
+cNameTest.prototype.localName          = null;
+cNameTest.prototype.namespaceURI       = null;
+
+var rNameTest  = /^(?:(?![0-9-])([\w-]+|\*)\:)?(?![0-9-])([\w-]+|\*)$/;
+function fNameTest_parse (oLexer, oStaticContext) {
+       var aMatch      = oLexer.peek().match(rNameTest);
+       if (aMatch) {
+               if (aMatch[1] == '*' && aMatch[2] == '*')
+                       throw new cException("XPST0003"
+                                       , "Illegal use of *:* wildcard in name 
test"
+                       );
+               oLexer.next();
+               return new cNameTest(aMatch[1] || null, aMatch[2], aMatch[1] ? 
aMatch[1] == '*' ? '*' : oStaticContext.getURIForPrefix(aMatch[1]) || null : 
oStaticContext.defaultElementNamespace);
+       }
+};
+
+cNameTest.prototype.test       = function (oNode, oContext) {
+       var fGetProperty        = oContext.DOMAdapter.getProperty,
+               nType   = fGetProperty(oNode, "nodeType");
+       if (nType == 1 || nType == 2) {
+               if (this.localName == '*')
+                       return (nType == 1 || (fGetProperty(oNode, "prefix") != 
"xmlns" && fGetProperty(oNode, "localName") != "xmlns")) && (!this.prefix || 
fGetProperty(oNode, "namespaceURI") == this.namespaceURI);
+               if (this.localName == fGetProperty(oNode, "localName"))
+                       return this.namespaceURI == '*' || (nType == 2 && 
!this.prefix && !fGetProperty(oNode, "prefix")) || fGetProperty(oNode, 
"namespaceURI") == this.namespaceURI;
+       }
+               return false;
+};
+
+
+function cPrimaryExpr() {
+
+};
+
+function fPrimaryExpr_parse (oLexer, oStaticContext) {
+       if (!oLexer.eof())
+               return fContextItemExpr_parse(oLexer, oStaticContext)
+                       || fParenthesizedExpr_parse(oLexer, oStaticContext)
+                       || fFunctionCall_parse(oLexer, oStaticContext)
+                       || fVarRef_parse(oLexer, oStaticContext)
+                       || fLiteral_parse(oLexer, oStaticContext);
+};
+
+
+function cParenthesizedExpr(oExpr) {
+       this.expression = oExpr;
+};
+
+function fParenthesizedExpr_parse (oLexer, oStaticContext) {
+       if (oLexer.peek() == '(') {
+               oLexer.next();
+                               var oExpr       = null;
+               if (oLexer.peek() != ')')
+                       oExpr   = fExpr_parse(oLexer, oStaticContext);
+
+                               if (oLexer.peek() != ')')
+                       throw new cException("XPST0003"
+                                       , "Expected ')' token in parenthesized 
expression"
+                       );
+
+               oLexer.next();
+
+                               return new cParenthesizedExpr(oExpr);
+       }
+};
+
+cParenthesizedExpr.prototype.evaluate  = function (oContext) {
+       return this.expression ? this.expression.evaluate(oContext) : [];
+};
+
+
+function cContextItemExpr() {
+
+};
+
+function fContextItemExpr_parse (oLexer, oStaticContext) {
+       if (oLexer.peek() == '.') {
+               oLexer.next();
+               return new cContextItemExpr;
+       }
+};
+
+cContextItemExpr.prototype.evaluate    = function (oContext) {
+       if (oContext.item == null)
+               throw new cException("XPDY0002"
+                               , "Dynamic context does not have context item 
initialized"
+               );
+               return [oContext.item];
+};
+
+
+function cLiteral() {
+
+};
+
+cLiteral.prototype.value       = null;
+
+function fLiteral_parse (oLexer, oStaticContext) {
+       if (!oLexer.eof())
+               return fNumericLiteral_parse(oLexer, oStaticContext)
+                       || fStringLiteral_parse(oLexer, oStaticContext);
+};
+
+cLiteral.prototype.evaluate    = function (oContext) {
+       return [this.value];
+};
+
+
+function cNumericLiteral(oValue) {
+       this.value      = oValue;
+};
+
+cNumericLiteral.prototype      = new cLiteral;
+
+var rNumericLiteral    = 
/^[+\-]?(?:(?:(\d+)(?:\.(\d*))?)|(?:\.(\d+)))(?:[eE]([+-])?(\d+))?$/;
+function fNumericLiteral_parse (oLexer, oStaticContext) {
+       var sValue      = oLexer.peek(),
+               vValue  = fNumericLiteral_parseValue(sValue);
+       if (vValue) {
+               oLexer.next();
+               return new cNumericLiteral(vValue);
+       }
+};
+
+function fNumericLiteral_parseValue(sValue) {
+       var aMatch      = sValue.match(rNumericLiteral);
+       if (aMatch) {
+               var cType       = cXSInteger;
+               if (aMatch[5])
+                       cType   = cXSDouble;
+               else
+               if (aMatch[2] || aMatch[3])
+                       cType   = cXSDecimal;
+               return new cType(+sValue);
+       }
+};
+
+
+function cStringLiteral(oValue) {
+       this.value      = oValue;
+};
+
+cStringLiteral.prototype       = new cLiteral;
+
+var rStringLiteral     = /^'([^']*(?:''[^']*)*)'|"([^"]*(?:""[^"]*)*)"$/;
+function fStringLiteral_parse (oLexer, oStaticContext) {
+       var aMatch      = oLexer.peek().match(rStringLiteral);
+       if (aMatch) {
+               oLexer.next();
+               return new cStringLiteral(new cXSString(aMatch[1] ? 
aMatch[1].replace("''", "'") : aMatch[2] ? aMatch[2].replace('""', '"') : ''));
+       }
+};
+
+
+function cFilterExpr(oPrimary) {
+       this.expression = oPrimary;
+       this.predicates = [];
+};
+
+cFilterExpr.prototype  = new cStepExpr;
+
+cFilterExpr.prototype.expression       = null;
+
+function fFilterExpr_parse (oLexer, oStaticContext) {
+       var oExpr;
+       if (oLexer.eof() ||!(oExpr = fPrimaryExpr_parse(oLexer, 
oStaticContext)))
+               return;
+
+       var oFilterExpr = new cFilterExpr(oExpr);
+               fStepExpr_parsePredicates(oLexer, oStaticContext, oFilterExpr);
+
+               if (oFilterExpr.predicates.length == 0)
+               return oFilterExpr.expression;
+
+       return oFilterExpr;
+};
+
+cFilterExpr.prototype.evaluate = function (oContext) {
+       var oSequence   = this.expression.evaluate(oContext);
+       if (this.predicates.length && oSequence.length)
+               oSequence       = this.applyPredicates(oSequence, oContext);
+       return oSequence;
+};
+
+
+function cVarRef(sPrefix, sLocalName, sNameSpaceURI) {
+       this.prefix                     = sPrefix;
+       this.localName          = sLocalName;
+       this.namespaceURI       = sNameSpaceURI;
+};
+
+cVarRef.prototype.prefix               = null;
+cVarRef.prototype.localName            = null;
+cVarRef.prototype.namespaceURI = null;
+
+function fVarRef_parse (oLexer, oStaticContext) {
+       if (oLexer.peek().substr(0, 1) == '$') {
+               var aMatch      = oLexer.peek().substr(1).match(rNameTest);
+               if (aMatch) {
+                       if (aMatch[1] == '*' || aMatch[2] == '*')
+                               throw new cException("XPST0003"
+                                                       , "Illegal use of 
wildcard in var expression variable name"
+                                       );
+
+                       var oVarRef     = new cVarRef(aMatch[1] || null, 
aMatch[2], aMatch[1] ? oStaticContext.getURIForPrefix(aMatch[1]) : null);
+                       oLexer.next();
+                       return oVarRef;
+               }
+       }
+};
+
+cVarRef.prototype.evaluate     = function (oContext) {
+       var sUri        = (this.namespaceURI ? '{' + this.namespaceURI + '}' : 
'') + this.localName;
+       if (oContext.scope.hasOwnProperty(sUri))
+               return [oContext.scope[sUri]];
+               throw new cException("XPST0008"
+                       , "Variable $" + (this.prefix ? this.prefix + ':' : '') 
+ this.localName + " has not been declared"
+       );
+};
+
+
+function cFunctionCall(sPrefix, sLocalName, sNameSpaceURI) {
+       this.prefix                     = sPrefix;
+       this.localName          = sLocalName;
+       this.namespaceURI       = sNameSpaceURI;
+       this.args       = [];
+};
+
+cFunctionCall.prototype.prefix                 = null;
+cFunctionCall.prototype.localName              = null;
+cFunctionCall.prototype.namespaceURI   = null;
+cFunctionCall.prototype.args   = null;
+
+function fFunctionCall_parse (oLexer, oStaticContext) {
+       var aMatch      = oLexer.peek().match(rNameTest);
+       if (aMatch && oLexer.peek(1) == '(') {
+                               if (!aMatch[1] && (aMatch[2] in 
hKindTest_names))
+                       return fAxisStep_parse(oLexer, oStaticContext);
+                               if (aMatch[1] == '*' || aMatch[2] == '*')
+                       throw new cException("XPST0003"
+                                       , "Illegal use of wildcard in function 
name"
+                       );
+               var oFunctionCallExpr   = new cFunctionCall(aMatch[1] || null, 
aMatch[2], aMatch[1] ? oStaticContext.getURIForPrefix(aMatch[1]) || null : 
oStaticContext.defaultFunctionNamespace),
+                       oExpr;
+               oLexer.next(2);
+                               if (oLexer.peek() != ')') {
+                       do {
+                               if (oLexer.eof() ||!(oExpr = 
fExprSingle_parse(oLexer, oStaticContext)))
+                                       throw new cException("XPST0003"
+                                                       , "Expected function 
call argument"
+                                       );
+                                                               
oFunctionCallExpr.args.push(oExpr);
+                       }
+                       while (oLexer.peek() == ',' && oLexer.next());
+                                               if (oLexer.peek() != ')')
+                               throw new cException("XPST0003"
+                                               , "Expected ')' token in 
function call"
+                               );
+               }
+               oLexer.next();
+               return oFunctionCallExpr;
+       }
+};
+
+cFunctionCall.prototype.evaluate       = function (oContext) {
+       var aArguments  = [],
+               aParameters,
+               fFunction;
+
+               for (var nIndex = 0, nLength = this.args.length; nIndex < 
nLength; nIndex++)
+               aArguments.push(this.args[nIndex].evaluate(oContext));
+
+       var sUri        = (this.namespaceURI ? '{' + this.namespaceURI + '}' : 
'') + this.localName;
+               if (this.namespaceURI == sNS_XPF) {
+               if (fFunction = hStaticContext_functions[this.localName]) {
+                                               if (aParameters = 
hStaticContext_signatures[this.localName])
+                               fFunctionCall_prepare(this.localName, 
aParameters, fFunction, aArguments, oContext);
+                                               var vResult     = 
fFunction.apply(oContext, aArguments);
+                                               return vResult == null ? [] : 
vResult instanceof cArray ? vResult : [vResult];
+               }
+               throw new cException("XPST0017"
+                               , "Unknown system function: " + sUri + '()'
+               );
+       }
+       else
+       if (this.namespaceURI == sNS_XSD) {
+               if ((fFunction = hStaticContext_dataTypes[this.localName]) && 
this.localName != "NOTATION" && this.localName != "anyAtomicType") {
+                                               
fFunctionCall_prepare(this.localName, [[cXSAnyAtomicType]], fFunction, 
aArguments, oContext);
+                                               return 
[fFunction.cast(aArguments[0])];
+               }
+               throw new cException("XPST0017"
+                               , "Unknown type constructor function: " + sUri 
+ '()'
+               );
+       }
+       else
+       if (fFunction = oContext.staticContext.getFunction(sUri)) {
+                               var vResult     = fFunction.apply(oContext, 
aArguments);
+                               return vResult == null ? [] : vResult 
instanceof cArray ? vResult : [vResult];
+       }
+               throw new cException("XPST0017"
+                       , "Unknown user function: " + sUri + '()'
+       );
+};
+
+var aFunctionCall_numbers      = ["first", "second", "third", "fourth", 
"fifth"];
+function fFunctionCall_prepare(sName, aParameters, fFunction, aArguments, 
oContext) {
+       var oArgument,
+               nArgumentsLength        = aArguments.length,
+               oParameter,
+               nParametersLength       = aParameters.length,
+               nParametersRequired     = 0;
+
+               while ((nParametersRequired < aParameters.length) && 
!aParameters[nParametersRequired][2])
+               nParametersRequired++;
+
+               if (nArgumentsLength > nParametersLength)
+               throw new cException("XPST0017"
+                               , "Function " + sName + "() must have " + 
(nParametersLength ? " no more than " : '') + nParametersLength + " argument" + 
(nParametersLength > 1 || !nParametersLength ? 's' : '')
+               );
+       else
+       if (nArgumentsLength < nParametersRequired)
+               throw new cException("XPST0017"
+                               , "Function " + sName + "() must have " + 
(nParametersRequired == nParametersLength ? "exactly" : "at least") + ' ' + 
nParametersRequired + " argument" + (nParametersLength > 1 ? 's' : '')
+               );
+
+       for (var nIndex = 0; nIndex < nArgumentsLength; nIndex++) {
+               oParameter      = aParameters[nIndex];
+               oArgument       = aArguments[nIndex];
+                               
fFunctionCall_assertSequenceCardinality(oContext, oArgument, oParameter[1]
+                               , aFunctionCall_numbers[nIndex] + " argument of 
" + sName + '()'
+               );
+                               fFunctionCall_assertSequenceItemType(oContext, 
oArgument, oParameter[0]
+                               , aFunctionCall_numbers[nIndex] + " argument of 
" + sName + '()'
+               );
+               if (oParameter[1] != '+' && oParameter[1] != '*')
+                       aArguments[nIndex]      = oArgument.length ? 
oArgument[0] : null;
+       }
+};
+
+function fFunctionCall_assertSequenceItemType(oContext, oSequence, cItemType
+               , sSource
+       ) {
+               for (var nIndex = 0, nLength = oSequence.length, nNodeType, 
vItem; nIndex < nLength; nIndex++) {
+               vItem   = oSequence[nIndex];
+                               if (cItemType == cXTNode || cItemType.prototype 
instanceof cXTNode) {
+                                               if 
(!oContext.DOMAdapter.isNode(vItem))
+                               throw new cException("XPTY0004"
+                                               , "Required item type of " + 
sSource + " is " + cItemType
+                               );
+
+                                               if (cItemType != cXTNode) {
+                               nNodeType       = 
oContext.DOMAdapter.getProperty(vItem, "nodeType");
+                               if ([null, cXTElement, cXTAttribute, cXTText, 
cXTText, null, null, cXTProcessingInstruction, cXTComment, cXTDocument, null, 
null, null][nNodeType] != cItemType)
+                                       throw new cException("XPTY0004"
+                                                       , "Required item type 
of " + sSource + " is " + cItemType
+                                       );
+                       }
+               }
+               else
+                               if (cItemType == cXSAnyAtomicType || 
cItemType.prototype instanceof cXSAnyAtomicType) {
+                                               vItem   = 
fFunction_sequence_atomize([vItem], oContext)[0];
+                                               if (cItemType != 
cXSAnyAtomicType) {
+                                                               if (vItem 
instanceof cXSUntypedAtomic)
+                                       vItem   = cItemType.cast(vItem);
+                                                               else
+                               if (cItemType == cXSString) {
+                                       if (vItem instanceof cXSAnyURI)
+                                               vItem   = cXSString.cast(vItem);
+                               }
+                               else
+                               if (cItemType == cXSDouble) {
+                                       if (fXSAnyAtomicType_isNumeric(vItem))
+                                               vItem   = cItemType.cast(vItem);
+                               }
+                       }
+                                               if (!(vItem instanceof 
cItemType))
+                               throw new cException("XPTY0004"
+                                               , "Required item type of " + 
sSource + " is " + cItemType
+                               );
+                                               oSequence[nIndex]       = vItem;
+               }
+       }
+};
+
+function fFunctionCall_assertSequenceCardinality(oContext, oSequence, 
sCardinality
+               , sSource
+       ) {
+       var nLength     = oSequence.length;
+               if (sCardinality == '?') {                      if (nLength > 1)
+                       throw new cException("XPTY0004"
+                                       , "Required cardinality of " + sSource 
+ " is one or zero"
+                       );
+       }
+       else
+       if (sCardinality == '+') {                      if (nLength < 1)
+                       throw new cException("XPTY0004"
+                                       , "Required cardinality of " + sSource 
+ " is one or more"
+                       );
+       }
+       else
+       if (sCardinality != '*') {                      if (nLength != 1)
+                       throw new cException("XPTY0004"
+                                       , "Required cardinality of " + sSource 
+ " is exactly one"
+                       );
+       }
+};
+
+
+function cIntersectExceptExpr(oExpr) {
+       this.left       = oExpr;
+       this.items      = [];
+};
+
+cIntersectExceptExpr.prototype.left            = null;
+cIntersectExceptExpr.prototype.items   = null;
+
+function fIntersectExceptExpr_parse (oLexer, oStaticContext) {
+       var oExpr,
+               sOperator;
+       if (oLexer.eof() ||!(oExpr = fInstanceofExpr_parse(oLexer, 
oStaticContext)))
+               return;
+       if (!((sOperator = oLexer.peek()) == "intersect" || sOperator == 
"except"))
+               return oExpr;
+
+               var oIntersectExceptExpr        = new 
cIntersectExceptExpr(oExpr);
+       while ((sOperator = oLexer.peek()) == "intersect" || sOperator == 
"except") {
+               oLexer.next();
+               if (oLexer.eof() ||!(oExpr = fInstanceofExpr_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected second operand in " + 
sOperator + " expression"
+                       );
+               oIntersectExceptExpr.items.push([sOperator, oExpr]);
+       }
+       return oIntersectExceptExpr;
+};
+
+cIntersectExceptExpr.prototype.evaluate        = function (oContext) {
+       var oSequence   = this.left.evaluate(oContext);
+       for (var nIndex = 0, nLength = this.items.length, oItem; nIndex < 
nLength; nIndex++)
+               oSequence       = hStaticContext_operators[(oItem = 
this.items[nIndex])[0]].call(oContext, oSequence, oItem[1].evaluate(oContext));
+       return oSequence;
+};
+
+
+function cRangeExpr(oLeft, oRight) {
+       this.left       = oLeft;
+       this.right      = oRight;
+};
+
+cRangeExpr.prototype.left      = null;
+cRangeExpr.prototype.right     = null;
+
+function fRangeExpr_parse (oLexer, oStaticContext) {
+       var oExpr,
+               oRight;
+       if (oLexer.eof() ||!(oExpr = fAdditiveExpr_parse(oLexer, 
oStaticContext)))
+               return;
+       if (oLexer.peek() != "to")
+               return oExpr;
+
+               oLexer.next();
+       if (oLexer.eof() ||!(oRight = fAdditiveExpr_parse(oLexer, 
oStaticContext)))
+               throw new cException("XPST0003"
+                               , "Expected second operand in range expression"
+               );
+       return new cRangeExpr(oExpr, oRight);
+};
+
+cRangeExpr.prototype.evaluate  = function (oContext) {
+               var oLeft       = this.left.evaluate(oContext);
+       if (!oLeft.length)
+               return [];
+               var sSource     = "first operand of 'to'";
+
+       fFunctionCall_assertSequenceCardinality(oContext, oLeft, '?'
+                       , sSource
+       );
+       fFunctionCall_assertSequenceItemType(oContext, oLeft, cXSInteger
+                       , sSource
+       );
+
+       var oRight      = this.right.evaluate(oContext);
+       if (!oRight.length)
+               return [];
+
+       sSource = "second operand of 'to'";
+
+       fFunctionCall_assertSequenceCardinality(oContext, oRight, '?'
+                       , sSource
+       );
+       fFunctionCall_assertSequenceItemType(oContext, oRight, cXSInteger
+                       , sSource
+       );
+
+       return hStaticContext_operators["to"].call(oContext, oLeft[0], 
oRight[0]);
+};
+
+
+function cUnionExpr(oExpr) {
+       this.left       = oExpr;
+       this.items      = [];
+};
+
+cUnionExpr.prototype.left      = null;
+cUnionExpr.prototype.items     = null;
+
+function fUnionExpr_parse (oLexer, oStaticContext) {
+       var oExpr,
+               sOperator;
+       if (oLexer.eof() ||!(oExpr = fIntersectExceptExpr_parse(oLexer, 
oStaticContext)))
+               return;
+       if (!((sOperator = oLexer.peek()) == '|' || sOperator == "union"))
+               return oExpr;
+
+               var oUnionExpr  = new cUnionExpr(oExpr);
+       while ((sOperator = oLexer.peek()) == '|' || sOperator == "union") {
+               oLexer.next();
+               if (oLexer.eof() ||!(oExpr = fIntersectExceptExpr_parse(oLexer, 
oStaticContext)))
+                       throw new cException("XPST0003"
+                                       , "Expected second operand in union 
expression"
+                       );
+               oUnionExpr.items.push(oExpr);
+       }
+       return oUnionExpr;
+};
+
+cUnionExpr.prototype.evaluate  = function (oContext) {
+       var oSequence   = this.left.evaluate(oContext);
+       for (var nIndex = 0, nLength = this.items.length; nIndex < nLength; 
nIndex++)
+               oSequence       = 
hStaticContext_operators["union"].call(oContext, oSequence, 
this.items[nIndex].evaluate(oContext));
+       return oSequence;
+};
+
+
+function cInstanceofExpr(oExpr, oType) {
+       this.expression = oExpr;
+       this.type               = oType;
+};
+
+cInstanceofExpr.prototype.expression   = null;
+cInstanceofExpr.prototype.type                 = null;
+
+function fInstanceofExpr_parse (oLexer, oStaticContext) {
+       var oExpr,
+               oType;
+       if (oLexer.eof() ||!(oExpr = fTreatExpr_parse(oLexer, oStaticContext)))
+               return;
+
+       if (!(oLexer.peek() == "instance" && oLexer.peek(1) == "of"))
+               return oExpr;
+
+       oLexer.next(2);
+       if (oLexer.eof() ||!(oType = fSequenceType_parse(oLexer, 
oStaticContext)))
+               throw new cException("XPST0003"
+                               , "Expected second operand in instance of 
expression"
+               );
+
+       return new cInstanceofExpr(oExpr, oType);
+};
+
+cInstanceofExpr.prototype.evaluate     = function(oContext) {
+       var oSequence1  = this.expression.evaluate(oContext),
+               oItemType       = this.type.itemType,
+               sOccurence      = this.type.occurence;
+               if (!oItemType)
+               return [new cXSBoolean(!oSequence1.length)];
+               if (!oSequence1.length)
+               return [new cXSBoolean(sOccurence == '?' || sOccurence == '*')];
+       if (oSequence1.length != 1)
+               if (!(sOccurence == '+' || sOccurence == '*'))
+                       return [new cXSBoolean(false)];
+
+               if (!oItemType.test)                    return [new 
cXSBoolean(true)];
+
+       var bValue      = true;
+       for (var nIndex = 0, nLength = oSequence1.length; (nIndex < nLength) && 
bValue; nIndex++)
+               bValue  = oItemType.test.test(oSequence1[nIndex], oContext);
+               return [new cXSBoolean(bValue)];
+};
+
+
+function cTreatExpr(oExpr, oType) {
+       this.expression = oExpr;
+       this.type               = oType;
+};
+
+cTreatExpr.prototype.expression        = null;
+cTreatExpr.prototype.type              = null;
+
+function fTreatExpr_parse (oLexer, oStaticContext) {
+       var oExpr,
+               oType;
+       if (oLexer.eof() ||!(oExpr = fCastableExpr_parse(oLexer, 
oStaticContext)))
+               return;
+
+       if (!(oLexer.peek() == "treat" && oLexer.peek(1) == "as"))
+               return oExpr;
+
+       oLexer.next(2);
+       if (oLexer.eof() ||!(oType = fSequenceType_parse(oLexer, 
oStaticContext)))
+               throw new cException("XPST0003"
+                               , "Expected second operand in treat expression"
+               );
+
+       return new cTreatExpr(oExpr, oType);
+};
+
+cTreatExpr.prototype.evaluate  = function(oContext) {
+       var oSequence1  = this.expression.evaluate(oContext),
+               oItemType       = this.type.itemType,
+               sOccurence      = this.type.occurence;
+               if (!oItemType) {
+               if (oSequence1.length)
+                       throw new cException("XPDY0050"
+                                       , "The only value allowed for the value 
in 'treat as' expression is an empty sequence"
+                       );
+               return oSequence1;
+       }
+
+               if (!(sOccurence == '?' || sOccurence == '*'))
+               if (!oSequence1.length)
+                       throw new cException("XPDY0050"
+                                       , "An empty sequence is not allowed as 
the value in 'treat as' expression"
+                       );
+
+       if (!(sOccurence == '+' || sOccurence == '*'))
+               if (oSequence1.length != 1)
+                       throw new cException("XPDY0050"
+                                       , "A sequence of more than one item is 
not allowed as the value in 'treat as' expression"
+                       );
+
+               if (!oItemType.test)                    return oSequence1;
+
+       for (var nIndex = 0, nLength = oSequence1.length; nIndex < nLength; 
nIndex++)
+               if (!oItemType.test.test(oSequence1[nIndex], oContext))
+                       throw new cException("XPDY0050"
+                                       , "Required item type of value in 
'treat as' expression is " + (oItemType.test.prefix ? oItemType.test.prefix + 
':' : '') + oItemType.test.localName
+                                                               );
+
+               return oSequence1;
+};
+
+
+function cCastableExpr(oExpr, oType) {
+       this.expression = oExpr;
+       this.type               = oType;
+};
+
+cCastableExpr.prototype.expression     = null;
+cCastableExpr.prototype.type           = null;
+
+function fCastableExpr_parse (oLexer, oStaticContext) {
+       var oExpr,
+               oType;
+       if (oLexer.eof() ||!(oExpr = fCastExpr_parse(oLexer, oStaticContext)))
+               return;
+
+       if (!(oLexer.peek() == "castable" && oLexer.peek(1) == "as"))
+               return oExpr;
+
+       oLexer.next(2);
+       if (oLexer.eof() ||!(oType = fSingleType_parse(oLexer, oStaticContext)))
+               throw new cException("XPST0003"
+                               , "Expected second operand in castable 
expression"
+               );
+
+       return new cCastableExpr(oExpr, oType);
+};
+
+cCastableExpr.prototype.evaluate       = function(oContext) {
+       var oSequence1  = this.expression.evaluate(oContext),
+               oItemType       = this.type.itemType,
+               sOccurence      = this.type.occurence;
+
+       if (oSequence1.length > 1)
+               return [new cXSBoolean(false)];
+       else
+       if (!oSequence1.length)
+               return [new cXSBoolean(sOccurence == '?')];
+
+               try {
+               oItemType.cast(fFunction_sequence_atomize(oSequence1, 
oContext)[0]);
+       }
+       catch (e) {
+               if (e.code == "XPST0051")
+                       throw e;
+               if (e.code == "XPST0017")
+                       throw new cException("XPST0080"
+                                       , "No value is castable to " + 
(oItemType.prefix ? oItemType.prefix + ':' : '') + oItemType.localName
+                       );
+                               return [new cXSBoolean(false)];
+       }
+
+       return [new cXSBoolean(true)];
+};
+
+
+function cCastExpr(oExpr, oType) {
+       this.expression = oExpr;
+       this.type               = oType;
+};
+
+cCastExpr.prototype.expression = null;
+cCastExpr.prototype.type               = null;
+
+function fCastExpr_parse (oLexer, oStaticContext) {
+       var oExpr,
+               oType;
+       if (oLexer.eof() ||!(oExpr = fUnaryExpr_parse(oLexer, oStaticContext)))
+               return;
+
+       if (!(oLexer.peek() == "cast" && oLexer.peek(1) == "as"))
+               return oExpr;
+
+       oLexer.next(2);
+       if (oLexer.eof() ||!(oType = fSingleType_parse(oLexer, oStaticContext)))
+               throw new cException("XPST0003"
+                               , "Expected second operand in cast expression"
+               );
+
+       return new cCastExpr(oExpr, oType);
+};
+
+cCastExpr.prototype.evaluate   = function(oContext) {
+       var oSequence1  = this.expression.evaluate(oContext);
+               fFunctionCall_assertSequenceCardinality(oCont

<TRUNCATED>

Reply via email to