<?xml version="1.0" encoding="UTF-8"?>

<!-- Current changes labelled at="A": first 3.1 draft -->
<!-- Current changes labeled at="B": post - April 2014 Working Draft -->
<!-- Current changes labeled at="C": post - October 2014 Working Draft -->
<!-- Current changes labeled at="D": post - December 2014 Working Draft -->
<!-- Current changes labeled at="E": post - January 2016 CR -->
<!-- Current changes labeled at="F": post - 13 December 2016 CR -->
<!-- TODO: reinstate the operand usage values (for XSLT streamability) -->
<fos:functions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.w3.org/xpath-functions/spec/namespace fos.xsd"
   xmlns:fos="http://www.w3.org/xpath-functions/spec/namespace">
   <fos:global-variables>
      <fos:variable id="v-po" name="po" as="element()">&lt;PurchaseOrder&gt; &lt;line-item&gt;
         &lt;description&gt;Large widget&lt;/description&gt; &lt;price&gt;8.95&lt;/price&gt;
         &lt;quantity&gt;5.0&lt;/quantity&gt; &lt;/line-item&gt; &lt;line-item&gt;
         &lt;description&gt;Small widget&lt;/description&gt; &lt;price&gt;3.99&lt;/price&gt;
         &lt;quantity&gt;2.0&lt;/quantity&gt; &lt;/line-item&gt; &lt;line-item&gt;
         &lt;description&gt;Tiny widget&lt;/description&gt; &lt;price&gt;1.49&lt;/price&gt;a
         &lt;quantity&gt;805&lt;/quantity&gt; &lt;/line-item&gt;
         &lt;/PurchaseOrder&gt;</fos:variable>
      <fos:variable id="v-item1" name="item1" select="$po/line-item[1]"/>
      <fos:variable id="v-item2" name="item2" select="$po/line-item[2]"/>
      <fos:variable id="v-item3" name="item3" select="$po/line-item[3]"/>
   </fos:global-variables>
   <fos:function name="node-name" prefix="fn">
      <fos:signatures>
         <fos:proto at="F" name="node-name" return-type="xs:QName?"/>
         <fos:proto name="node-name" return-type="xs:QName?">
            <fos:arg name="arg" type="node()?" default="." usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the name of a node, as an <code>xs:QName</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If the argument is omitted, it defaults to the context item (<code>.</code>). The
            behavior of the function if the argument is omitted is exactly the same as if the
            context item had been passed as the argument.</p>
         <p>If <code>$arg</code> is the empty sequence, the empty sequence is returned.</p>
         <p>Otherwise, the function returns the result of the <code>dm:node-name</code> accessor as
            defined in <bibref ref="xpath-datamodel-31"/> (see <xspecref spec="DM31"
               ref="dm-node-name"/>).</p>
      </fos:rules>
      <fos:errors>
         <p>The following errors may be raised when <code>$arg</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>

      </fos:errors>
      <fos:notes>
         <p>For element and attribute nodes, the name of the node is returned as an
               <code>xs:QName</code>, retaining the prefix, namespace URI, and local part.</p>
         <p>For processing instructions, the name of the node is returned as an
               <code>xs:QName</code> in which the prefix and namespace URI are <xtermref
               ref="dt-absent" spec="DM31">absent</xtermref>.</p>
         <p>For a namespace node, the function returns an empty sequence if the node represents the
            default namespace; otherwise it returns an <code>xs:QName</code> in which prefix and
            namespace URI are <xtermref ref="dt-absent" spec="DM31">absent</xtermref> and the local
            part is the namespace prefix being bound.</p>
         <p>For all other kinds of node, the function returns the empty sequence.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="nilled" prefix="fn">
      <fos:signatures>
         <fos:proto name="nilled" return-type="xs:boolean?"/>
         <fos:proto name="nilled" return-type="xs:boolean?">
            <fos:arg name="arg" type="node()?" default="." usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>

      <fos:summary>
         <p>Returns true for an element that is <term>nilled</term>.</p>
      </fos:summary>
      <fos:rules>
         <p>If the argument is omitted, it defaults to the context item (<code>.</code>). The
            behavior of the function if the argument is omitted is exactly the same as if the
            context item had been passed as the argument.</p>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise the function returns the result of the <code>dm:nilled</code> accessor as
            defined in <bibref ref="xpath-datamodel-31"/> (see <xspecref spec="DM31" ref="dm-nilled"
            />).</p>
      </fos:rules>
      <fos:errors>
         <p>The following errors may be raised when <code>$arg</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>

      </fos:errors>
      <fos:notes>
         <p>If <code>$arg</code> is not an element node, the function returns the empty
            sequence.</p>
         <p>If <code>$arg</code> is an untyped element node, the function returns false.</p>
         <p>In practice, the function returns <code>true</code> only for an element node that has
            the attribute <code>xsi:nil="true"</code> and that is successfully validated against a
            schema that defines the element to be nillable; the detailed rules, however, are defined
            in <bibref ref="xpath-datamodel-31"/>.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="string" prefix="fn">
      <fos:signatures>
         <fos:proto name="string" return-type="xs:string"/>
         <fos:proto name="string" return-type="xs:string">
            <fos:arg name="arg" type="item()?" default="." usage="absorption"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the value of <code>$arg</code> represented as an <code>xs:string</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>In the zero-argument version of the function, <code>$arg</code> defaults to the context
            item. That is, calling <code>fn:string()</code> is equivalent to calling
               <code>fn:string(.)</code>.</p>
         <p>If <code>$arg</code> is the empty sequence, the function returns the zero-length
            string.</p>
         
               <p>If <var>$arg</var> is a node, the function returns the string value of the node, as obtained using the
                     <code>dm:string-value</code> accessor defined in <bibref
                     ref="xpath-datamodel-31"/> (see <xspecref spec="DM31" ref="dm-string-value"
                  />).</p>
            
               <p>If <var>$arg</var> is an atomic value, the function returns the result of the expression <code>$arg cast
                     as xs:string</code> (see <specref ref="casting"/>).</p>
            
               <p>In all other cases, a dynamic error occurs (see below).</p>
 

      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <xerrorref spec="XP" class="DY" code="0002" type="type"/> by
            the zero-argument version of the function if the context item is <xtermref
               ref="dt-absent" spec="DM31">absent</xtermref>. </p>
         <p>A type error is raised <errorref class="TY" code="0014" type="type"/> if
               <code>$arg</code> is a function item (this includes maps and arrays).</p>
      </fos:errors>
      <fos:notes>
         <p diff="add" at="A">Every node has a string value, even an element with element-only
            content (which has no typed value). Moreover, casting an atomic value to a string always
            succeeds. Functions, maps, and arrays have no string value, so these are the
            only arguments that satisfy the type signature but cause failure.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>string(23)</fos:expression>
               <fos:result>"23"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>string(false())</fos:expression>
               <fos:result>"false"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>string("Paris")</fos:expression>
               <fos:result>"Paris"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>string((1, 2, 3))</fos:expression>
               <fos:error-result error-code="XPTY0004"/>
            </fos:test>
            <fos:test>
               <fos:expression>string([[1, 2], [3, 4]])</fos:expression>
               <fos:error-result error-code="FOTY0014"/>
            </fos:test>
            <fos:test>
               <fos:expression>string(abs#1)</fos:expression>
               <fos:error-result error-code="FOTY0014"/>
            </fos:test>
         </fos:example>
         <fos:variable id="v-string-para" name="para"><![CDATA[
<para>In a hole in the ground there lived a <term author="Tolkien">hobbit</term>.</para>]]>
         </fos:variable>
         <fos:example>
            <fos:test use="v-string-para">
               <fos:expression>string($para)</fos:expression>
               <fos:result>"In a hole in the ground there lived a hobbit."</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="data" prefix="fn">
      <fos:signatures>
         <fos:proto name="data" return-type="xs:anyAtomicType*"/>
         <fos:proto name="data" return-type="xs:anyAtomicType*">
            <fos:arg name="arg" type="item()*" default="." usage="absorption"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p diff="chg" at="C">Returns the result of atomizing a sequence. This process flattens arrays, and replaces nodes by their typed values.</p>
      </fos:summary>
      <fos:rules>
         <p>If the argument is omitted, it defaults to the context item (<code>.</code>). The
            behavior of the function if the argument is omitted is exactly the same as if the
            context item had been passed as the argument.</p>
         <p> The result of <code>fn:data</code> is the sequence of atomic values produced by
            applying the following rules to each item in <code>$arg</code>:</p>
         <ulist>
            <item>
               <p>If the item is an atomic value, it is appended to the result sequence.</p>
            </item>
            <item>
               <p>If the item is a node, the typed value of the node is appended to the result
                  sequence. The typed value is a sequence of zero or more atomic values:
                  specifically, the result of the <code>dm:typed-value</code> accessor as defined in
                     <bibref ref="xpath-datamodel-31"/> (See <xspecref spec="DM31"
                     ref="dm-typed-value"/>).</p>
            </item>
            <item diff="add" at="A">
               <p>If the item is an array, the result of applying <code>fn:data</code> to
                  each member of the array, in order, is appended to the result sequence.</p>
            </item>
         </ulist>
      </fos:rules>
      <fos:errors>
         <p>A type error is raised <errorref class="TY" code="0012" type="type"/> if an item in the
            sequence <code>$arg</code> is a node that does not have a typed value. </p>
         <p>A type error is raised <errorref class="TY" code="0013" type="dynamic"/> if an item in
            the sequence <code>$arg</code> is a function item <phrase diff="add" at="A">other than
               an array</phrase>. </p>

         <p>A dynamic error is raised if <code>$arg</code> is omitted and the context item is
               <xtermref ref="dt-absent" spec="DM31">absent</xtermref>.</p>


      </fos:errors>
      <fos:notes>
         <p>The process of applying the <code>fn:data</code> function to a sequence is referred to
            as <code>atomization</code>. In many cases an explicit call on <code>fn:data</code> is
            not required, because atomization is invoked implicitly when a node or sequence of nodes
            is supplied in a context where an atomic value or sequence of atomic values is
            required.</p>
         <p>The result of atomizing an empty sequence is an empty sequence.</p>
         <p>The result of atomizing an empty array is an empty sequence.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>data(123)</fos:expression>
               <fos:result>123</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>data((123, 456))</fos:expression>
               <fos:result>123, 456</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>data([[1,2],[3,4]])</fos:expression>
               <fos:result>1, 2, 3, 4</fos:result>
            </fos:test>
         </fos:example>

         <fos:variable id="v-data-para" name="para"><![CDATA[
<para>In a hole in the ground there lived a <term author="Tolkien">hobbit</term>.</para>]]>
         </fos:variable>
         <fos:example>
            <fos:test use="v-data-para">
               <fos:expression>data($para)</fos:expression>
               <fos:result>xs:untypedAtomic("In a hole in the ground there lived a hobbit.")</fos:result>
            </fos:test>
            <fos:test use="v-data-para">
               <fos:expression>data($para/term/@author)</fos:expression>
               <fos:result>xs:untypedAtomic("Tolkien")</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>data(abs#1)</fos:expression>
               <fos:error-result error-code="FOTY0013"/>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="base-uri" prefix="fn">
      <fos:signatures>
         <fos:proto name="base-uri" return-type="xs:anyURI?"/>
         <fos:proto name="base-uri" return-type="xs:anyURI?">
            <fos:arg name="arg" type="node()?" default="." usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the base URI of a node.</p>
      </fos:summary>
      <fos:rules>
         <!-- see bug 6340 -->
         <p>The zero-argument version of the function returns the base URI of the context node: it
            is equivalent to calling <code>fn:base-uri(.)</code>.</p>
         <p>The single-argument version of the function behaves as follows:</p>
         <olist>
            <item>If <code>$arg</code> is the empty sequence, the function returns the empty
               sequence.</item>

            <item>Otherwise, the function returns the value of the <code>dm:base-uri</code> accessor
               applied to the node <code>$arg</code>. This accessor is defined, for each kind of
               node, in the XDM specification (See <xspecref spec="DM31" ref="dm-base-uri"
               />).</item>
         </olist>
         <note>As explained in XDM, document, element and processing-instruction nodes have a
            base-uri property which may be empty. The base-uri property for all other node kinds is
            the empty sequence. The dm:base-uri accessor returns the base-uri property of a node if
            it exists and is non-empty; otherwise it returns the result of applying the dm:base-uri
            accessor to its parent, recursively. If the node does not have a parent, or if the
            recursive ascent up the ancestor chain encounters a parentless node whose base-uri
            property is empty, the empty sequence is returned. In the case of namespace nodes,
            however, the result is always an empty sequence &#x2014; it does not depend on the base URI of
            the parent element.</note>


         <p>See also <code>fn:static-base-uri</code>.</p>
      </fos:rules>
      <fos:errors>
         <p>The following errors may be raised when <code>$arg</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>
      </fos:errors>
   </fos:function>
   <fos:function name="document-uri" prefix="fn">
      <fos:signatures>
         <fos:proto name="document-uri" return-type="xs:anyURI?"/>
         <fos:proto name="document-uri" return-type="xs:anyURI?">
            <fos:arg name="arg" type="node()?" default="." usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the URI of a resource where a document can be found, if available.</p>
      </fos:summary>
      <fos:rules>
         <p>If the argument is omitted, it defaults to the context item (<code>.</code>). The
            behavior of the function if the argument is omitted is exactly the same as if the
            context item had been passed as the argument.</p>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>If <code>$arg</code> is not a document node, the function returns the empty
            sequence.</p>
         <p>Otherwise, the function returns the value of the <code>document-uri</code> accessor
            applied to <code>$arg</code>, as defined in <bibref ref="xpath-datamodel-31"/> (See
               <xspecref spec="DM31" ref="DocumentNodeAccessors"/>).</p>
      </fos:rules>
      <fos:errors>
         <p>The following errors may be raised when <code>$arg</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>

      </fos:errors>
      <fos:notes>
         <p>In the case of a document node <code>$D</code> returned by the <code>fn:doc</code>
            function, or a document node at the root of a tree containing a node returned by the
               <code>fn:collection</code> function, it will always be true that either
               <code>fn:document-uri($D)</code> returns the empty sequence, or that the following
            expression is true: <code>fn:doc(fn:document-uri($D))</code> is <code>$D</code>. It is
               <termref def="implementation-defined">implementation-defined</termref> whether this guarantee also holds for
            document nodes obtained by other means, for example a document node passed as the
            initial context node of a query or transformation.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="error" prefix="fn">
      <fos:signatures>
         <fos:proto name="error" return-type="none"/>
         <fos:proto name="error" return-type="none">
            <fos:arg name="code" type="xs:QName?"/>
         </fos:proto>
         <fos:proto name="error" return-type="none">
            <fos:arg name="code" type="xs:QName?"/>
            <fos:arg name="description" type="xs:string"/>
         </fos:proto>
         <fos:proto name="error" return-type="none">
            <fos:arg name="code" type="xs:QName?"/>
            <fos:arg name="description" type="xs:string"/>
            <fos:arg name="error-object" type="item()*" default="." usage="navigation"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>nondeterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Calling the <code>fn:error</code> function raises an application-defined error.</p>
      </fos:summary>
      <fos:rules>
         <p>This function never returns a value. Instead it always raises an error. The effect of
            the error is identical to the effect of dynamic errors raised implicitly, for example
            when an incorrect argument is supplied to a function.</p>
         <p>The parameters to the <code>fn:error</code> function supply information that is
            associated with the error condition and that is made available to a caller that asks for
            information about the error. The error may be caught either by the host language (using
            a try/catch construct in XSLT or XQuery, for example), or by the calling application or
            external processing environment. The way in which error information is returned to the
            external processing environment is <termref def="implementation-dependent">implementation-dependent</termref>.</p>
         
         <p>There are three pieces of information that may be associated with an error:</p>
         <ulist>
            <item>
               <p>The <code>$code</code> is an error code that distinguishes this error from others.
                  It is an <code>xs:QName</code>; the namespace URI conventionally identifies the
                  component, subsystem, or authority responsible for defining the meaning of the
                  error code, while the local part identifies the specific error condition. The
                  namespace URI <code>http://www.w3.org/2005/xqt-errors</code> is used for errors
                  defined in this specification; other namespace URIs may be used for errors defined
                  by the application.</p>
               <p>If the external processing environment expects the error code to be returned as a
                  URI or a string rather than as an <code>xs:QName</code>, then an error code with
                  namespace URI <code>NS</code> and local part <code>LP</code> will be returned in
                  the form <code>NS#LP</code>. The namespace URI part of the error code should
                  therefore not include a fragment identifier.</p>
               <p diff="add" at="B">If no value is supplied for the <code>$code</code> argument (that is,
                  if the function is called with no arguments or if the first argument is an empty sequence),
                  the effective value of the error code is <code>fn:QName('http://www.w3.org/2005/xqt-errors', 'err:FOER0000')</code>.</p>
            </item>
            <item>
               <p>The <code>$description</code> is a natural-language description of the error
                  condition.</p>
               <p diff="add" at="B-bug24359">If no value is supplied for the <code>$description</code>
                  argument (that is, if the function is called with less than two arguments), then the
                  effective value of the description is <termref def="implementation-dependent">implementation-dependent</termref>.</p>
            </item>
            <item>
               <p>The <code>$error-object</code> is an arbitrary value used to convey additional
                  information about the error, and may be used in any way the application
                  chooses.</p>
               <p diff="add" at="B-bug24359">If no value is supplied for the <code>$error-object</code>
                  argument (that is, if the function is called with less than three arguments), then the
                  effective value of the error object is <termref def="implementation-dependent">implementation-dependent</termref>.</p>
            </item>
         </ulist>
         
         
         
      </fos:rules>
      <fos:errors>
         <p>This function always raises a dynamic error. By default, it raises <errorref class="ER"
               code="0000"/></p>
      </fos:errors>
      <fos:notes>
         <p>The value of the <code>$description</code> parameter may need to be localized.</p>
         <p>The type <quote>none</quote> is a special type defined in <bibref ref="xquery-semantics"
            /> and is not available to the user. It indicates that the function never returns and
            ensures that it has the correct static type.</p>
         <p>Any QName may be used as an error code; there are no reserved names or namespaces. The
            error is always classified as a dynamic error, even if the error code used is one that
            is normally used for static errors or type errors.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:error()</fos:expression>
               <fos:error-result error-code="FOER0000"/>
               <fos:postamble>This returns the URI
                     <code>http://www.w3.org/2005/xqt-errors#FOER0000</code> (or the corresponding
                     <code>xs:QName</code>) to the external processing environment, unless the error
                  is caught using a try/catch construct in the host language.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:error(fn:QName('http://www.example.com/HR', 'myerr:toohighsal'),
                  'Does not apply because salary is too high')</fos:expression>
               <fos:error-result error-code="myerr:toohighsal"/>
               <fos:postamble>This returns <code>http://www.example.com/HR#toohighsal</code> and the
                     <code>xs:string</code>
                  <code>"Does not apply because salary is too high"</code> (or the corresponding
                     <code>xs:QName</code>) to the external processing environment, unless the error
                  is caught using a try/catch construct in the host language.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="trace" prefix="fn">
      <fos:signatures>
         <fos:proto name="trace" return-type="item()*">
            <fos:arg name="value" type="item()*"/>
         </fos:proto>
         <fos:proto name="trace" return-type="item()*">
            <fos:arg name="value" type="item()*" usage="transmission"/>
            <fos:arg name="label" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Provides an execution trace intended to be used in debugging queries.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the value of <code>$value</code>, unchanged.</p>
         <p>In addition, the values of <code>$value</code>, converted to an <code>xs:string</code>,
            and <code>$label</code> <phrase diff="add" at="B">(if supplied)</phrase>
            <rfc2119>may</rfc2119> be directed to a trace data set. The destination of the trace
            output is <termref def="implementation-defined">implementation-defined</termref>. The format of the trace output is
            <termref def="implementation-dependent">implementation-dependent</termref>. The ordering of output from calls of the
            <code>fn:trace</code> function is <termref def="implementation-dependent">implementation-dependent</termref>.</p>
      </fos:rules>
      <fos:notes>
         <p>Sometimes there is a need to output trace information unrelated to a specific value.
            In such cases it can be useful to set <code>$value</code> to an empty string or an empty
            sequence, and to compute the value of the <code>$label</code> argument: 
            <code>fn:trace((), "Processing item " || $i)</code>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p>Consider a situation in which a user wants to investigate the actual value passed to
               a function. Assume that in a particular execution, <code>$v</code> is an
                  <code>xs:decimal</code> with value <code>124.84</code>. Writing <code>fn:trace($v,
                  'the value of $v is:')</code> will put the strings <code>"124.84"</code> and
                  <code>"the value of $v is:"</code> in the trace data set in implementation
               dependent order.</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="numeric-add" prefix="op">
      <fos:signatures>
         <fos:proto name="numeric-add" return-type="xs:numeric">
            <fos:arg name="arg1" type="xs:numeric"/>
            <fos:arg name="arg2" type="xs:numeric"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="+" types="numeric">Defines the semantics of the "+" operator when
         applied to two numeric values</fos:opermap>
      <fos:summary>
         <p>Returns the arithmetic sum of its operands: (<code>$arg1 + $arg2</code>).</p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="op.numeric"/>.</p>
      </fos:rules>
      <fos:notes>
         <p> For <code>xs:float</code> or <code>xs:double</code> values, if one of the operands is a
            zero or a finite number and the other is <code>INF</code> or <code>-INF</code>,
               <code>INF</code> or <code>-INF</code> is returned. If both operands are
               <code>INF</code>, <code>INF</code> is returned. If both operands are
               <code>-INF</code>, <code>-INF</code> is returned. If one of the operands is
               <code>INF</code> and the other is <code>-INF</code>, <code>NaN</code> is
            returned.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="numeric-subtract" prefix="op">
      <fos:signatures>
         <fos:proto name="numeric-subtract" return-type="xs:numeric">
            <fos:arg name="arg1" type="xs:numeric"/>
            <fos:arg name="arg2" type="xs:numeric"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="-" types="numeric">Defines the semantics of the "-" operator when
         applied to two numeric values. </fos:opermap>
      <fos:summary>
         <p>Returns the arithmetic difference of its operands: (<code>$arg1 - $arg2</code>).</p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="op.numeric"/>.</p>
      </fos:rules>
      <fos:notes>
         <p> For <code>xs:float</code> or <code>xs:double</code> values, if one of the operands is a
            zero or a finite number and the other is <code>INF</code> or <code>-INF</code>, an
            infinity of the appropriate sign is returned. If both operands are <code>INF</code> or
               <code>-INF</code>, <code>NaN</code> is returned. If one of the operands is
               <code>INF</code> and the other is <code>-INF</code>, an infinity of the appropriate
            sign is returned.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="numeric-multiply" prefix="op">
      <fos:signatures>
         <fos:proto name="numeric-multiply" return-type="xs:numeric">
            <fos:arg name="arg1" type="xs:numeric"/>
            <fos:arg name="arg2" type="xs:numeric"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="*" types="numeric">Defines the semantics of the "*" operator when
         applied to two numeric values.</fos:opermap>
      <fos:summary>
         <p>Returns the arithmetic product of its operands: (<code>$arg1 * $arg2</code>).</p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="op.numeric"/>.</p>
      </fos:rules>
      <fos:notes>
         <p> For <code>xs:float</code> or <code>xs:double</code> values, if one of the operands is a
            zero and the other is an infinity, <code>NaN</code> is returned. If one of the operands
            is a non-zero number and the other is an infinity, an infinity with the appropriate sign
            is returned.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="numeric-divide" prefix="op">
      <fos:signatures>
         <fos:proto name="numeric-divide" return-type="xs:numeric">
            <fos:arg name="arg1" type="xs:numeric"/>
            <fos:arg name="arg2" type="xs:numeric"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="div" types="numeric">Defines the semantics of the "div" operator when
         applied to two numeric values.</fos:opermap>
      <fos:summary>
         <p>Returns the arithmetic quotient of its operands: (<code>$arg1 div $arg2</code>).</p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="op.numeric"/>.</p>
         <p>As a special case, if the types of both <code>$arg1</code> and <code>$arg2</code> are
               <code>xs:integer</code>, then the return type is <code>xs:decimal</code>.</p>

      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="AR" code="0001"/> for <code>xs:decimal</code>
            and <code>xs:integer</code> operands, if the divisor is (positive or negative) zero.</p>
      </fos:errors>
      <fos:notes>
         <p>For <code>xs:float</code> and <code>xs:double</code> operands, floating point division
            is performed as specified in <bibref ref="ieee754-2008"/>. A positive number divided by
            positive zero returns <code>INF</code>. A negative number divided by positive zero
            returns <code>-INF</code>. Division by negative zero returns <code>-INF</code> and
               <code>INF</code>, respectively. Positive or negative zero divided by positive or
            negative zero returns <code>NaN</code>. Also, <code>INF</code> or <code>-INF</code>
            divided by <code>INF</code> or <code>-INF</code> returns <code>NaN</code>.</p>
      </fos:notes>

   </fos:function>
   <fos:function name="numeric-integer-divide" prefix="op">
      <fos:signatures>
         <fos:proto name="numeric-integer-divide" return-type="xs:integer">
            <fos:arg name="arg1" type="xs:numeric"/>
            <fos:arg name="arg2" type="xs:numeric"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="idiv" types="numeric">Defines the semantics of the "idiv" operator when
         applied to two numeric values.</fos:opermap>
      <fos:summary>
         <p>Performs an integer division.</p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="op.numeric"/>.</p>

         <p>If <code>$arg2</code> is <code>INF</code> or <code>-INF</code>, and <code>$arg1</code>
            is not <code>INF</code> or <code>-INF</code>, then the result is zero.</p>

         <p>Otherwise, subject to limits of precision and overflow/underflow conditions, the result
            is the largest (furthest from zero) <code>xs:integer</code> value <code>$N</code> such
            that the following expression is true:</p>
         
         <eg>fn:abs($N * $arg2) le fn:abs($arg1) 
               and fn:compare($N * $arg2, 0) eq fn:compare($arg1, 0).</eg>
         <note>
            <p>The second term in this condition ensures that the result has the correct sign.</p>
         </note>
         <p>The implementation may adopt a different algorithm provided that it is equivalent to
            this formulation in all cases where <termref def="implementation-dependent"
               >implementation-dependent</termref> or <termref def="implementation-defined"
               >implementation-defined</termref> behavior does not affect the outcome, for example,
            the implementation-defined precision of the result of <code>xs:decimal</code>
            division.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="AR" code="0001"/> if the divisor is (positive
            or negative) zero.</p>
         <p>A dynamic error is raised <errorref class="AR" code="0002"/> if either operand is
               <code>NaN</code> or if <code>$arg1</code> is <code>INF</code> or
            <code>-INF</code>.</p>
      </fos:errors>
      <fos:notes>
         <p>Except in situations involving errors, loss of precision, or overflow/underflow, the
            result of <code>$a idiv $b</code> is the same as <code>($a div $b) cast as
               xs:integer</code>.</p>
         <p>The semantics of this function are different from integer division as defined in
            programming languages such as Java and C++.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:numeric-integer-divide(10,3)</fos:expression>
               <fos:result>3</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:numeric-integer-divide(3,-2)</fos:expression>
               <fos:result>-1</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:numeric-integer-divide(-3,2)</fos:expression>
               <fos:result>-1</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:numeric-integer-divide(-3,-2)</fos:expression>
               <fos:result>1</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:numeric-integer-divide(9.0,3)</fos:expression>
               <fos:result>3</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:numeric-integer-divide(-3.5,3)</fos:expression>
               <fos:result>-1</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:numeric-integer-divide(3.0,4)</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:numeric-integer-divide(3.1E1,6)</fos:expression>
               <fos:result>5</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:numeric-integer-divide(3.1E1,7)</fos:expression>
               <fos:result>4</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="numeric-mod" prefix="op">
      <fos:signatures>
         <fos:proto name="numeric-mod" return-type="xs:numeric">
            <fos:arg name="arg1" type="xs:numeric"/>
            <fos:arg name="arg2" type="xs:numeric"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="mod" types="numeric">Defines the semantics of the "mod" operator when
         applied to two numeric values.</fos:opermap>
      <fos:summary>
         <p>Returns the remainder resulting from dividing <code>$arg1</code>, the dividend, by
               <code>$arg2</code>, the divisor. </p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="op.numeric"/>.</p>
         <p>The operation <code>a mod b</code> for operands that are <code>xs:integer</code> or
               <code>xs:decimal</code>, or types derived from them, produces a result such that
               <code>(a idiv b)*b+(a mod b)</code> is equal to <code>a</code> and the magnitude of
            the result is always less than the magnitude of <code>b</code>. This identity holds even
            in the special case that the dividend is the negative integer of largest possible
            magnitude for its type and the divisor is -1 (the remainder is 0). It follows from this
            rule that the sign of the result is the sign of the dividend.</p>

         <p> For <code>xs:float</code> and <code>xs:double</code> operands the following rules
            apply:</p>
         <ulist>
            <item>
               <p>If either operand is <code>NaN</code>, the result is <code>NaN</code>.</p>
            </item>
            <item>
               <p>If the dividend is positive or negative infinity, or the divisor is positive or
                  negative zero (0), or both, the result is <code>NaN</code>.</p>
            </item>
            <item>
               <p>If the dividend is finite and the divisor is an infinity, the result equals the
                  dividend.</p>
            </item>
            <item>
               <p>If the dividend is positive or negative zero and the divisor is finite, the result
                  is the same as the dividend.</p>
            </item>
            <item>
               <p>In the remaining cases, where neither positive or negative infinity, nor positive
                  or negative zero, nor <code>NaN</code> is involved, the result obeys <code>(a idiv
                     b)*b+(a mod b)</code> = <code>a</code>.
                  <!--float or double remainder r from a dividend n and a divisor d is defined by the mathematical relation r = n-(d * q) where q is an integer that is negative only if n/d is negative and positive only if n/d is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of n and d.  -->
                  Division is truncating division, analogous to integer division, not <bibref
                     ref="ieee754-2008"/> rounding division i.e. additional digits are truncated,
                  not rounded to the required precision.</p>
            </item>
         </ulist>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="AR" code="0001"/> for <code>xs:integer</code>
            and <code>xs:decimal</code> operands, if <code>$arg2</code> is zero.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:numeric-mod(10,3)</fos:expression>
               <fos:result>1</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:numeric-mod(6,-2)</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:numeric-mod(4.5,1.2)</fos:expression>
               <fos:result>0.9</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:numeric-mod(1.23E2, 0.6E1)</fos:expression>
               <fos:result>3.0E0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="numeric-unary-plus" prefix="op">
      <fos:signatures>
         <fos:proto name="numeric-unary-plus" return-type="xs:numeric">
            <fos:arg name="arg" type="xs:numeric"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="+" types="numeric">Defines the semantics of the unary "+" operator
         applied to a numeric value.</fos:opermap>
      <fos:summary>
         <p>Returns its operand with the sign unchanged: (<code>+ $arg</code>).</p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="op.numeric"/>.</p>
         <p>The returned value is equal to <code>$arg</code>, and is an instance of
               <code>xs:integer</code>, <code>xs:decimal</code>, <code>xs:double</code>, or
               <code>xs:float</code> depending on the type of <code>$arg</code>.</p>
      </fos:rules>
      <fos:notes>
         <p>Because function conversion rules are applied in the normal way, the unary
               <code>+</code> operator can be used to force conversion of an untyped node to a
            number: the result of <code>+@price</code> is the same as <code>xs:double(@price)</code>
            if the type of <code>@price</code> is <code>xs:untypedAtomic</code>.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="numeric-unary-minus" prefix="op">
      <fos:signatures>
         <fos:proto name="numeric-unary-minus" return-type="xs:numeric">
            <fos:arg name="arg" type="xs:numeric"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="-" types="numeric">Defines the semantics of the unary "-" operator when
         applied to a numeric value.</fos:opermap>
      <fos:summary>
         <p>Returns its operand with the sign reversed: (<code>- $arg</code>).</p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="op.numeric"/>.</p>
         <p>The returned value is an instance of <code>xs:integer</code>, <code>xs:decimal</code>,
               <code>xs:double</code>, or <code>xs:float</code> depending on the type of
               <code>$arg</code>.</p>
         <p>For <code>xs:integer</code> and <code>xs:decimal</code> arguments, <code>0</code> and
               <code>0.0</code> return <code>0</code> and <code>0.0</code>, respectively. For
               <code>xs:float</code> and <code>xs:double</code> arguments, <code>NaN</code> returns
               <code>NaN</code>, <code>0.0E0</code> returns <code>-0.0E0</code> and vice versa.
               <code>INF</code> returns <code>-INF</code>. <code>-INF</code> returns
               <code>INF</code>.</p>
      </fos:rules>
   </fos:function>
   <fos:function name="numeric-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="numeric-equal" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:numeric"/>
            <fos:arg name="arg2" type="xs:numeric"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="eq" types="numeric" other-operators="ne le ge">Defines the semantics of
         the "eq" operator when applied to two numeric values, and is also used in defining the
         semantics of "ne", "le" and "ge".</fos:opermap>
      <fos:summary>
         <p>Returns true if and only if the value of <code>$arg1</code> is equal to the value of
               <code>$arg2</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="op.numeric"/> and <specref ref="comp.numeric"/>.</p>
         <p> For <code>xs:float</code> and <code>xs:double</code> values, positive zero and negative
            zero compare equal. <code>INF</code> equals <code>INF</code>, and <code>-INF</code>
            equals <code>-INF</code>. <code>NaN</code> does not equal itself.</p>
      </fos:rules>
   </fos:function>
   <fos:function name="numeric-less-than" prefix="op">
      <fos:signatures>
         <fos:proto name="numeric-less-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:numeric"/>
            <fos:arg name="arg2" type="xs:numeric"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="lt" types="numeric" other-operators="le">Defines the semantics of the
         "lt" operator when applied to two numeric values, and is also used in defining the
         semantics of "le".</fos:opermap>
      <fos:summary>
         <p>Returns <code>true</code> if and only if <code>$arg1</code> is numerically less than
               <code>$arg2</code>. </p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="op.numeric"/> and <specref ref="comp.numeric"/>.</p>
         <p>For <code>xs:float</code> and <code>xs:double</code> values, positive infinity is
            greater than all other non-<code>NaN</code> values; negative infinity is less than all
            other non-<code>NaN</code> values. If <code>$arg1</code> or <code>$arg2</code> is
               <code>NaN</code>, the function returns <code>false</code>.</p>
      </fos:rules>
   </fos:function>
   <fos:function name="numeric-greater-than" prefix="op">
      <fos:signatures>
         <fos:proto name="numeric-greater-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:numeric"/>
            <fos:arg name="arg2" type="xs:numeric"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="gt" types="numeric" other-operators="ge">Defines the semantics of the
         "gt" operator when applied to two numeric values, and is also used in defining the
         semantics of "ge".</fos:opermap>
      <fos:summary>
         <p>Returns <code>true</code> if and only if <code>$arg1</code> is numerically greater than
               <code>$arg2</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>The function call <code>op:numeric-greater-than($A, $B)</code> is defined to return the
            same result as <code>op:numeric-less-than($B, $A)</code></p>
      </fos:rules>
   </fos:function>
   <fos:function name="abs" prefix="fn">
      <fos:signatures>
         <fos:proto name="abs" return-type="xs:numeric?">
            <fos:arg name="arg" type="xs:numeric?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the absolute value of <code>$arg</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="numeric-value-functions"/>.</p>
         <p>If <code>$arg</code> is negative the function returns <code>-$arg</code>, otherwise it
            returns <code>$arg</code>.</p>
         <p diff="chg" at="B">For the four types <code>xs:float</code>,
               <code>xs:double</code>, <code>xs:decimal</code> and <code>xs:integer</code>, it is
            guaranteed that if the type of <code>$arg</code> is an instance of type <var>T</var> then
            the result will also be an instance of <var>T</var>. The result <rfc2119>may</rfc2119>
            also be an instance of a type derived from one of these four by restriction. For example, if
            <code>$arg</code> is an instance of <code>xs:positiveInteger</code> then the value of
            <code>$arg</code> <rfc2119>may</rfc2119> be returned unchanged.</p>
         <p>For <code>xs:float</code> and <code>xs:double</code> arguments, if the argument is
            positive zero or negative zero, then positive zero is returned. If the argument is
            positive or negative infinity, positive infinity is returned.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:abs(10.5)</fos:expression>
               <fos:result>10.5</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:abs(-10.5)</fos:expression>
               <fos:result>10.5</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="ceiling" prefix="fn">
      <fos:signatures>
         <fos:proto name="ceiling" return-type="xs:numeric?">
            <fos:arg name="arg" type="xs:numeric?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Rounds <code>$arg</code> upwards to a whole number.</p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="numeric-value-functions"/>.</p>
         <p>The function returns the smallest (closest to negative infinity) number with no
            fractional part that is not less than the value of <code>$arg</code>.</p>
         <p diff="chg" at="B">For the four types <code>xs:float</code>,
            <code>xs:double</code>, <code>xs:decimal</code> and <code>xs:integer</code>, it is
            guaranteed that if the type of <code>$arg</code> is an instance of type <var>T</var> then
            the result will also be an instance of <var>T</var>. The result <rfc2119>may</rfc2119>
            also be an instance of a type derived from one of these four by restriction. For example, if
         <code>$arg</code> is an instance of <code>xs:decimal</code> then the result <rfc2119>may</rfc2119>
         be an instance of <code>xs:integer</code>.</p>
         <p>For <code>xs:float</code> and <code>xs:double</code> arguments, if the argument is
            positive zero, then positive zero is returned. If the argument is negative zero, then
            negative zero is returned. If the argument is less than zero and greater than -1,
            negative zero is returned.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:ceiling(10.5)</fos:expression>
               <fos:result>11</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:ceiling(-10.5)</fos:expression>
               <fos:result>-10</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="floor" prefix="fn">
      <fos:signatures>
         <fos:proto name="floor" return-type="xs:numeric?">
            <fos:arg name="arg" type="xs:numeric?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Rounds <code>$arg</code> downwards to a whole number.</p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="numeric-value-functions"/>.</p>
         <p>The function returns the largest (closest to positive infinity) number with no
            fractional part that is not greater than the value of <code>$arg</code>.</p>
         <p diff="chg" at="B">For the four types <code>xs:float</code>,
         <code>xs:double</code>, <code>xs:decimal</code> and <code>xs:integer</code>, it is
         guaranteed that if the type of <code>$arg</code> is an instance of type <var>T</var> then
         the result will also be an instance of <var>T</var>. The result <rfc2119>may</rfc2119>
         also be an instance of a type derived from one of these four by restriction. For example, if
         <code>$arg</code> is an instance of <code>xs:decimal</code> then the result <rfc2119>may</rfc2119>
         be an instance of <code>xs:integer</code>.</p>
         <p>For <code>xs:float</code> and <code>xs:double</code> arguments, if the argument is
            positive zero, then positive zero is returned. If the argument is negative zero, then
            negative zero is returned.</p>

      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:floor(10.5)</fos:expression>
               <fos:result>10</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:floor(-10.5)</fos:expression>
               <fos:result>-11</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="round" prefix="fn">
      <fos:signatures>
         <fos:proto name="round" return-type="xs:numeric?">
            <fos:arg name="arg" type="xs:numeric?"/>
         </fos:proto>
         <fos:proto name="round" return-type="xs:numeric?">
            <fos:arg name="arg" type="xs:numeric?"/>
            <fos:arg name="precision" type="xs:integer"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Rounds a value to a specified number of decimal places, rounding upwards if two such
            values are equally near.</p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="numeric-value-functions"/>.</p>
         <p>The function returns the nearest (that is, numerically closest) value to
               <code>$arg</code> that is a multiple of ten to the power of minus
               <code>$precision</code>. If two such values are equally near (for example, if the
            fractional part in <code>$arg</code> is exactly .5), the function returns the one that
            is closest to positive infinity.</p>
         <p diff="chg" at="B">For the four types <code>xs:float</code>,
            <code>xs:double</code>, <code>xs:decimal</code> and <code>xs:integer</code>, it is
            guaranteed that if the type of <code>$arg</code> is an instance of type <var>T</var> then
            the result will also be an instance of <var>T</var>. The result <rfc2119>may</rfc2119>
            also be an instance of a type derived from one of these four by restriction. For example, if
            <code>$arg</code> is an instance of <code>xs:decimal</code> and <code>$precision</code> is less than one,
            then the result <rfc2119>may</rfc2119>
            be an instance of <code>xs:integer</code>.</p>
         <p>The single-argument version of this function produces the same result as the
            two-argument version with <code>$precision=0</code> (that is, it rounds to a whole
            number).</p>
         <p>When <code>$arg</code> is of type <code>xs:float</code> and <code>xs:double</code>:</p>
         <olist>
            <item>
               <p>If <code>$arg</code> is NaN, positive or negative zero, or positive or negative
                  infinity, then the result is the same as the argument.</p>
            </item>
            <item>
               <p>For other values, the argument is cast to <code>xs:decimal</code> using an
                  implementation of <code>xs:decimal</code> that imposes no limits on the number of
                  digits that can be represented. The function is applied to this
                     <code>xs:decimal</code> value, and the resulting <code>xs:decimal</code> is
                  cast back to <code>xs:float</code> or <code>xs:double</code> as appropriate to
                  form the function result. If the resulting <code>xs:decimal</code> value is zero,
                  then positive or negative zero is returned according to the sign of
                     <code>$arg</code>.</p>
            </item>
         </olist>

      </fos:rules>
      <fos:notes>
         <p>This function is typically used with a non-zero <code>$precision</code> in financial
            applications where the argument is of type <code>xs:decimal</code>. For arguments of
            type <code>xs:float</code> and <code>xs:double</code> the results may be
            counter-intuitive. For example, consider <code>round(35.425e0, 2)</code>. The result is
            not 35.43, as might be expected, but 35.42. This is because the <code>xs:double</code>
            written as 35.425e0 has an exact value equal to 35.42499999999..., which is closer to
            35.42 than to 35.43.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:round(2.5)</fos:expression>
               <fos:result>3.0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:round(2.4999)</fos:expression>
               <fos:result>2.0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:round(-2.5)</fos:expression>
               <fos:result>-2.0</fos:result>
               <fos:postamble>Not the possible alternative, <code>-3</code></fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test xslt-version="3.0">
               <fos:expression>fn:round(1.125, 2)</fos:expression>
               <fos:result>1.13</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test xslt-version="3.0">
               <fos:expression>fn:round(8452, -2)</fos:expression>
               <fos:result>8500</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test xslt-version="3.0">
               <fos:expression>fn:round(3.1415e0, 2)</fos:expression>
               <fos:result>3.14e0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="round-half-to-even" prefix="fn">
      <fos:signatures>
         <fos:proto name="round-half-to-even" return-type="xs:numeric?">
            <fos:arg name="arg" type="xs:numeric?"/>
         </fos:proto>
         <fos:proto name="round-half-to-even" return-type="xs:numeric?">
            <fos:arg name="arg" type="xs:numeric?"/>
            <fos:arg name="precision" type="xs:integer"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Rounds a value to a specified number of decimal places, rounding to make the last digit
            even if two such values are equally near.</p>
      </fos:summary>
      <fos:rules>
         <p>General rules: see <specref ref="numeric-value-functions"/>.</p>
         <p>The function returns the nearest (that is, numerically closest) value to
               <code>$arg</code> that is a multiple of ten to the power of minus
               <code>$precision</code>. If two such values are equally near (e.g. if the fractional
            part in <code>$arg</code> is exactly .500...), the function returns the one whose least
            significant digit is even.</p>
         <p diff="chg" at="B">For the four types <code>xs:float</code>,
            <code>xs:double</code>, <code>xs:decimal</code> and <code>xs:integer</code>, it is
            guaranteed that if the type of <code>$arg</code> is an instance of type <var>T</var> then
            the result will also be an instance of <var>T</var>. The result <rfc2119>may</rfc2119>
            also be an instance of a type derived from one of these four by restriction. For example, if
            <code>$arg</code> is an instance of <code>xs:decimal</code> and <code>$precision</code>
            is less than one, then the result <rfc2119>may</rfc2119>
            be an instance of <code>xs:integer</code>.</p>
         <p> The first signature of this function produces the same result as the second signature
            with <code>$precision=0</code>.</p>
         <p>For arguments of type <code>xs:float</code> and <code>xs:double</code>:</p>
         <olist>
            <item>
               <p>If the argument is <code>NaN</code>, positive or negative zero, or positive or
                  negative infinity, then the result is the same as the argument.</p>
            </item>
            <item>
               <p>In all other cases, the argument is cast to <code>xs:decimal</code> using an
                  implementation of xs:decimal that imposes no limits on the number of digits that
                  can be represented. The function is applied to this <code>xs:decimal</code> value,
                  and the resulting <code>xs:decimal</code> is cast back to <code>xs:float</code> or
                     <code>xs:double</code> as appropriate to form the function result. If the
                  resulting <code>xs:decimal</code> value is zero, then positive or negative zero is
                  returned according to the sign of the original argument.</p>
            </item>
         </olist>

      </fos:rules>
      <fos:notes>
         <p>This function is typically used in financial applications where the argument is of type
               <code>xs:decimal</code>. For arguments of type <code>xs:float</code> and
               <code>xs:double</code> the results may be counter-intuitive. For example, consider
               <code>round-half-to-even(xs:float(150.015), 2)</code>. The result is not 150.02 as
            might be expected, but 150.01. This is because the conversion of the
               <code>xs:float</code> value represented by the literal 150.015 to an
               <code>xs:decimal</code> produces the <code>xs:decimal</code> value 150.014999389...,
            which is closer to 150.01 than to 150.02.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:round-half-to-even(0.5)</fos:expression>
               <fos:result>0.0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:round-half-to-even(1.5)</fos:expression>
               <fos:result>2.0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:round-half-to-even(2.5)</fos:expression>
               <fos:result>2.0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:round-half-to-even(3.567812e+3, 2)</fos:expression>
               <fos:result>3567.81e0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:round-half-to-even(4.7564e-3, 2)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:round-half-to-even(35612.25, -2)</fos:expression>
               <fos:result>35600</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="format-integer" prefix="fn">
      <fos:signatures>
         <fos:proto name="format-integer" return-type="xs:string">
            <fos:arg name="value" type="xs:integer?"/>
            <fos:arg name="picture" type="xs:string"/>
         </fos:proto>
         <fos:proto name="format-integer" return-type="xs:string">
            <fos:arg name="value" type="xs:integer?"/>
            <fos:arg name="picture" type="xs:string"/>
            <fos:arg name="lang" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="default-language">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="3">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Formats an integer according to a given picture string, using the conventions of a given
            natural language if specified.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$value</code> is an empty sequence, the function returns a zero-length
            string.</p>
         <p>In all other cases, the <code>$picture</code> argument describes the format in which
               <code>$value</code> is output.</p>
         <p>The rules that follow describe how non-negative numbers are output. If the value of
               <code>$value</code> is negative, the rules below are applied to the absolute value of
               <code>$value</code>, and a minus sign is prepended to the result.</p>

         <p>The value of <code>$picture</code> consists of a primary format token, optionally
            followed by a format modifier. The primary format token is always present and
               <rfc2119>must not</rfc2119> be zero-length. If the string contains one or more
            semicolons then everything that precedes the last semicolon is taken as the primary
            format token and everything that follows is taken as the format modifier; if the string
            contains no semicolon then the entire picture is taken as the primary format token, and
            the format modifier is taken to be absent (which is equivalent to supplying a
            zero-length string).</p>



         <p>The primary format token is classified as one of the following:</p>
         <olist>
            <item>
               <p>A <var>decimal-digit-pattern</var> made up of <var>optional-digit-signs</var>,
                     <var>mandatory-digit-signs</var>, and <var>grouping-separator-signs</var>.</p>

               <ulist>
                  <item>
                     <p>The <var>optional-digit-sign</var> is the character "#".</p>
                  </item>
                  <item>
                     <p>A <var>mandatory-digit-sign</var> is a <termref def="character"
                           >character</termref> in Unicode category <var>Nd</var>. All
                           <var>mandatory-digit-signs</var> within the format token
                           <rfc2119>must</rfc2119> be from the same digit family, where a digit
                        family is a sequence of ten consecutive characters in Unicode category <var>Nd</var>,
                        having digit values 0 through 9. Within the format token, these digits are
                        interchangeable: a three-digit number may thus be indicated equivalently by
                           <code>000</code>, <code>001</code>, or <code>999</code>.</p>
                  </item>
                  <item>
                     <p>a <var>grouping-separator-sign</var> is a non-alphanumeric character, that
                        is a <termref def="character">character</termref> whose Unicode category is
                        other than <var>Nd</var>, <var>Nl</var>, <var>No</var>, <var>Lu</var>, <var>Ll</var>, 
                        <var>Lt</var>, <var>Lm</var> or <var>Lo</var>.</p>
                  </item>
               </ulist>

               <p>If the primary format token contains at least one Unicode digit then it is taken
                  as a decimal digit pattern, and in this case it <rfc2119>must</rfc2119> match the
                  regular expression <code>^((\p{Nd}|#|[^\p{N}\p{L}])+?)$</code>. If it contains a
                  digit but does not match this pattern, a dynamic error is raised <errorref
                     class="DF" code="1310"/>.</p>

               <note>
                  <p>If a semicolon is to be used as a grouping separator, then the primary format
                     token as a whole must be followed by another semicolon, to ensure that the
                     grouping separator is not mistaken as a separator between the primary format
                     token and the format modifier.</p>
               </note>


               <p>There <rfc2119>must</rfc2119> be at least one <var>mandatory-digit-sign</var>.
                  There may be zero or more <var>optional-digit-signs</var>, and (if present) these
                     <rfc2119>must</rfc2119> precede all <var>mandatory-digit-signs</var>. There may
                  be zero or more <var>grouping-separator-signs</var>. A
                     <var>grouping-separator-sign</var>
                  <rfc2119>must not</rfc2119> appear at the start or end of the
                     <var>decimal-digit-pattern</var>, nor adjacent to another
                     <var>grouping-separator-sign</var>.</p>

               <p>The corresponding output format is a decimal number, using this digit family, with
                  at least as many digits as there are <var>mandatory-digit-signs</var> in the
                  format token. Thus, a format token <code>1</code> generates the sequence <code>0 1
                     2 ... 10 11 12 ...</code>, and a format token <code>01</code> (or equivalently,
                     <code>00</code> or <code>99</code>) generates the sequence <code>00 01 02 ...
                     09 10 11 12 ... 99 100 101</code>. A format token of <code>&amp;#x661;</code>
                  (Arabic-Indic digit one) generates the sequence <code>١</code> then <code>٢</code>
                  then <code>٣</code> ...</p>

               <p diff="chg" at="E">The <var>grouping-separator-signs</var> are handled as follows:</p>
                  
                  <olist>
                     <item><p>The position of
                        grouping separators within the format token, counting backwards from the last
                        digit, indicates the position of grouping separators to appear within the
                        formatted number, and the character used as the <var>grouping-separator-sign</var>
                        within the format token indicates the character to be used as the corresponding
                        grouping separator in the formatted number.
                     </p></item>
                     <item><p>More specifically, the <term>position</term> of a grouping separator is
                        the number of <var>optional-digit-signs</var> and <var>mandatory-digit-signs</var> appearing
                        between the grouping separator and the right-hand end of the primary format token.</p></item>
                     <item><p>Grouping separators are defined to be <term>regular</term> if the following conditions apply:</p>
                        <olist>
                           <item><p>There is at least one grouping separator.</p></item>
                           <item><p>Every grouping separator is the same character (call it <var>C</var>).</p></item>
                           <item><p>There is a positive integer <var>G</var> (the grouping size) such that:</p>
                           <olist>
                              <item><p>The position of every grouping separator is an integer multiple of <var>G</var>, and</p></item>
                              <item><p>Every positive integer multiple of <var>G</var> that is less than the number of 
                              <var>optional-digit-signs</var> and <var>mandatory-digit-signs</var> in the primary format token
                              is the position of a grouping separator.</p></item>                           
                           </olist></item>
                        </olist>
                     </item>
                     <item><p>The <term>grouping separator template</term> is a (possibly infinite) set of (position, character) pairs.</p></item>
                     <item><p>If grouping separators are regular, then the grouping separator template contains one pair of the form <code>(n×G, C)</code>
                     for every positive integer <var>n</var> where <var>G</var> is the grouping size and <var>C</var> is the grouping character.</p></item>
                     <item><p>Otherwise (when grouping separators are not regular), the grouping separator template contains one pair of the form
                     <code>(P, C)</code> for every grouping separator found in the primary formatting token, where <var>C</var> is the grouping
                     separator character and <var>P</var> is its position.</p></item>
                     <item><note><p>If there are no grouping separators, then the grouping separator template is an empty set.</p></note></item>
                  </olist>
              
               
              <p>The number is formatted as follows:</p>
               
               <olist>
                  <item><p>Let <var>S/1</var> be the result of formatting the supplied number in decimal notation as if by casting
                  it to <code>xs:string</code>.</p></item>
                  <item><p>Let <var>S/2</var> be the result of padding <var>S/1</var> on the left with as many leading zeroes
                  as are needed to ensure that it contains at least as many digits as the number of <var>mandatory-digit-signs</var>
                  in the primary format token.</p></item>
                  <item><p>Let <var>S/3</var> be the result of replacing all decimal digits (0-9) in <var>S/2</var> with the corresponding
                     digits from the selected digit family.</p></item>
                  <item><p>Let <var>S/4</var> be the result of inserting grouping separators into <var>S/3</var>: for every (position 
                     <var>P</var>, character <var>C</var>) pair in the grouping separator template where <var>P</var> is less than the number
                  of digits in <var>S/3</var>, insert character <var>C</var> into <var>S/3</var> at position <var>P</var>, counting from 
                  the right-hand end.</p></item>
                  <item><p>Let <var>S/5</var> be the result of converting <var>S/4</var> into ordinal form, if an ordinal modifier
                  is present, as described below.</p></item>
                  <item><p>The result of the function is then <var>S/5</var>.</p></item>
               </olist>
                  
 
            </item>




            <item>
               <p>The format token <code>A</code>, which generates the sequence <code>A B C ... Z AA
                     AB AC...</code>.</p>
            </item>
            <item>
               <p>The format token <code>a</code>, which generates the sequence <code>a b c ... z aa
                     ab ac...</code>.</p>
            </item>
            <item>
               <p>The format token <code>i</code>, which generates the sequence <code>i ii iii iv v
                     vi vii viii ix x ...</code>.</p>
            </item>
            <item>
               <p>The format token <code>I</code>, which generates the sequence <code>I II III IV V
                     VI VII VIII IX X ...</code>.</p>
            </item>
            <item>
               <p>The format token <code>w</code>, which generates numbers written as lower-case
                  words, for example in English, <code>one two three four ...</code>
               </p>
            </item>
            <item>
               <p>The format token <code>W</code>, which generates numbers written as upper-case
                  words, for example in English, <code>ONE TWO THREE FOUR ...</code>
               </p>
            </item>
            <item>
               <p>The format token <code>Ww</code>, which generates numbers written as title-case
                  words, for example in English, <code>One Two Three Four ...</code>
               </p>
            </item>
            <item>
               <p>Any other format token, which indicates a numbering sequence in which that token
                  represents the number 1 (one) (but see the note below).
                  <!-- Where possible (given the constraint that format tokens
						must be alphanumeric, and that they must be distinct) the format token
						used to represent a numbering sequence should be the same as the representation
						of the number 1 (one) in that sequence.-->
                  It is <termref def="implementation-defined">implementation-defined</termref> which
                  numbering sequences, additional to those listed above, are supported. If an
                  implementation does not support a numbering sequence represented by the given
                  token, it <rfc2119>must</rfc2119> use a format token of <code>1</code>.</p>
               <note>
                  <p>In some traditional numbering sequences additional signs are added to denote
                     that the letters should be interpreted as numbers; these are not included in
                     the format token. An example (see also the example below) is classical Greek
                     where a <emph>dexia keraia</emph> <phrase role="normalize-nfc">(x0374, &#x0374;)</phrase> and sometimes an
                     <emph>aristeri keraia</emph> <phrase role="normalize-nfc">(x0375, &#x0375;)</phrase> is added.</p>
               </note>
            </item>
         </olist>
         <p>For all format tokens other than a <var>decimal-digit-pattern</var>, there 
            <rfc2119>may</rfc2119> be <termref def="implementation-defined"
               >implementation-defined</termref> lower and upper bounds on the range of numbers that
            can be formatted using this format token; indeed, for some numbering sequences there may
            be intrinsic limits. For example, the format token <code>&amp;#x2460;</code> (circled
            digit one, ①) has a range imposed by the Unicode character repertoire &#x2014; <phrase diff="chg" at="D">zero to 20</phrase>
            in Unicode versions prior to <phrase diff="chg" at="D">3.2</phrase>, or <phrase diff="chg" at="D">zero to 50</phrase> in subsequent versions. For the numbering
            sequences described above any upper bound imposed by the implementation <rfc2119>must
               not</rfc2119> be less than 1000 (one thousand) and any lower bound must not be
            greater than 1. Numbers that fall outside this range <rfc2119>must</rfc2119> be
            formatted using the format token <code>1</code>.</p>
         <p>The above expansions of numbering sequences for format tokens such as <code>a</code> and
               <code>i</code> are indicative but not prescriptive. There are various conventions in
            use for how alphabetic sequences continue when the alphabet is exhausted, and differing
            conventions for how roman numerals are written (for example, <code>IV</code> versus
               <code>IIII</code> as the representation of the number 4). Sometimes alphabetic
            sequences are used that omit letters such as <code>i</code> and <code>o</code>. This
            specification does not prescribe the detail of any sequence other than those sequences
            consisting entirely of decimal digits.</p>
         <p>Many numbering sequences are language-sensitive. This applies especially to the sequence
            selected by the tokens <code>w</code>, <code>W</code> and <code>Ww</code>. It also
            applies to other sequences, for example different languages using the Cyrillic alphabet
            use different sequences of characters, each starting with the letter #x410 (Cyrillic
            capital letter A). In such cases, the <code>$lang</code> argument specifies which
            language's conventions are to be used. If the argument is specified, the value
               <rfc2119>should</rfc2119> be either an empty sequence or a value that would be valid
            for the <code>xml:lang</code> attribute (see <bibref ref="xml"/>). Note that this
            permits the identification of sublanguages based on country codes (from ISO 3166-1) as
            well as identification of dialects and regions within a country.</p>
         <p>The set of languages for which numbering is supported is <termref
            def="implementation-defined">implementation-defined</termref>. If the <code>$lang</code> argument is absent, or is
            set to an empty sequence, or is invalid, or is not a language supported by the
            implementation, then the number is formatted using the default language from the dynamic
            context. </p>
         <p>The format modifier <rfc2119>must</rfc2119> be a string that matches the regular
            expression <code>^([co](\(.+\))?)?[at]?$</code>. That is, if it is present it must
            consist of one or more of the following, in order:</p>
         <ulist>
            <item>
               <p>either <code>c</code> or <code>o</code>, optionally followed by a sequence of
                  characters enclosed between parentheses, to indicate cardinal or ordinal numbering
                  respectively, the default being cardinal numbering</p>
            </item>
            <item>
               <p>either <code>a</code> or <code>t</code>, to indicate alphabetic or traditional
                  numbering respectively, the default being <termref def="implementation-defined"
                     >implementation-defined</termref>.</p>
            </item>
         </ulist>
         <p>If the <code>o</code> modifier is present, this indicates a request to output ordinal
            numbers rather than cardinal numbers. For example, in English, when used with the format
            token <code>1</code>, this outputs the sequence <code>1st 2nd 3rd 4th ...</code>, and
            when used with the format token <code>w</code> outputs the sequence <code>first second
               third fourth ...</code>.</p>
         <p>The string of characters between the parentheses, if present, is used to select between
            other possible variations of cardinal or ordinal numbering sequences. The interpretation
            of this string is <termref def="implemementation-defined"
               >implementation-defined</termref>. No error occurs if the implementation does not
            define any interpretation for the defined string.</p>

         
         <p>It is <termref def="implementation-defined">implementation-defined</termref> what
            combinations of values of the format token, the language, and the cardinal/ordinal
            modifier are supported. If ordinal numbering is not supported for the combination of the
            format token, the language, and the string appearing in parentheses, the request is
            ignored and cardinal numbers are generated instead.</p>
         
         <p>The use of the <code>a</code> or <code>t</code> modifier disambiguates between numbering
            sequences that use letters. In many languages there are two commonly used numbering
            sequences that use letters. One numbering sequence assigns numeric values to letters in
            alphabetic sequence, and the other assigns numeric values to each letter in some other
            manner traditional in that language. In English, these would correspond to the numbering
            sequences specified by the format tokens <code>a</code> and <code>i</code>. In some
            languages, the first member of each sequence is the same, and so the format token alone
            would be ambiguous. In the absence of the <code>a</code> or <code>t</code> modifier, the
            default is <termref def="implementation-defined">implementation-defined</termref>.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="DF" code="1310"/> if the format token is
            invalid, that is, if it violates any mandatory rules (indicated by an emphasized
               <rfc2119>must</rfc2119> or <rfc2119>required</rfc2119> keyword in the above rules).
            For example, the error is raised if the primary format token contains a digit but does
            not match the required regular expression.</p>
      </fos:errors>
      <fos:notes>
         <olist>
            <item><p>Note the careful distinction between conditions that are errors and conditions where
               fallback occurs. The principle is that an error in the syntax of the format picture will
               be reported by all processors, while a construct that is recognized by some
               implementations but not others will never result in an error, but will instead cause a
               fallback representation of the integer to be used.</p></item>
            <item><p>The following notes apply when a <var>decimal-digit-pattern</var> is used:</p>
               <olist>
                  <item><p>If <var>grouping-separator-signs</var>
                     appear at regular intervals within the format token, then the sequence is extrapolated to
                     the left, so grouping separators will be used in the formatted number at every
                     multiple of <var>N</var>. For example, if the format token is <code>0'000</code>
                     then the number one million will be formatted as <code>1'000'000</code>, while the
                     number fifteen will be formatted as <code>0'015</code>.</p></item>
                  <item><p>The only purpose of <var>optional-digit-signs</var> is to mark the position of
                     <var>grouping-separator-signs</var>. For example, if the format token is
                     <code>#'##0</code> then the number one million will be formatted as
                     <code>1'000'000</code>, while the number fifteen will be formatted as
                     <code>15</code>. A grouping separator is included in the formatted number only
                     if there is a digit to its left, which will only be the case if either (a) the
                     number is large enough to require that digit, or (b) the number of
                     <var>mandatory-digit-signs</var> in the format token requires insignificant
                     leading zeros to be present.</p></item>
                  <item><p>Grouping separators are <emph>not</emph> designed for effects such as
                     formatting a US telephone number as <code>(365)123-9876</code>. In general they are not 
                     suitable for such purposes because (a) only single characters are allowed, and (b) they
                     cannot appear at the beginning or end of the number.</p></item>
                  <item><p>Numbers will never be truncated. Given the <var>decimal-digit-pattern</var>
                     <code>01</code>, the number three hundred will be output as <code>300</code>,
                     despite the absence of any <var>optional-digit-sign</var>.</p></item>
                  
               </olist>
            </item>
            <item><p>The following notes apply when ordinal numbering is selected using the <code>o</code> modifier.</p>
               <p>In some languages, the form of numbers (especially ordinal numbers) varies depending 
                  on the grammatical context: they may have different genders and may decline with the 
                  noun that they qualify. In such cases the string appearing in parentheses after the 
                  letter <code>c</code> or <code>o</code> may be used to indicate the variation of the 
                  cardinal or ordinal number required.</p> 
                  
                  <p>The way in which the variation is indicated will depend on the conventions of the language.</p> 
                  
                  <p>For inflected languages that vary the ending of the word, the approach recommended 
                     in the previous version of this specification was to indicate the required ending, 
                     preceded by a hyphen: for example in German, appropriate values might be 
                     <code>o(-e)</code>, <code>o(-er)</code>, <code>o(-es)</code>, <code>o(-en)</code>. 
                  </p>
                  <p>Another approach, which might usefully be adopted by an implementation based on the 
                     open-source ICU localization library <bibref ref="ICU"/>, or any other library making use of the 
                     Unicode Common Locale Data Repository <bibref ref="CLDR"/>, is to allow the value in parentheses 
                     to be the name of a registered numbering rule set for the language in question, 
                     conventionally prefixed with a percent sign: for example, 
                     <code>o(%spellout-ordinal-masculine)</code>, or <code>c(%spellout-cardinal-year)</code>.
                  </p>
            
            </item>
         </olist>
  
         
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test xslt-version="3.0">
               <fos:expression>format-integer(123, '0000')</fos:expression>
               <fos:result>"0123"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p><code>format-integer(123, 'w')</code> might return <code>"one hundred and
                  twenty-three"</code></p>
         </fos:example>
         <fos:example>
            <p>Ordinal numbering in Italian: The specification <code>"1;o(-º)"</code> with <code>$lang</code> equal to
                  <code>it</code>, if supported, should produce the sequence:</p>
               <eg xml:space="preserve">1º 2º 3º 4º ...</eg>
               <p>The specification <code>"Ww;o"</code> with <code>$lang</code> equal to
                  <code>it</code>, if supported, should produce the sequence:</p>
               <eg xml:space="preserve">Primo Secondo Terzo Quarto Quinto ...</eg>
         </fos:example>
         <fos:example>
            <fos:test xslt-version="3.0">
               <fos:expression>format-integer(21, '1;o', 'en')</fos:expression>
               <fos:result>"21st"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p><code>format-integer(14, 'Ww;o(-e)', 'de')</code> might return
                  <code>"Vierzehnte"</code></p>
         </fos:example>
         <fos:example>
            <fos:test xslt-version="3.0">
               <fos:expression>format-integer(7, 'a')</fos:expression>
               <fos:result>"g"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test xslt-version="3.0">
               <fos:expression>format-integer(57, 'I')</fos:expression>
               <fos:result>"LVII"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test xslt-version="3.0">
               <fos:expression>format-integer(1234, '#;##0;')</fos:expression>
               <fos:result>"1;234"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="format-number" prefix="fn">
      <fos:signatures>
         <fos:proto name="format-number" return-type="xs:string">
            <fos:arg name="value" type="xs:numeric?"/>
            <fos:arg name="picture" type="xs:string"/>
         </fos:proto>
         <fos:proto name="format-number" return-type="xs:string">
            <fos:arg name="value" type="xs:numeric?"/>
            <fos:arg name="picture" type="xs:string"/>
            <fos:arg name="decimal-format-name" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="3">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="decimal-formats namespaces">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a string containing a number formatted according to a given picture string,
            taking account of decimal formats specified in the static context.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the two-argument form of the function is equivalent to calling the
            three-argument form with an empty sequence as the value of the third argument.</p>
         <p>The function formats <code>$value</code> as a string using the <termref
               def="dt-picture-string">picture string</termref> specified by the
               <code>$picture</code> argument and the decimal-format named by the
               <code>$decimal-format-name</code> argument, or the unnamed decimal-format, if there
            is no <code>$decimal-format-name</code> argument. The syntax of the picture string is
            described in <specref ref="syntax-of-picture-string"/>.</p>
         <p>The <code>$value</code> argument may be of any numeric data type
            (<code>xs:double</code>, <code>xs:float</code>, <code>xs:decimal</code>, or their
            subtypes including <code>xs:integer</code>). Note that if an <code>xs:decimal</code> is
            supplied, it is not automatically promoted to an <code>xs:double</code>, as such
            promotion can involve a loss of precision.</p>
         <p>If the supplied value of the <code>$value</code> argument is an empty sequence, the
            function behaves as if the supplied value were the <code>xs:double</code> value
               <code>NaN</code>.</p>
         <p>The value of <code>$decimal-format-name</code>, if present and non-empty,
               <rfc2119>must</rfc2119> be a string which after removal of leading and trailing
            whitespace is in the form of an <code>EQName</code> as defined in the XPath 3.0
            grammar, that is one of the following:</p>

         <ulist>
            <item>
               <p>A lexical QName, which is expanded using the statically known namespaces. The
                  default namespace is not used (no prefix means no namespace).</p>
            </item>
            <item>
               <p>A <code>URIQualifiedName</code> using the syntax <code>Q{uri}local</code>, where
                  the URI can be zero-length to indicate a name in no namespace.</p>
            </item>
         </ulist>


         <p>The decimal format that is used is the decimal format in the static context whose name
            matches <code>$decimal-format-name</code> if supplied, or the unnamed decimal format in
            the static context otherwise.</p>

         <p>The evaluation of the <code>fn:format-number</code> function takes place in two
            phases, an analysis phase described in <specref ref="analyzing-picture-string"/> and a
            formatting phase described in <specref ref="formatting-the-number"/>.</p>

         <p>The analysis phase takes as its inputs the <termref def="dt-picture-string">picture
               string</termref> and the variables derived from the relevant decimal format in the
            static context, and produces as its output a number of variables with defined values.
            The formatting phase takes as its inputs the number to be formatted and the variables
            produced by the analysis phase, and produces as its output a string containing a
            formatted representation of the number.</p>

         <p>The result of the function is the formatted string representation of the supplied
            number.</p>

      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="DF" code="1280"/> if the name specified as
            the <code>$decimal-format-name</code> argument is neither a valid lexical QName nor a
            valid <code>URIQualifiedName</code>, or if it uses a prefix that is not found in the
            statically known namespaces, or if the static context does not contain a declaration of
            a decimal-format with a matching expanded QName. If the processor is able to detect the
            error statically (for example, when the argument is supplied as a string literal), then
            the processor <rfc2119>may</rfc2119> optionally signal this as a static error.</p>
      </fos:errors>
      <fos:notes>
         <p diff="chg" at="D">A string is an ordered sequence of characters, and this specification 
            uses terms such as "left" and "right", "preceding" and "following" in relation to this ordering, 
            irrespective of the position of the characters when visually rendered on some output medium. 
            Both in the picture string and in the result string, digits with higher significance (that is, 
            representing higher powers of ten) always precede digits with lower significance, even when 
            the rendered text flow is from right to left.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p>The following examples assume a default decimal format in which the chosen digits are
               the ASCII digits 0-9, the decimal separator is ".", the grouping separator is ",",
               the minus-sign is "-", and the percent-sign is "%".</p>
            <fos:test>
               <fos:expression>format-number(12345.6, '#,###.00')</fos:expression>
               <fos:result>"12,345.60"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>format-number(12345678.9, '9,999.99')</fos:expression>
               <fos:result>"12,345,678.90"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>format-number(123.9, '9999')</fos:expression>
               <fos:result>"0124"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>format-number(0.14, '01%')</fos:expression>
               <fos:result>"14%"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>format-number(-6, '000')</fos:expression>
               <fos:result>"-006"</fos:result>
            </fos:test>
            <p>The following example assumes the existence of a decimal format named 'ch' in which
               the grouping separator is <code>&#x2b9;</code> and the decimal separator is
                  <code>&#xb7;</code>:</p>
            <fos:test>
               <fos:expression>format-number(1234.5678, '#&#x2b9;##0&#xb7;00',
                  'ch')</fos:expression>
               <fos:result>"1&#x2b9;234&#xb7;57"</fos:result>
            </fos:test>
            <p diff="add" at="A">The following examples assume that the exponent separator is
               in decimal format 'fortran' is 'E':</p>
            <fos:test>
               <fos:expression>format-number(1234.5678, '00.000E0', 'fortran')</fos:expression>
               <fos:result>"12.346E2"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>format-number(0.234, '0.0E0', 'fortran')</fos:expression>
               <fos:result>"2.3E-1"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>format-number(0.234, '#.00E0', 'fortran')</fos:expression>
               <fos:result>"0.23E0"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>format-number(0.234, '.00E0', 'fortran')</fos:expression>
               <fos:result>".23E0"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="pi" prefix="math">
      <fos:signatures>
         <fos:proto name="pi" return-type="xs:double"/>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns an approximation to the mathematical constant <var>π</var>.</p>
      </fos:summary>
      <fos:rules>
         <p>This function returns the <code>xs:double</code> value whose lexical representation is
            3.141592653589793e0</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test xslt-version="3.0">
               <fos:expression>2*math:pi()</fos:expression>
               <fos:result>6.283185307179586e0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>The expression <code>60 * (math:pi() div 180)</code> converts an angle of 60 degrees
               to radians. </p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="exp" prefix="math">
      <fos:signatures>
         <fos:proto name="exp" return-type="xs:double?">
            <fos:arg name="arg" type="xs:double?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the value of <var>e</var><sup><var>x</var></sup>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise the result is the mathematical constant <var>e</var> raised to the power of
               <code>$arg</code>, as defined in the <bibref ref="ieee754-2008"/> specification of
            the <code>exp</code> function applied to 64-bit binary floating point values.</p>
      </fos:rules>
      <fos:notes>
         <p>The treatment of overflow and underflow is defined in <specref ref="op.numeric"/>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>math:exp(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp(0)</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp(1)</fos:expression>
               <fos:result approx="true">2.7182818284590455e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp(2)</fos:expression>
               <fos:result>7.38905609893065e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp(-1)</fos:expression>
               <fos:result>0.36787944117144233e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp(math:pi())</fos:expression>
               <fos:result>23.140692632779267e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp(xs:double('NaN'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp(xs:double('INF'))</fos:expression>
               <fos:result>xs:double('INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp(xs:double('-INF'))</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="exp10" prefix="math">
      <fos:signatures>
         <fos:proto name="exp10" return-type="xs:double?">
            <fos:arg name="arg" type="xs:double?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the value of <code>10</code><sup><var>x</var></sup>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise the result is ten raised to the power of <code>$arg</code>, as defined in the
               <bibref ref="ieee754-2008"/> specification of the <code>exp10</code> function applied
            to 64-bit binary floating point values.</p>
      </fos:rules>
      <fos:notes>
         <p>The treatment of overflow and underflow is defined in <specref ref="op.numeric"/>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>math:exp10(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp10(0)</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp10(1)</fos:expression>
               <fos:result>1.0e1</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp10(0.5)</fos:expression>
               <fos:result>3.1622776601683795e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp10(-1)</fos:expression>
               <fos:result>1.0e-1</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp10(xs:double('NaN'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp10(xs:double('INF'))</fos:expression>
               <fos:result>xs:double('INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:exp10(xs:double('-INF'))</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="log" prefix="math">
      <fos:signatures>
         <fos:proto name="log" return-type="xs:double?">
            <fos:arg name="arg" type="xs:double?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the natural logarithm of the argument.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise the result is the natural logarithm of <code>$arg</code>, as defined in the
               <bibref ref="ieee754-2008"/> specification of the <code>log</code> function applied
            to 64-bit binary floating point values.</p>
      </fos:rules>
      <fos:notes>
         <p>The treatment of <code>divideByZero</code> and <code>invalidOperation</code> exceptions
            is defined in <specref ref="op.numeric"/>. <phrase diff="chg" at="D">The effect is that if the argument is 
            zero, the result is <code>-INF</code>, and if it is negative, the result is <code>NaN</code></phrase>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>math:log(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log(0)</fos:expression>
               <fos:result>xs:double('-INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log(math:exp(1))</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log(1.0e-3)</fos:expression>
               <fos:result>-6.907755278982137e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log(2)</fos:expression>
               <fos:result>0.6931471805599453e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log(-1)</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log(xs:double('NaN'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log(xs:double('INF'))</fos:expression>
               <fos:result>xs:double('INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log(xs:double('-INF'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="log10" prefix="math">
      <fos:signatures>
         <fos:proto name="log10" return-type="xs:double?">
            <fos:arg name="arg" type="xs:double?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the base-ten logarithm of the argument.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise the result is the base-10 logarithm of <code>$arg</code>, as defined in the
               <bibref ref="ieee754-2008"/> specification of the <code>log10</code> function applied
            to 64-bit binary floating point values.</p>
      </fos:rules>
      <fos:notes>
         <p>The treatment of <code>divideByZero</code> and <code>invalidOperation</code> exceptions
            is defined in <specref ref="op.numeric"/>. <phrase diff="chg" at="D">The effect is that if the argument is 
               zero, the result is <code>-INF</code>, and if it is negative, the result is <code>NaN</code></phrase>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>math:log10(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log10(0)</fos:expression>
               <fos:result>xs:double('-INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log10(1.0e3)</fos:expression>
               <fos:result>3.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log10(1.0e-3)</fos:expression>
               <fos:result>-3.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log10(2)</fos:expression>
               <fos:result>0.3010299956639812e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log10(-1)</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log10(xs:double('NaN'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log10(xs:double('INF'))</fos:expression>
               <fos:result>xs:double('INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:log10(xs:double('-INF'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="sqrt" prefix="math">
      <fos:signatures>
         <fos:proto name="sqrt" return-type="xs:double?">
            <fos:arg name="arg" type="xs:double?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the non-negative square root of the argument.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise the result is the mathematical non-negative square root of <code>$arg</code>
            as defined in the <bibref ref="ieee754-2008"/> specification of the
               <code>squareRoot</code> function applied to 64-bit binary floating point values.</p>
      </fos:rules>
      <fos:notes>

         <p>The treatment of the <code>invalidOperation</code> exception is defined in <specref
               ref="op.numeric"/>. The effect is that if the argument is less than zero, the result
            is <code>NaN</code>.</p>

         <p>If <code>$arg</code> is positive or negative zero, positive infinity, or
               <code>NaN</code>, then the result is <code>$arg</code>. (Negative zero is the only
            case where the result can have negative sign)</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>math:sqrt(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sqrt(0.0e0)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sqrt(-0.0e0)</fos:expression>
               <fos:result>-0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sqrt(1.0e6)</fos:expression>
               <fos:result>1.0e3</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sqrt(2.0e0)</fos:expression>
               <fos:result>1.4142135623730951e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sqrt(-2.0e0)</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sqrt(xs:double('NaN'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sqrt(xs:double('INF'))</fos:expression>
               <fos:result>xs:double('INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sqrt(xs:double('-INF'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="pow" prefix="math">
      <fos:signatures>
         <fos:proto name="pow" return-type="xs:double?">
            <fos:arg name="x" type="xs:double?"/>
            <fos:arg name="y" type="xs:numeric"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the result of raising the first argument to the power of the second.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$x</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>If <code>$y</code> is an instance of <code>xs:integer</code>, the result is
               <code>$x</code> raised to the power of <code>$y</code> as defined in the <bibref
               ref="ieee754-2008"/> specification of the <code>pown</code> function applied to a
            64-bit binary floating point value and an integer.</p>
         <p>Otherwise <code>$y</code> is converted to an <code>xs:double</code> by numeric
            promotion, and the result is the value of <code>$x</code> raised to the power of
               <code>$y</code> as defined in the <bibref ref="ieee754-2008"/> specification of the
               <code>pow</code> function applied to two 64-bit binary floating point values.</p>
      </fos:rules>
      <fos:notes>

         <p>The treatment of the <code>divideByZero</code> and <code>invalidOperation</code>
            exceptions is defined in <specref ref="op.numeric"/>. Some of the consequences are
            illustrated in the examples below.</p>

      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>math:pow((), 93.7)</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(2, 3)</fos:expression>
               <fos:result>8.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(-2, 3)</fos:expression>
               <fos:result>-8.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(2, -3)</fos:expression>
               <fos:result>0.125e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(-2, -3)</fos:expression>
               <fos:result>-0.125e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(2, 0)</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(0, 0)</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(xs:double('INF'), 0)</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(xs:double('NaN'), 0)</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(-math:pi(), 0)</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(0e0, 3)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(0e0, 4)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(-0e0, 3)</fos:expression>
               <fos:result>-0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(0, 4)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(0e0, -3)</fos:expression>
               <fos:result>xs:double('INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(0e0, -4)</fos:expression>
               <fos:result>xs:double('INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(-0e0, -3)</fos:expression>
               <fos:result>xs:double('-INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(0, -4)</fos:expression>
               <fos:result>xs:double('INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(16, 0.5e0)</fos:expression>
               <fos:result>4.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(16, 0.25e0)</fos:expression>
               <fos:result>2.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(0e0, -3.0e0)</fos:expression>
               <fos:result>xs:double('INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(-0e0, -3.0e0)</fos:expression>
               <fos:result>xs:double('-INF')</fos:result>
               <fos:postamble>Odd-valued whole numbers are treated specially</fos:postamble>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(0e0, -3.1e0)</fos:expression>
               <fos:result>xs:double('INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(-0e0, -3.1e0)</fos:expression>
               <fos:result>xs:double('INF')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(0e0, 3.0e0)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(-0e0, 3.0e0)</fos:expression>
               <fos:result>-0.0e0</fos:result>
               <fos:postamble>Odd-valued whole numbers are treated specially</fos:postamble>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(0e0, 3.1e0)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(-0e0, 3.1e0)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(-1, xs:double('INF'))</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(-1, xs:double('-INF'))</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(1, xs:double('INF'))</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(1, xs:double('-INF'))</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(1, xs:double('NaN'))</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(-2.5e0, 2.0e0)</fos:expression>
               <fos:result>6.25e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:pow(-2.5e0, 2.00000001e0)</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="sin" prefix="math">
      <fos:signatures>
         <fos:proto name="sin" return-type="xs:double?">
            <fos:arg name="θ" type="xs:double?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the sine of the argument. The argument is an angle in radians.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$</code><var>θ</var> is the empty sequence, the function returns the empty
            sequence.</p>

         <p>Otherwise the result is the sine of <code>$</code><var>θ</var> (which is treated as an angle in
            radians) as defined in the <bibref ref="ieee754-2008"/> specification of the
               <code>sin</code> function applied to 64-bit binary floating point values.</p>

      </fos:rules>
      <fos:notes>
         <p>The treatment of the <code>invalidOperation</code> and <code>underflow</code> exceptions
            is defined in <specref ref="op.numeric"/>. </p>
         <p>If <code>$</code><var>θ</var> is positive or negative zero, the result is
               <code>$</code><var>θ</var>.</p>
         <p>If <code>$</code><var>θ</var> is positive or negative infinity, or <code>NaN</code>,
            then the result is <code>NaN</code>.</p>
         <p>Otherwise the result is always in the range -1.0e0 to +1.0e0</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>math:sin(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sin(0)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sin(-0.0e0)</fos:expression>
               <fos:result>-0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sin(math:pi() div 2)</fos:expression>
               <fos:result approx="true">1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sin(-math:pi() div 2)</fos:expression>
               <fos:result approx="true">-1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sin(math:pi())</fos:expression>
               <fos:result approx="true">0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sin(xs:double('NaN'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sin(xs:double('INF'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:sin(xs:double('-INF'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="cos" prefix="math">
      <fos:signatures>
         <fos:proto name="cos" return-type="xs:double?">
            <fos:arg name="θ" type="xs:double?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the cosine of the argument. The argument is an angle in radians.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$</code><var>θ</var> is the empty sequence, the function returns the empty
            sequence.</p>
         <p>If <code>$</code><var>θ</var> is positive or negative infinity, or <code>NaN</code>,
            then the result is <code>NaN</code>.</p>
         <p>Otherwise the result is the cosine of <code>$</code><var>θ</var> (which is treated as an angle in
            radians) as defined in the <bibref ref="ieee754-2008"/> specification of the
               <code>cos</code> function applied to 64-bit binary floating point values.</p>
      </fos:rules>
      <fos:notes>
         <p>The treatment of the <code>invalidOperation</code> exception is defined in <specref
               ref="op.numeric"/>. </p>
         <p>If <code>$</code><var>θ</var> is positive or negative zero, the result is
               <code>$</code><var>θ</var>.</p>
         <p>If <code>$</code><var>θ</var> is positive or negative infinity, or <code>NaN</code>,
            then the result is <code>NaN</code>.</p>
         <p>Otherwise the result is always in the range -1.0e0 to +1.0e0</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>math:cos(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:cos(0)</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:cos(-0.0e0)</fos:expression>
               <fos:result>1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:cos(math:pi() div 2)</fos:expression>
               <fos:result approx="true">0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:cos(-math:pi() div 2)</fos:expression>
               <fos:result approx="true">0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:cos(math:pi())</fos:expression>
               <fos:result approx="true">-1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:cos(xs:double('NaN'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:cos(xs:double('INF'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:cos(xs:double('-INF'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="tan" prefix="math">
      <fos:signatures>
         <fos:proto name="tan" return-type="xs:double?">
            <fos:arg name="θ" type="xs:double?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the tangent of the argument. The argument is an angle in radians.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$</code><var>θ</var> is the empty sequence, the function returns the empty
            sequence.</p>
         <p>Otherwise the result is the tangent of <code>$</code><var>θ</var> (which is treated as an angle
            in radians) as defined in the <bibref ref="ieee754-2008"/> specification of the
               <code>tan</code> function applied to 64-bit binary floating point values.</p>

      </fos:rules>
      <fos:notes>
         <p>The treatment of the <code>invalidOperation</code> and <code>underflow</code> exceptions
            is defined in <specref ref="op.numeric"/>. </p>
         <p>If <code>$</code><var>θ</var> is positive or negative infinity, or <code>NaN</code>,
            then the result is <code>NaN</code>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>math:tan(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:tan(0)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:tan(-0.0e0)</fos:expression>
               <fos:result>-0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:tan(math:pi() div 4)</fos:expression>
               <fos:result approx="true">1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:tan(-math:pi() div 4)</fos:expression>
               <fos:result approx="true">-1.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>1 div math:tan(math:pi() div 2)</fos:expression>
               <fos:result approx="true">0.0e0</fos:result>
               <fos:postamble>Mathematically, <emph>tan(π/2)</emph> is positive infinity. But because <code>math:pi() div 2</code>
                  returns an approximation, the result of <code>math:tan(math:pi() div 2)</code> will be a large
                  but finite number.</fos:postamble>
            </fos:test>
            <fos:test>
               <fos:expression>1 div math:tan(-math:pi() div 2)</fos:expression>
               <fos:result approx="true">-0.0e0</fos:result>
               <fos:postamble>Mathematically, <emph>tan(-π/2)</emph> is negative infinity. But because <code>-math:pi() div 2</code>
                  returns an approximation, the result of <code>math:tan(-math:pi() div 2)</code> will be a large
                  but finite negative number.</fos:postamble>
            </fos:test>
            <fos:test>
               <fos:expression>math:tan(math:pi())</fos:expression>
               <fos:result approx="true">0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:tan(xs:double('NaN'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:tan(xs:double('INF'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:tan(xs:double('-INF'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="asin" prefix="math">
      <fos:signatures>
         <fos:proto name="asin" return-type="xs:double?">
            <fos:arg name="arg" type="xs:double?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the arc sine of the argument.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise the result is the arc sine of <code>$arg</code> as defined in the <bibref ref="ieee754-2008"/> specification of the
            <code>asin</code> function applied to 64-bit binary floating point values. 
            The result is in the range -<var>π</var>/2 to +<var>π</var>/2 radians. </p>
      </fos:rules>
      <fos:notes>
         <p>The treatment of the <code>invalidOperation</code> and <code>underflow</code> exceptions
            is defined in <specref ref="op.numeric"/>. </p>
         <p>If <code>$arg</code> is positive or negative zero, the result is <code>$arg</code>.</p>
         <p>If <code>$arg</code> is <code>NaN</code>, or if its absolute value is greater than one,
            then the result is <code>NaN</code>.</p>
         <p>In other cases the result is an <code>xs:double</code> value representing an angle
               <var>θ</var> in radians in the range -<var>π</var><code>/2 &lt;=
               </code><var>θ</var><code> &lt;= +</code><var>π</var><code>/2</code>. </p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>math:asin(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:asin(0)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:asin(-0.0e0)</fos:expression>
               <fos:result>-0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:asin(1.0e0)</fos:expression>
               <fos:result approx="true">1.5707963267948966e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:asin(-1.0e0)</fos:expression>
               <fos:result approx="true">-1.5707963267948966e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:asin(2.0e0)</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:asin(xs:double('NaN'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:asin(xs:double('INF'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:asin(xs:double('-INF'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="acos" prefix="math">
      <fos:signatures>
         <fos:proto name="acos" return-type="xs:double?">
            <fos:arg name="arg" type="xs:double?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the arc cosine of the argument.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise the result is the arc cosine of <code>$arg</code>, as defined in the <bibref ref="ieee754-2008"/> specification of the
               <code>acos</code> function applied to 64-bit binary floating point values.
            The result is in the range zero to +<var>π</var> radians.</p>
      </fos:rules>
      <fos:notes>
         <p>The treatment of the <code>invalidOperation</code> exception is defined in <specref
               ref="op.numeric"/>. </p>
         <p>If <code>$arg</code> is <code>NaN</code>, or if its absolute value is greater than one,
            then the result is <code>NaN</code>.</p>
         <p>In other cases the result is an <code>xs:double</code> value representing an angle
               <var>θ</var> in radians in the range <code>0 &lt;= </code><var>θ</var><code> &lt;=
               +</code><var>π</var>. </p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>math:acos(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:acos(0)</fos:expression>
               <fos:result approx="true">1.5707963267948966e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:acos(-0.0e0)</fos:expression>
               <fos:result approx="true">1.5707963267948966e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:acos(1.0e0)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:acos(-1.0e0)</fos:expression>
               <fos:result approx="true">3.141592653589793e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:acos(2.0e0)</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:acos(xs:double('NaN'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:acos(xs:double('INF'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:acos(xs:double('-INF'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="atan" prefix="math">
      <fos:signatures>
         <fos:proto name="atan" return-type="xs:double?">
            <fos:arg name="arg" type="xs:double?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the arc tangent of the argument.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise the result is the arc tangent of <code>$arg</code>, as defined 
            in the <bibref ref="ieee754-2008"/> specification of the
               <code>atan</code> function applied to 64-bit binary floating point values.
            The result is in the range -<var>π</var>/2
            to +<var>π</var>/2 radians.</p>
      </fos:rules>
      <fos:notes>
         <p>The treatment of the <code>underflow</code> exception is defined in <specref
               ref="op.numeric"/>. </p>
         <p>If <code>$arg</code> is positive or negative zero, the result is <code>$arg</code>.</p>
         <p>If <code>$arg</code> is <code>NaN</code> then the result is <code>NaN</code>.</p>
         <p>In other cases the result is an <code>xs:double</code> value representing an angle
               <var>θ</var> in radians in the range -<var>π</var><code>/2 &lt;=
               </code><var>θ</var><code> &lt;= +</code><var>π</var><code>/2</code>. </p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>math:atan(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan(0)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan(-0.0e0)</fos:expression>
               <fos:result>-0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan(1.0e0)</fos:expression>
               <fos:result approx="true">0.7853981633974483e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan(-1.0e0)</fos:expression>
               <fos:result approx="true">-0.7853981633974483e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan(xs:double('NaN'))</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan(xs:double('INF'))</fos:expression>
               <fos:result approx="true">1.5707963267948966e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan(xs:double('-INF'))</fos:expression>
               <fos:result approx="true">-1.5707963267948966e0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="atan2" prefix="math">
      <fos:signatures>
         <fos:proto name="atan2" return-type="xs:double">
            <fos:arg name="y" type="xs:double"/>
            <fos:arg name="x" type="xs:double"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the angle in radians subtended at the origin by the point on a plane with
            coordinates (x, y) and the positive x-axis.</p>
      </fos:summary>
      <fos:rules>
         <p>The result is the value of <code>atan2(y, x)</code> as defined in the <bibref
               ref="ieee754-2008"/> specification of the <code>atan2</code> function applied to
            64-bit binary floating point values. The result is in the range -<var>π</var>
            to +<var>π</var> radians.</p>
      </fos:rules>
      <fos:notes>
         <p>The treatment of the <code>underflow</code> exception is defined in <specref
               ref="op.numeric"/>. </p>
         <p>If either argument is <code>NaN</code> then the result is <code>NaN</code>.</p>
         <p>If <code>$y</code> is positive and <code>$x</code> is positive and finite, then (subject
            to rules for overflow, underflow and approximation) the value of <code>atan2($y,
               $x)</code> is <code>atan($y div $x)</code>.</p>
         <p>If <code>$y</code> is positive and <code>$x</code> is negative and finite, then (subject
            to the same caveats) the value of <code>atan2($y, $x)</code> is <var>π</var>
            <code>- atan($y div $x)</code>.</p>
         <p>Some results for special values of the arguments are shown in the examples below.</p>

      </fos:notes>
      <fos:examples>


         <fos:example>
            <fos:test>
               <fos:expression>math:atan2(+0.0e0, 0.0e0)</fos:expression>
               <fos:result>0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan2(-0.0e0, 0.0e0)</fos:expression>
               <fos:result>-0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan2(+0.0e0, -0.0e0)</fos:expression>
               <fos:result>3.141592653589793e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan2(-0.0e0, -0.0e0)</fos:expression>
               <fos:result>-3.141592653589793e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan2(-1, 0.0e0)</fos:expression>
               <fos:result>-1.5707963267948966e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan2(+1, 0.0e0)</fos:expression>
               <fos:result>1.5707963267948966e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan2(-0.0e0, -1)</fos:expression>
               <fos:result>-3.141592653589793e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan2(+0.0e0, -1)</fos:expression>
               <fos:result>3.141592653589793e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan2(-0.0e0, +1)</fos:expression>
               <fos:result>-0.0e0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>math:atan2(+0.0e0, +1)</fos:expression>
               <fos:result>+0.0e0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="codepoints-to-string" prefix="fn">
      <fos:signatures>
         <fos:proto name="codepoints-to-string" return-type="xs:string">
            <fos:arg name="arg" type="xs:integer*"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p diff="chg" at="C">Returns an <code>xs:string</code> whose characters have supplied <termref def="codepoint"
               >codepoints</termref>.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the string made up from the <termref def="character"
               >characters</termref> whose Unicode <termref def="codepoint">codepoints</termref> are
            supplied in <code>$arg</code>. This will be the zero-length string if <code>$arg</code>
            is the empty sequence. </p>

      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="CH" code="0001"/> if any of the codepoints in
               <code>$arg</code> is not a permitted XML character.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:codepoints-to-string((66, 65, 67, 72))</fos:expression>
               <fos:result>"BACH"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:codepoints-to-string((2309, 2358, 2378, 2325))</fos:expression>
               <fos:result>"अशॊक"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:codepoints-to-string(())</fos:expression>
               <fos:result>""</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:codepoints-to-string(0)</fos:expression>
               <fos:error-result error-code="FOCH0001"/>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="string-to-codepoints" prefix="fn">
      <fos:signatures>
         <fos:proto name="string-to-codepoints" return-type="xs:integer*">
            <fos:arg name="arg" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the sequence of <termref def="codepoint">codepoints</termref> that constitute an
               <code>xs:string</code> value. </p>
      </fos:summary>
      <fos:rules>
         <p>The function returns a sequence of integers, each integer being the Unicode <termref
               def="codepoint">codepoint</termref> of the corresponding <termref def="character"
               >character</termref> in <code>$arg</code>.</p>
         <p>If <code>$arg</code> is a zero-length string or the empty sequence, the function returns
            the empty sequence.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:string-to-codepoints("Thérèse")</fos:expression>
               <fos:result>(84, 104, 233, 114, 232, 115, 101)</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="compare" prefix="fn">
      <fos:signatures>
         <fos:proto name="compare" return-type="xs:integer?">
            <fos:arg name="comparand1" type="xs:string?"/>
            <fos:arg name="comparand2" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="compare" return-type="xs:integer?">
            <fos:arg name="comparand1" type="xs:string?"/>
            <fos:arg name="comparand2" type="xs:string?"/>
            <fos:arg name="collation" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="3">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns -1, 0, or 1, depending on whether <code>$comparand1</code> collates before,
            equal to, or after <code>$comparand2</code> according to the rules of a selected
            collation.</p>
      </fos:summary>
      <fos:rules>
         <p>Returns -1, 0, or 1, depending on whether the value of the <code>$comparand1</code> is
            respectively less than, equal to, or greater than the value of <code>$comparand2</code>,
            according to the rules of the collation that is used. </p>
         <p>The collation used by this function is determined according to the rules in <specref
               ref="choosing-a-collation"/>. </p>
         <p>If either <code>$comparand1</code> or <code>$comparand2</code> is the empty sequence,
            the function returns the empty sequence.</p>
         <p>This function, called with the first signature, defines the semantics of the "eq", "ne",
            "gt", "lt", "le" and "ge" operators on <code>xs:string</code> values.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:compare('abc', 'abc')</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test default-collation="http://www.w3.org/2013/collation/UCA?lang=de;strength=primary">
               <fos:expression>fn:compare('Strasse', 'Straße')</fos:expression>
               <fos:result>0</fos:result>
               <fos:postamble>Assuming the default collation includes provisions that equate
                     <quote>ss</quote> and the (German) character <quote>ß</quote>
                     (<quote>sharp-s</quote>). Otherwise, the returned value depends on the
                  semantics of the default collation.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:compare('Strasse', 'Straße',
                  'http://www.w3.org/2013/collation/UCA?lang=de;strength=primary')</fos:expression>
               <fos:result>0</fos:result>
               <fos:postamble>The specified collation equates
                     <quote>ss</quote> and the (German) character <quote>ß</quote>
                     (<quote>sharp-s</quote>).</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test default-collation="http://www.w3.org/2013/collation/UCA?lang=de">
               <fos:expression>fn:compare('Strassen', 'Straße')</fos:expression>
               <fos:result>1</fos:result>
               <fos:postamble>Assuming the default collation includes provisions that treat
                  differences between <quote>ss</quote> and the (German) character <quote>ß</quote>
                     (<quote>sharp-s</quote>) with less strength than the differences between the
                  base characters, such as the final <quote>n</quote>. </fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="codepoint-equal" prefix="fn">
      <fos:signatures>
         <fos:proto name="codepoint-equal" return-type="xs:boolean?">
            <fos:arg name="comparand1" type="xs:string?"/>
            <fos:arg name="comparand2" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if two strings are equal, considered codepoint-by-codepoint.</p>
      </fos:summary>
      <fos:rules>
         <p>If either argument is the empty sequence, the function returns the empty sequence. </p>
         <p>Otherwise, the function returns <code>true</code> or <code>false</code> depending on
            whether the value of <code>$comparand1</code> is equal to the value of
               <code>$comparand2</code>, according to the Unicode codepoint collation
               (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p>

      </fos:rules>
      <fos:notes>
         <p>This function allows <code>xs:anyURI</code> values to be compared without having to
            specify the Unicode codepoint collation.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:codepoint-equal("abcd", "abcd")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:codepoint-equal("abcd", "abcd ")</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:codepoint-equal("", "")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:codepoint-equal("", ())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:codepoint-equal((), ())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="concat" prefix="fn">
      <fos:signatures>
         <fos:proto name="concat" return-type="xs:string">
            <fos:arg name="arg1" type="xs:anyAtomicType?"/>
            <fos:arg name="arg2" type="xs:anyAtomicType?"/>
            <fos:arg name="..." type="xs:anyAtomicType?"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="||" types="xs:anyAtomicType xs:anyAtomicType"> The two-argument form of
         this function defines the semantics of the "||" operator.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the concatenation of the string values of the arguments.</p>
      </fos:summary>
      <fos:rules>
         <p>This function accepts two or more <code>xs:anyAtomicType</code> arguments and casts each
            one to <code>xs:string</code>. The function returns the <code>xs:string</code> that is
            the concatenation of the values of its arguments after conversion. If any argument is
            the empty sequence, that argument is treated as the zero-length string.</p>
         <p>The <code>fn:concat</code> function is specified to allow two or more arguments, which
            are concatenated together. This is the only function specified in this document that
            allows a variable number of arguments. This capability is retained for compatibility
            with <bibref ref="xpath"/>. </p>
      </fos:rules>
      <fos:notes>
         <p>As mentioned in <specref ref="string-types"/> Unicode normalization is not automatically
            applied to the result of <code>fn:concat</code>. If a normalized result is required,
               <code>fn:normalize-unicode</code> can be applied to the <code>xs:string</code>
            returned by <code>fn:concat</code>. The following XQuery:</p>
         <eg xml:space="preserve">
let $v1 := "I plan to go to Mu"
let $v2 := "?nchen in September"
return concat($v1, $v2)</eg>
         <p>where the "?" represents either the actual Unicode character COMBINING DIARESIS (Unicode
            codepoint U+0308) or "&amp;#x0308;", will return:</p>
         <p>"I plan to go to Mu?nchen in September"</p>
         <p>where the "?" represents either the actual Unicode character COMBINING DIARESIS (Unicode
            codepoint U+0308) or "&amp;#x0308;". It is worth noting that the returned value is not
            normalized in NFC; however, it is normalized in NFD.</p>
         <p> However, the following XQuery:</p>
         <eg xml:space="preserve">
let $v1 := "I plan to go to Mu"
let $v2 := "?nchen in September"
return normalize-unicode(concat($v1, $v2))</eg>
         <p>where the "?" represents either the actual Unicode character COMBINING DIARESIS (Unicode
            codepoint U+0308) or "&amp;#x0308;", will return:</p>
         <p> "I plan to go to München in September"</p>
         <p>This returned result is normalized in NFC.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:concat('un', 'grateful')</fos:expression>
               <fos:result>"ungrateful"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:concat('Thy ', (), 'old ', "groans", "", ' ring',
                  ' yet', ' in', ' my', ' ancient',' ears.')</fos:expression>
               <fos:result>"Thy old groans ring yet in my ancient ears."</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:concat('Ciao!',())</fos:expression>
               <fos:result>"Ciao!"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:concat('Ingratitude, ', 'thou ', 'marble-hearted', ' fiend!')</fos:expression>
               <fos:result>"Ingratitude, thou marble-hearted fiend!"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:concat(01, 02, 03, 04, true())</fos:expression>
               <fos:result>"1234true"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>10 || '/' || 6</fos:expression>
               <fos:result>"10/6"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="string-join" prefix="fn">
      <fos:signatures>
         <fos:proto name="string-join" return-type="xs:string">
            <fos:arg name="arg1" type="xs:anyAtomicType*"/>
         </fos:proto>
         <fos:proto name="string-join" return-type="xs:string">
            <fos:arg name="arg1" type="xs:anyAtomicType*"/>
            <fos:arg name="arg2" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a string created by concatenating the items in a sequence, with a defined
            separator between adjacent items.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of calling the single-argument version of this function is the same as
            calling the two-argument version with <code>$arg2</code> set to a zero-length
            string.</p>
         <p>The function returns an <code>xs:string</code> created by <phrase diff="chg" at="D">casting each item 
            in the sequence <code>$arg1</code> to an <code>xs:string</code>, 
            and then concatenating the result strings in order,</phrase> 
            using the value of <code>$arg2</code> as a
            separator between adjacent strings. If the value of <code>$arg2</code> is the zero-length
            string, then the members of <code>$arg1</code> are concatenated without a separator.</p>

      </fos:rules>
      <fos:notes>
         <p>If the value of <code>$arg1</code> is the empty sequence, the function returns the
            zero-length string.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:string-join(1 to 9)</fos:expression>
               <fos:result>"123456789"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:string-join(('Now', 'is', 'the', 'time', '...'),
                  ' ')</fos:expression>
               <fos:result>"Now is the time ..."</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:string-join(('Blow, ', 'blow, ', 'thou ', 'winter ', 'wind!'),
                  '')</fos:expression>
               <fos:result>"Blow, blow, thou winter wind!"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:string-join((), 'separator')</fos:expression>
               <fos:result>""</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:string-join(1 to 5, ', ')</fos:expression>
               <fos:result>"1, 2, 3, 4, 5"</fos:result>
            </fos:test>
         </fos:example>
         
         <fos:variable name="doc" id="v-string-join-doc">&lt;doc&gt;
  &lt;chap&gt;
    &lt;section xml:id="xyz"/&gt;
  &lt;/chap&gt;
&lt;/doc&gt;</fos:variable>
         <fos:example>
            <fos:test use="v-string-join-doc">
               <fos:expression>$doc//@xml:id ! fn:string-join((node-name(), '="', ., '"'))</fos:expression>
               <fos:result>'xml:id="xyz"'</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-string-join-doc">
               <fos:expression>$doc//section ! fn:string-join(ancestor-or-self::*/name(), '/')</fos:expression>
               <fos:result>"doc/chap/section"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="substring" prefix="fn">
      <fos:signatures>
         <fos:proto name="substring" return-type="xs:string">
            <fos:arg name="sourceString" type="xs:string?"/>
            <fos:arg name="start" type="xs:double"/>
         </fos:proto>
         <fos:proto name="substring" return-type="xs:string">
            <fos:arg name="sourceString" type="xs:string?"/>
            <fos:arg name="start" type="xs:double"/>
            <fos:arg name="length" type="xs:double"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the portion of the value of <code>$sourceString</code> beginning at the position
            indicated by the value of <code>$start</code> and continuing for the number of <termref
               def="character">characters</termref> indicated by the value of
            <code>$length</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If the value of <code>$sourceString</code> is the empty sequence, the function returns
            the zero-length string. </p>
         <p>Otherwise, the function returns a string comprising those <termref def="character"
               >characters</termref> of <code>$sourceString</code> whose index position (counting
            from one) is greater than or equal to the value of <code>$start</code> (rounded to an
            integer), and (if <code>$length</code> is specified) less than the sum of
               <code>$start</code> and <code>$length</code> (both rounded to integers).</p>
         <p>The characters returned do not extend beyond <code>$sourceString</code>. If
               <code>$start</code> is zero or negative, only those characters in positions greater
            than zero are returned.</p>
         <p>More specifically, the three argument version of the function returns the characters in
               <code>$sourceString</code> whose position <code>$p</code> satisfies:</p>
         <p diff="chg" at="E">
            <code>fn:round($start) &lt;= $p and $p &lt; fn:round($start) + fn:round($length)</code>
         </p>
         <p>The two argument version of the function assumes that <code>$length</code> is infinite
            and thus returns the <termref def="character">characters</termref> in
               <code>$sourceString</code> whose position <code>$p</code> satisfies:</p>
         <p>
            <code>fn:round($start) &lt;= $p</code>
         </p>
         <p>In the above computations, the rules for <code>op:numeric-less-than</code> and
               <code>op:numeric-greater-than</code> apply.</p>
      </fos:rules>
      <fos:notes>
         <p>The first character of a string is located at position 1, not position 0.</p>
         <p>The second and third arguments allow <code>xs:double</code> values (rather than
         requiring <code>xs:integer</code>) in order to achieve compatibility with XPath 1.0.</p>
         <p>A surrogate pair counts as one character, not two.</p>
         <p>The consequences of supplying values such as <code>NaN</code> or positive or negative
         infinity for the <code>$start</code> or <code>$length</code> arguments follow from the
         above rules, and are not always intuitive.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring("motor car", 6)</fos:expression>
               <fos:result>" car"</fos:result>
               <fos:postamble>Characters starting at position 6 to the end of
                     <code>$sourceString</code> are selected.</fos:postamble>
            </fos:test>
            <p/>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring("metadata", 4, 3)</fos:expression>
               <fos:result>"ada"</fos:result>
               <fos:postamble>Characters at positions greater than or equal to 4 and less than 7 are
                  selected.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring("12345", 1.5, 2.6)</fos:expression>
               <fos:result>"234"</fos:result>
               <fos:postamble>Characters at positions greater than or equal to 2 and less than 5 are
                  selected.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring("12345", 0, 3)</fos:expression>
               <fos:result>"12"</fos:result>
               <fos:postamble>Characters at positions greater than or equal to 0 and less than 3 are
                  selected. Since the first position is 1, these are the characters at positions 1
                  and 2.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring("12345", 5, -3)</fos:expression>
               <fos:result>""</fos:result>
               <fos:postamble>Characters at positions greater than or equal to 5 and less than 2 are
                  selected.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring("12345", -3, 5)</fos:expression>
               <fos:result>"1"</fos:result>
               <fos:postamble>Characters at positions greater than or equal to -3 and less than 2
                  are selected. Since the first position is 1, this is the character at position
                  1.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring("12345", 0 div 0E0, 3)</fos:expression>
               <fos:result>""</fos:result>
               <fos:postamble>Since <code>0 div 0E0</code> returns <code>NaN</code>, and
                     <code>NaN</code> compared to any other number returns <code>false</code>, no
                  characters are selected.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring("12345", 1, 0 div 0E0)</fos:expression>
               <fos:result>""</fos:result>
               <fos:postamble>As above.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring((), 1, 3)</fos:expression>
               <fos:result>""</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring("12345", -42, 1 div 0E0)</fos:expression>
               <fos:result>"12345"</fos:result>
               <fos:postamble>Characters at positions greater than or equal to -42 and less than
                     <code>INF</code> are selected.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring("12345", -1 div 0E0, 1 div 0E0)</fos:expression>
               <fos:result>""</fos:result>
               <fos:postamble>Since the value of <code>-INF + INF</code> is <code>NaN</code>, no
                  characters are selected.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="string-length" prefix="fn">
      <fos:signatures>
         <fos:proto name="string-length" return-type="xs:integer"/>
         <fos:proto name="string-length" return-type="xs:integer">
            <fos:arg name="arg" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the number of <termref def="character">characters</termref> in a string.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns an <code>xs:integer</code> equal to the length in <termref
               def="character">characters</termref> of the value of <code>$arg</code>.</p>
         <p>Calling the zero-argument version of the function is equivalent to calling
               <code>fn:string-length(fn:string(.))</code>.</p>
         <p>If the value of <code>$arg</code> is the empty sequence, the function returns the
               <code>xs:integer</code> value zero (0).</p>
      </fos:rules>
      <fos:errors>
         <p>If <code>$arg</code> is not specified and the context item is <xtermref ref="dt-absent"
               spec="DM31">absent</xtermref>, a dynamic error is raised: <xerrorref spec="XP"
               class="DY" code="0002" type="dynamic"/>.</p>
      </fos:errors>
      <fos:notes>
         <p>Unlike some programming languages, a <termref def="codepoint">codepoint</termref>
            greater than 65535 counts as one character, not two.</p>
         <p>There are situations where <code>fn:string-length()</code> has a different effect
            from <code>fn:string-length(.)</code>. For example, if the context item
         is an attribute node typed as an <code>xs:integer</code> with the string value <code>000001</code>,
         then <code>fn:string-length()</code> returns 6 (the length of the string value of the node), while 
            <code>fn:string-length(.)</code> raises a type error (because the result of atomization
            is not an <code>xs:string</code>).</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:string-length("Harp not on that string, madam; that is past.")</fos:expression>
               <fos:result>45</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:string-length(())</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="normalize-space" prefix="fn">
      <fos:signatures>
         <fos:proto name="normalize-space" return-type="xs:string"/>
         <fos:proto name="normalize-space" return-type="xs:string">
            <fos:arg name="arg" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the value of <code>$arg</code> with leading and trailing whitespace removed, and
            sequences of internal whitespace reduced to a single space character.</p>
      </fos:summary>
      <fos:rules>
         <p>If the value of <code>$arg</code> is the empty sequence, the function returns the
            zero-length string.</p>
         <p>The function returns a string constructed by stripping leading and trailing whitespace
            from the value of <code>$arg</code>, and replacing sequences of one or more adjacent
            whitespace characters with a single space, <code>#x20</code>.</p>
         <p>The whitespace characters are defined in the metasymbol S (Production 3) of <bibref
               ref="xml"/>.</p>

         <p>If no argument is supplied, then <code>$arg</code> defaults to the string value
            (calculated using <code>fn:string</code>) of the context item (<code>.</code>). </p>
      </fos:rules>
      <fos:errors>
         <p>If no argument is supplied and the context item is <xtermref ref="dt-absent" spec="DM31"
               >absent</xtermref> then a dynamic error is raised: <xerrorref spec="XP" class="DY"
               code="0002" type="dynamic"/>.</p>
      </fos:errors>
      <fos:notes>
         <p>The definition of whitespace is unchanged in <bibref ref="xml11"/>. It is repeated here
         for convenience:</p>
         <p><code>S ::= (#x20 | #x9 | #xD | #xA)+</code></p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression xml:space="preserve">fn:normalize-space(" The    wealthy curled darlings
                                        of    our    nation. ")</fos:expression>
               <fos:result>"The wealthy curled darlings of our nation."</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:normalize-space(())</fos:expression>
               <fos:result>""</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="normalize-unicode" prefix="fn">
      <fos:signatures>
         <fos:proto name="normalize-unicode" return-type="xs:string">
            <fos:arg name="arg" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="normalize-unicode" return-type="xs:string">
            <fos:arg name="arg" type="xs:string?"/>
            <fos:arg name="normalizationForm" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the value of <code>$arg</code> after applying Unicode normalization.</p>
      </fos:summary>
      <fos:rules>
         <p>If the value of <code>$arg</code> is the empty sequence, the function returns the
            zero-length string.</p>
         <p>If the single-argument version of the function is used, the result is the same as
            calling the two-argument version with <code>$normalizationForm</code> set to the string
            "NFC".</p>
         <p>Otherwise, the function returns the value of <code>$arg</code> normalized according to
            the rules of the normalization form identified by the value of
               <code>$normalizationForm</code>.</p>
         <p>The effective value of <code>$normalizationForm</code> is the value of the expression
               <code>fn:upper-case(fn:normalize-space($normalizationForm))</code>.</p>

         <ulist>
            <item>
               <p>If the effective value of <code>$normalizationForm</code> is <quote>NFC</quote>,
                  then the function returns the value of <code>$arg</code> converted to Unicode
                  Normalization Form C (NFC).</p>
            </item>
            <item>
               <p>If the effective value of <code>$normalizationForm</code> is <quote>NFD</quote>,
                  then the function returns the value of <code>$arg</code> converted to Unicode
                  Normalization Form D (NFD).</p>
            </item>
            <item>
               <p>If the effective value of <code>$normalizationForm</code> is <quote>NFKC</quote>,
                  then the function returns the value of <code>$arg</code> in Unicode Normalization
                  Form KC (NFKC).</p>
            </item>
            <item>
               <p>If the effective value of <code>$normalizationForm</code> is <quote>NFKD</quote>,
                  then the function returns the value of <code>$arg</code> converted to Unicode
                  Normalization Form KD (NFKD).</p>
            </item>
            <item>
               <p>If the effective value of <code>$normalizationForm</code> is
                     <quote>FULLY-NORMALIZED</quote>, then the function returns the value of
                     <code>$arg</code> converted to fully normalized form. </p>
            </item>
            <item>
               <p>If the effective value of <code>$normalizationForm</code> is the zero-length
                  string, no normalization is performed and <code>$arg</code> is returned.</p>
            </item>
         </ulist>
         <p>Normalization forms NFC, NFD, NFKC, and NFKD, and the algorithms to be used for
            converting a string to each of these forms, are defined in <bibref
               ref="UNICODE-TR15"/>.</p>
         <p>The motivation for normalization form FULLY-NORMALIZED is explained in <bibref
               ref="charmod-normalization"/>. However, as that specification did not progress beyond
            working draft status, the normative specification is as follows:</p>
         <ulist>
            <item>
               <p>A string is <term>fully-normalized</term> if (a) it is in normalization form NFC
                  as defined in <bibref ref="UNICODE-TR15"/>, and (b) it does not start
                  with a composing character.</p>
            </item>
            <item>
               <p>A composing character is a character that is one or both of the following:</p>
               <ulist>
                  <item>
                     <p>the second character in the canonical decomposition mapping of some
                        character that is not listed in the Composition Exclusion Table defined in
                        <bibref ref="UNICODE-TR15"/>;</p>
                  </item>
                  <item>
                     <p>of non-zero canonical combining class (as defined in <bibref ref="Unicode"
                        />).</p>
                  </item>

               </ulist>
            </item>
            <item>
               <p>A string is converted to FULLY-NORMALIZED form as follows:</p>
               <ulist>
                  <item>
                     <p>if the first character in the string is a composing character, prepend a
                        single space (x20);</p>
                  </item>
                  <item>
                     <p>convert the resulting string to normalization form NFC.</p>
                  </item>
               </ulist>
            </item>
         </ulist>

         <p>Conforming implementations <rfc2119>must</rfc2119> support normalization form "NFC" and
               <rfc2119>may</rfc2119> support normalization forms "NFD", "NFKC", "NFKD", and
            "FULLY-NORMALIZED". They <rfc2119>may</rfc2119> also support other normalization forms
            with <termref def="implementation-defined">implementation-defined</termref> semantics. </p>
         <p>It is <termref def="implementation-defined">implementation-defined</termref> which
            version of Unicode (and therefore, of the normalization algorithms and their underlying
            data) is supported by the implementation. See <bibref ref="UNICODE-TR15"/> for
            details of the stability policy regarding changes to the normalization rules in future
            versions of Unicode. If the input string contains codepoints that are unassigned in the
            relevant version of Unicode, or for which no normalization rules are defined, the
               <code>fn:normalize-unicode</code> function leaves such codepoints unchanged. If the
            implementation supports the requested normalization form then it <rfc2119>must</rfc2119>
            be able to handle every input string without raising an error.</p>
      </fos:rules>
      <fos:errors>
         <p>A <phrase>dynamic</phrase> error is raised <errorref class="CH" code="0003"/> if the
            effective value of the <code>$normalizationForm</code> argument is not one of the values
            supported by the implementation.</p>
      </fos:errors>
   </fos:function>
   <fos:function name="upper-case" prefix="fn">
      <fos:signatures>
         <fos:proto name="upper-case" return-type="xs:string">
            <fos:arg name="arg" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Converts a string to upper case.</p>
      </fos:summary>
      <fos:rules>
         <p>If the value of <code>$arg</code> is the empty sequence, the zero-length string is
            returned.</p>
         <p>Otherwise, the function returns the value of <code>$arg</code> after translating every
               <termref def="character">character</termref> to its upper-case correspondent as
            defined in the appropriate case mappings section in the Unicode standard <bibref
               ref="Unicode"/>. For versions of Unicode beginning with the 2.1.8 update, only
            locale-insensitive case mappings should be applied. Beginning with version 3.2.0 (and
            likely future versions) of Unicode, precise mappings are described in default case
            operations, which are full case mappings in the absence of tailoring for particular
            languages and environments. Every lower-case character that does not have an upper-case
            correspondent, as well as every upper-case character, is included in the returned value
            in its original form. </p>
      </fos:rules>
      <fos:notes>
         <p>Case mappings may change the length of a string. In general, the
               <code>fn:upper-case</code> and <code>fn:lower-case</code> functions are not inverses
            of each other: <code>fn:lower-case(fn:upper-case($arg))</code> is not guaranteed to
            return <code>$arg</code>, nor is <code>fn:upper-case(fn:lower-case($arg))</code>. The
            Latin small letter dotless i (as used in Turkish) is perhaps the most prominent
            lower-case letter which will not round-trip. The Latin capital letter i with dot above
            is the most prominent upper-case letter which will not round trip; there are others,
            such as Latin capital letter Sharp S (#1E9E) which was introduced in Unicode 5.1.</p>
         <p> These functions may not always be linguistically appropriate (e.g. Turkish i without
            dot) or appropriate for the application (e.g. titlecase). In cases such as Turkish, a
            simple translation should be used first.</p>
         <p> Because the function is not sensitive to locale, results will not always match user
            expectations. In Quebec, for example, the standard uppercase equivalent of "è" is "È",
            while in metropolitan France it is more commonly "E"; only one of these is supported by
            the functions as defined.</p>
         <p> Many characters of class Ll lack uppercase equivalents in the Unicode case mapping
            tables; many characters of class Lu lack lowercase equivalents.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:upper-case("abCd0")</fos:expression>
               <fos:result>"ABCD0"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="lower-case" prefix="fn">
      <fos:signatures>
         <fos:proto name="lower-case" return-type="xs:string">
            <fos:arg name="arg" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Converts a string to lower case.</p>
      </fos:summary>
      <fos:rules>
         <p>If the value of <code>$arg</code> is the empty sequence, the zero-length string is
            returned.</p>
         <p>Otherwise, the function returns the value of <code>$arg</code> after translating every
               <termref def="character">character</termref> to its lower-case correspondent as
            defined in the appropriate case mappings section in the Unicode standard <bibref
               ref="Unicode"/>. For versions of Unicode beginning with the 2.1.8 update, only
            locale-insensitive case mappings should be applied. Beginning with version 3.2.0 (and
            likely future versions) of Unicode, precise mappings are described in default case
            operations, which are full case mappings in the absence of tailoring for particular
            languages and environments. Every upper-case character that does not have a lower-case
            correspondent, as well as every lower-case character, is included in the returned value
            in its original form. </p>
      </fos:rules>
      <fos:notes>
         <p>Case mappings may change the length of a string. In general, the
               <code>fn:upper-case</code> and <code>fn:lower-case</code> functions are not inverses
            of each other: <code>fn:lower-case(fn:upper-case($arg))</code> is not guaranteed to
            return <code>$arg</code>, nor is <code>fn:upper-case(fn:lower-case($arg))</code>. The
            Latin small letter dotless i (as used in Turkish) is perhaps the most prominent
            lower-case letter which will not round-trip. The Latin capital letter i with dot above
            is the most prominent upper-case letter which will not round trip; there are others,
            such as Latin capital letter Sharp S (#1E9E) which was introduced in Unicode 5.1.</p>
         <p> These functions may not always be linguistically appropriate (e.g. Turkish i without
            dot) or appropriate for the application (e.g. titlecase). In cases such as Turkish, a
            simple translation should be used first.</p>
         <p> Because the function is not sensitive to locale, results will not always match user
            expectations. In Quebec, for example, the standard uppercase equivalent of "è" is "È",
            while in metropolitan France it is more commonly "E"; only one of these is supported by
            the functions as defined.</p>
         <p> Many characters of class Ll lack uppercase equivalents in the Unicode case mapping
            tables; many characters of class Lu lack lowercase equivalents.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:lower-case("ABc!D")</fos:expression>
               <fos:result>"abc!d"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="translate" prefix="fn">
      <fos:signatures>
         <fos:proto name="translate" return-type="xs:string">
            <fos:arg name="arg" type="xs:string?"/>
            <fos:arg name="mapString" type="xs:string"/>
            <fos:arg name="transString" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the value of <code>$arg</code> modified by replacing or removing individual
            characters. </p>
      </fos:summary>
      <fos:rules>
         <p>If the value of <code>$arg</code> is the empty sequence, the function returns the
            zero-length string.</p>
         <p>Otherwise, the function returns a result string constructed by processing each <termref
               def="character">character</termref> in the value of <code>$arg</code>, in order,
            according to the following rules:</p>
         <olist>
            <item>
               <p>If the character does not appear in the value of <code>$mapString</code> then it
                  is added to the result string unchanged.</p>
            </item>
            <item>
               <p>If the character first appears in the value of <code>$mapString</code> at some
                  position <emph>M</emph>, where the value of <code>$transString</code> is
                     <emph>M</emph> or more characters in length, then the character at position
                     <emph>M</emph> in <code>$transString</code> is added to the result string.</p>
            </item>
            <item>
               <p>If the character first appears in the value of <code>$mapString</code> at some
                  position <emph>M</emph>, where the value of <code>$transString</code> is less than
                     <emph>M</emph> characters in length, then the character is omitted from the
                  result string.</p>
            </item>
         </olist>
      </fos:rules>
      <fos:notes>
         <p>If <code>$mapString</code> is the zero-length string then the function returns
               <code>$arg</code> unchanged.</p>
         <p>If a character occurs more than once in <code>$mapString</code>, then the first
            occurrence determines the action taken.</p>
         <p>If <code>$transString</code> is longer than <code>$mapString</code>, the excess
            characters are ignored.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:translate("bar","abc","ABC")</fos:expression>
               <fos:result>"BAr"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:translate("--aaa--","abc-","ABC")</fos:expression>
               <fos:result>"AAA"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:translate("abcdabc", "abc", "AB")</fos:expression>
               <fos:result>"ABdAB"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="encode-for-uri" prefix="fn">
      <fos:signatures>
         <fos:proto name="encode-for-uri" return-type="xs:string">
            <fos:arg name="uri-part" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Encodes reserved characters in a string that is intended to be used in the path segment
            of a URI.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$uri-part</code> is the empty sequence, the function returns the zero-length
            string.</p>
         <p>This function applies the URI escaping rules defined in section 2 of <bibref
               ref="rfc3986"/> to the <code>xs:string</code> supplied as <code>$uri-part</code>. The
            effect of the function is to escape reserved characters. Each such character in the
            string is replaced with its percent-encoded form as described in <bibref ref="rfc3986"
            />.</p>
         <p>Since <bibref ref="rfc3986"/> recommends that, for consistency, URI producers and
            normalizers should use uppercase hexadecimal digits for all percent-encodings, this
            function must always generate hexadecimal values using the upper-case letters A-F.</p>
      </fos:rules>
      <fos:notes>
         <p>All characters are escaped except those identified as "unreserved" by <bibref
               ref="rfc3986"/>, that is the upper- and lower-case letters A-Z, the digits 0-9,
            HYPHEN-MINUS ("-"), LOW LINE ("_"), FULL STOP ".", and TILDE "~".</p>
         <p>This function escapes URI delimiters and therefore cannot be used indiscriminately to
            encode "invalid" characters in a path segment.</p>
         <p>This function is invertible but not idempotent. This is because a string containing a
            percent character will be modified by applying the function: for example
               <code>100%</code> becomes <code>100%25</code>, while <code>100%25</code> becomes
               <code>100%2525</code>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:encode-for-uri("http://www.example.com/00/Weather/CA/Los%20Angeles#ocean")</fos:expression>
               <fos:result>"http%3A%2F%2Fwww.example.com%2F00%2FWeather%2FCA%2FLos%2520Angeles%23ocean"</fos:result>
               <fos:postamble>This is probably not what the user intended because all of the
                  delimiters have been encoded.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>concat("http://www.example.com/",
                  encode-for-uri("~bébé"))</fos:expression>
               <fos:result>"http://www.example.com/~b%C3%A9b%C3%A9"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>concat("http://www.example.com/", encode-for-uri("100% organic"))</fos:expression>
               <fos:result>"http://www.example.com/100%25%20organic"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="iri-to-uri" prefix="fn">
      <fos:signatures>
         <fos:proto name="iri-to-uri" return-type="xs:string">
            <fos:arg name="iri" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Converts a string containing an IRI into a URI according to the rules of <bibref
               ref="rfc3987"/>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$iri</code> is the empty sequence, the function returns the zero-length
            string.</p>
         <p>Otherwise, the function converts the value of <code>$iri</code> into a URI according to
            the rules given in Section 3.1 of <bibref ref="rfc3987"/> by percent-encoding characters
            that are allowed in an IRI but not in a URI. If <code>$iri</code> contains a character
            that is invalid in an IRI, such as the space character (see note below), the invalid
            character is replaced by its percent-encoded form as described in <bibref ref="rfc3986"
            /> before the conversion is performed.</p>
         <p>Since <bibref ref="rfc3986"/> recommends that, for consistency, URI producers and
            normalizers should use uppercase hexadecimal digits for all percent-encodings, this
            function must always generate hexadecimal values using the upper-case letters A-F.</p>
      </fos:rules>
      <fos:notes>
         <p>The function is idempotent but not invertible. Both the inputs <code>My Documents</code>
            and <code>My%20Documents</code> will be converted to the output
               <code>My%20Documents</code>.</p>
         <p>This function does not check whether <code>$iri</code> is a valid IRI. It treats it as
            an <termref def="string">string</termref> and operates on the <termref def="character"
               >characters</termref> in the string.</p>
         <!--Text replaced by erratum E8 change 1"-->
         <p> The following printable ASCII characters are invalid in an IRI: "&lt;", "&gt;", <quote>
               " </quote> (double quote), space, "{", "}", "|", "\", "^", and "`". Since these
            characters should not appear in an IRI, if they do appear in <code>$iri</code> they will
            be percent-encoded. In addition, characters outside the range x20-x7E will be
            percent-encoded because they are invalid in a URI. </p>
         <!--End of text replaced by erratum E8-->
         <p> Since this function does not escape the PERCENT SIGN "%" and this character is not
            allowed in data within a URI, users wishing to convert character strings (such as file
            names) that include "%" to a URI should manually escape "%" by replacing it with "%25".
         </p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:iri-to-uri
                  ("http://www.example.com/00/Weather/CA/Los%20Angeles#ocean")</fos:expression>
               <fos:result>"http://www.example.com/00/Weather/CA/Los%20Angeles#ocean"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:iri-to-uri ("http://www.example.com/~bébé")</fos:expression>
               <fos:result>"http://www.example.com/~b%C3%A9b%C3%A9"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="escape-html-uri" prefix="fn">
      <fos:signatures>
         <fos:proto name="escape-html-uri" return-type="xs:string">
            <fos:arg name="uri" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Escapes a URI in the same way that HTML user agents handle attribute values expected to
            contain URIs.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$uri</code> is the empty sequence, the function returns the zero-length
            string.</p>
         <p>Otherwise, the function escapes all <termref def="character">characters</termref> except
            printable characters of the US-ASCII coded character set, specifically the <termref
               def="codepoint">codepoints</termref> between 32 and 126 (decimal) inclusive. Each
            character in <code>$uri</code> to be escaped is replaced by an escape sequence, which is
            formed by encoding the character as a sequence of octets in UTF-8, and then representing
            each of these octets in the form %HH, where HH is the hexadecimal representation of the
            octet. This function must always generate hexadecimal values using the upper-case
            letters A-F.</p>
      </fos:rules>
      <fos:notes>
         <p>The behavior of this function corresponds to the recommended handling of non-ASCII
            characters in URI attribute values as described in <bibref ref="HTML40"/> Appendix
            B.2.1.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:escape-html-uri("http://www.example.com/00/Weather/CA/Los Angeles#ocean")</fos:expression>
               <fos:result>"http://www.example.com/00/Weather/CA/Los Angeles#ocean"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:escape-html-uri("javascript:if (navigator.browserLanguage == 'fr') window.open('http://www.example.com/~bébé');")</fos:expression>
               <fos:result>"javascript:if (navigator.browserLanguage == 'fr') window.open('http://www.example.com/~b%C3%A9b%C3%A9');"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="contains" prefix="fn">
      <fos:signatures>
         <fos:proto name="contains" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:string?"/>
            <fos:arg name="arg2" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="contains" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:string?"/>
            <fos:arg name="arg2" type="xs:string?"/>
            <fos:arg name="collation" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="3">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if the string <code>$arg1</code> contains <code>$arg2</code> as a
            substring, taking collations into account.</p>
      </fos:summary>
      <fos:rules>
         <p>If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or
            contains only ignorable collation units, it is interpreted as the zero-length
            string.</p>
         <p>If the value of <code>$arg2</code> is the zero-length string, then the function returns
               <code>true</code>.</p>
         <p>If the value of <code>$arg1</code> is the zero-length string, the function returns
               <code>false</code>.</p>
         <p>The collation used by this function is determined according to the rules in <specref
               ref="choosing-a-collation"/>.</p>
         <p>The function returns an <code>xs:boolean</code> indicating whether or not the value of
               <code>$arg1</code> contains (at the beginning, at the end, or anywhere within) at
            least one sequence of collation units that provides a <term>minimal match</term> to the
            collation units in the value of <code>$arg2</code>, according to the collation that is
            used.</p>
         <note>
            <p><term>Minimal match</term> is defined in <bibref ref="UNICODE-TR10"/>. </p>
         </note>

      </fos:rules>
      <fos:errors>
         <p>A <phrase>dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH"
               code="0004"/> if the specified collation does not support collation units.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <p>The collation used in these examples, <code>http://example.com/CollationA</code> is a
               collation in which both "-" and "*" are ignorable collation units.</p>
            <p>"Ignorable collation unit" is equivalent to "ignorable collation element" in <bibref
               ref="UNICODE-TR10"/>.</p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:contains ( "tattoo", "t")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:contains ( "tattoo", "ttt")</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:contains ( "", ())</fos:expression>
               <fos:result>true()</fos:result>
               <fos:postamble>The first rule is applied, followed by the second
                  rule.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:contains ( "abcdefghi", "-d-e-f-",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:contains ( "a*b*c*d*e*f*g*h*i*", "d-ef-",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:contains ( "abcd***e---f*--*ghi", "def",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:contains ( (), "--***-*---",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
               <fos:postamble>The second argument contains only ignorable collation units and is
                  equivalent to the zero-length string.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="starts-with" prefix="fn">
      <fos:signatures>
         <fos:proto name="starts-with" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:string?"/>
            <fos:arg name="arg2" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="starts-with" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:string?"/>
            <fos:arg name="arg2" type="xs:string?"/>
            <fos:arg name="collation" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="3">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if the string <code>$arg1</code> contains <code>$arg2</code> as a leading
            substring, taking collations into account.</p>
      </fos:summary>
      <fos:rules>
         <p>If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or
            contains only ignorable collation units, it is interpreted as the zero-length
            string.</p>
         <p>If the value of <code>$arg2</code> is the zero-length string, then the function returns
               <code>true</code>. If the value of <code>$arg1</code> is the zero-length string and
            the value of <code>$arg2</code> is not the zero-length string, then the function returns
               <code>false</code>.</p>
         <p>The collation used by this function is determined according to the rules in <specref
               ref="choosing-a-collation"/>.</p>
         <p>The function returns an <code>xs:boolean</code> indicating whether or not the value of
               <code>$arg1</code> starts with a sequence of collation units that provides a
               <term>match</term> to the collation units of <code>$arg2</code> according to the
            collation that is used.</p>
         <note>
            <p><term>Match</term> is defined in <bibref ref="UNICODE-TR10"/>.</p>
         </note>

      </fos:rules>
      <fos:errors>
         <p>A <phrase>dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH"
               code="0004"/> if the specified collation does not support collation units.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <p>The collation used in these examples, <code>http://example.com/CollationA</code> is a
               collation in which both "-" and "*" are ignorable collation units.</p>
            <p>"Ignorable collation unit" is equivalent to "ignorable collation element" in <bibref
                  ref="UNICODE-TR10"/>.</p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:starts-with("tattoo", "tat")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:starts-with ( "tattoo", "att")</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:starts-with ((), ())</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:starts-with ( "abcdefghi", "-a-b-c-",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:starts-with ( "a*b*c*d*e*f*g*h*i*", "a-bc-",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:starts-with ( "abcd***e---f*--*ghi", "abcdef",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:starts-with ( (), "--***-*---",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
               <fos:postamble>The second argument contains only ignorable collation units and is
                  equivalent to the zero-length string.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:starts-with ( "-abcdefghi", "-abc",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="ends-with" prefix="fn">
      <fos:signatures>
         <fos:proto name="ends-with" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:string?"/>
            <fos:arg name="arg2" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="ends-with" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:string?"/>
            <fos:arg name="arg2" type="xs:string?"/>
            <fos:arg name="collation" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="3">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if the string <code>$arg1</code> contains <code>$arg2</code> as a trailing
            substring, taking collations into account.</p>
      </fos:summary>
      <fos:rules>
         <p>If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or
            contains only ignorable collation units, it is interpreted as the zero-length
            string.</p>
         <p>If the value of <code>$arg2</code> is the zero-length string, then the function returns
               <code>true</code>. If the value of <code>$arg1</code> is the zero-length string and
            the value of <code>$arg2</code> is not the zero-length string, then the function returns
               <code>false</code>.</p>
         <p>The collation used by this function is determined according to the rules in <specref
               ref="choosing-a-collation"/>.</p>
         <p>The function returns an <code>xs:boolean</code> indicating whether or not the value of
               <code>$arg1</code> <phrase diff="chg" at="B">ends</phrase> with a sequence of collation units that provides a
               <term>match</term> to the collation units of <code>$arg2</code> according to the
            collation that is used.</p>
         <note>
            <p>
               <term>Match</term> is defined in <bibref ref="UNICODE-TR10"/>. </p>
         </note>

      </fos:rules>
      <fos:errors>
         <p>A <phrase>dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH"
               code="0004"/> if the specified collation does not support collation units.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <p>The collation used in these examples, <code>http://example.com/CollationA</code> is a
               collation in which both "-" and "*" are ignorable collation units.</p>
            <p>"Ignorable collation unit" is equivalent to "ignorable collation element" in <bibref
                  ref="UNICODE-TR10"/>.</p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:ends-with ( "tattoo", "tattoo")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:ends-with ( "tattoo", "atto")</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:ends-with ((), ())</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:ends-with ( "abcdefghi", "-g-h-i-",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:ends-with ( "abcd***e---f*--*ghi", "defghi",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:ends-with ( "abcd***e---f*--*ghi", "defghi",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:ends-with ( (), "--***-*---",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
               <fos:postamble>The second argument contains only ignorable collation units and is
                  equivalent to the zero-length string.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:ends-with ( "abcdefghi", "ghi-",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="substring-before" prefix="fn">
      <fos:signatures>
         <fos:proto name="substring-before" return-type="xs:string">
            <fos:arg name="arg1" type="xs:string?"/>
            <fos:arg name="arg2" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="substring-before" return-type="xs:string">
            <fos:arg name="arg1" type="xs:string?"/>
            <fos:arg name="arg2" type="xs:string?"/>
            <fos:arg name="collation" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="3">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the part of <code>$arg1</code> that precedes the first occurrence of
               <code>$arg2</code>, taking collations into account.</p>
      </fos:summary>
      <fos:rules>
         <p> If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or
            contains only ignorable collation units, it is interpreted as the zero-length
            string.</p>
         <p>If the value of <code>$arg2</code> is the zero-length string, then the function returns
            the zero-length string. </p>
         <p>If the value of <code>$arg1</code> does not contain a string that is equal to the value
            of <code>$arg2</code>, then the function returns the zero-length string. </p>
         <p>The collation used by this function is determined according to the rules in <specref
               ref="choosing-a-collation"/>.</p>
         <p>The function returns the substring of the value of <code>$arg1</code> that precedes in
            the value of <code>$arg1</code> the first occurrence of a sequence of collation units
            that provides a <term>minimal match</term> to the collation units of <code>$arg2</code>
            according to the collation that is used.</p>
         <note>
            <p><term>Minimal match</term> is defined in <bibref ref="UNICODE-TR10"/>. </p>
         </note>

      </fos:rules>
      <fos:errors>
         <p>A <phrase>dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH"
               code="0004"/> if the specified collation does not support collation units.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <p>The collation used in these examples, <code>http://example.com/CollationA</code> is a
               collation in which both "-" and "*" are ignorable collation units.</p>
            <p>"Ignorable collation unit" is equivalent to "ignorable collation element" in <bibref
                  ref="UNICODE-TR10"/>.</p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring-before ( "tattoo", "attoo")</fos:expression>
               <fos:result>"t"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring-before ( "tattoo", "tatto")</fos:expression>
               <fos:result>""</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring-before ((), ())</fos:expression>
               <fos:result>""</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring-before ( "abcdefghi", "--d-e-",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>"abc"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring-before ( "abc--d-e-fghi", "--d-e-",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>"abc--"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring-before ( "a*b*c*d*e*f*g*h*i*", "***cde",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>"a*b*"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring-before ( "Eureka!", "--***-*---",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>""</fos:result>
               <fos:postamble>The second argument contains only ignorable collation units and is
                  equivalent to the zero-length string.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="substring-after" prefix="fn">
      <fos:signatures>
         <fos:proto name="substring-after" return-type="xs:string">
            <fos:arg name="arg1" type="xs:string?"/>
            <fos:arg name="arg2" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="substring-after" return-type="xs:string">
            <fos:arg name="arg1" type="xs:string?"/>
            <fos:arg name="arg2" type="xs:string?"/>
            <fos:arg name="collation" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="3">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the part of <code>$arg1</code> that follows the first occurrence of
               <code>$arg2</code>, taking collations into account.</p>
      </fos:summary>
      <fos:rules>
         <p>If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or
            contains only ignorable collation units, it is interpreted as the zero-length
            string.</p>
         <p>If the value of <code>$arg2</code> is the zero-length string, then the function returns
            the value of <code>$arg1</code>.</p>
         <p>If the value of <code>$arg1</code> does not contain a string that is equal to the value
            of <code>$arg2</code>, then the function returns the zero-length string. </p>
         <p>The collation used by this function is determined according to the rules in <specref
               ref="choosing-a-collation"/>.</p>
         <p>The function returns the substring of the value of <code>$arg1</code> that follows in
            the value of <code>$arg1</code> the first occurrence of a sequence of collation units
            that provides a <term>minimal match</term> to the collation units of <code>$arg2</code>
            according to the collation that is used. </p>
         <note>
            <p><term>Minimal match</term> is defined in <bibref ref="UNICODE-TR10"/>. </p>
         </note>

      </fos:rules>
      <fos:errors>
         <p>A dynamic error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if
            the specified collation does not support collation units.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <p>The collation used in these examples, <code>http://example.com/CollationA</code> is a
               collation in which both "-" and "*" are ignorable collation units.</p>
            <p>"Ignorable collation unit" is equivalent to "ignorable collation element" in <bibref
                  ref="UNICODE-TR10"/>.</p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring-after("tattoo", "tat")</fos:expression>
               <fos:result>"too"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring-after("tattoo", "tattoo")</fos:expression>
               <fos:result>""</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring-after((), ())</fos:expression>
               <fos:result>""</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression> fn:substring-after("abcdefghi", "--d-e-",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>"fghi"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring-after("abc--d-e-fghi", "--d-e-",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>"-fghi"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring-after ( "a*b*c*d*e*f*g*h*i*", "***cde***",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>"*f*g*h*i*"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:substring-after ( "Eureka!", "--***-*---",
                  "http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary")</fos:expression>
               <fos:result>"Eureka!"</fos:result>
               <fos:postamble>The second argument contains only ignorable collation units and is
                  equivalent to the zero-length string.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="matches" prefix="fn">
      <fos:signatures>
         <fos:proto name="matches" return-type="xs:boolean">
            <fos:arg name="input" type="xs:string?"/>
            <fos:arg name="pattern" type="xs:string"/>
         </fos:proto>
         <fos:proto name="matches" return-type="xs:boolean">
            <fos:arg name="input" type="xs:string?"/>
            <fos:arg name="pattern" type="xs:string"/>
            <fos:arg name="flags" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if the supplied string matches a given regular expression.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of calling the first version of this function (omitting the argument
               <code>$flags</code>) is the same as the effect of calling the second version with the
               <code>$flags</code> argument set to a zero-length string. Flags are defined in
               <specref ref="flags"/>.</p>
         <p>If <code>$input</code> is the empty sequence, it is interpreted as the zero-length
            string.</p>
         <p>The function returns <code>true</code> if <code>$input</code> or some substring of
               <code>$input</code> matches the regular expression supplied as <code>$pattern</code>.
            Otherwise, the function returns <code>false</code>. The matching rules are influenced by
            the value of <code>$flags</code> if present. </p>

      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="RX" code="0002"/> if the value of
               <code>$pattern</code> is invalid according to the rules described in <specref
               ref="regex-syntax"/>. </p>
         <p>A dynamic error is raised <errorref class="RX" code="0001"/> if the value of
               <code>$flags</code> is invalid according to the rules described in <specref
               ref="flags"/>. </p>
      </fos:errors>
      <fos:notes>
         <p>Unless the metacharacters <code>^</code> and <code>$</code> are used as anchors, the
            string is considered to match the pattern if any substring matches the pattern. But if
            anchors are used, the anchors must match the start/end of the string (in string mode),
            or the start/end of a line (in multi-line mode). </p>
         <p>This is different from the behavior of patterns in <bibref ref="xmlschema-2"/>, where
            regular expressions are <emph>implicitly</emph> anchored.</p>
         <p>Regular expression matching is defined on the basis of Unicode code points; it takes no
            account of collations.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:matches("abracadabra", "bra")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:matches("abracadabra", "^a.*a$")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:matches("abracadabra", "^bra")</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>Given the source document:</p>
         </fos:example>
         <fos:variable name="poem" id="v-matches-poem" as="element()"><![CDATA[
<poem author="Wilhelm Busch">
Kaum hat dies der Hahn gesehen,
Fängt er auch schon an zu krähen:
Kikeriki! Kikikerikih!!
Tak, tak, tak! - da kommen sie.
</poem>]]></fos:variable>
         <fos:example>
            <p>the following function calls produce the following results, with the
                  <code>poem</code> element as the context node:</p>
         </fos:example>
         <fos:example>
            <fos:test use="v-matches-poem">
               <fos:expression>fn:matches($poem, "Kaum.*krähen")</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-matches-poem">
               <fos:expression>fn:matches($poem, "Kaum.*krähen", "s")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-matches-poem">
               <fos:expression>fn:matches($poem, "^Kaum.*gesehen,$", "m")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-matches-poem">
               <fos:expression>fn:matches($poem, "^Kaum.*gesehen,$")</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-matches-poem">
               <fos:expression>fn:matches($poem, "kiki", "i")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="replace" prefix="fn">
      <fos:signatures>
         <fos:proto name="replace" return-type="xs:string">
            <fos:arg name="input" type="xs:string?"/>
            <fos:arg name="pattern" type="xs:string"/>
            <fos:arg name="replacement" type="xs:string"/>
         </fos:proto>
         <fos:proto name="replace" return-type="xs:string">
            <fos:arg name="input" type="xs:string?"/>
            <fos:arg name="pattern" type="xs:string"/>
            <fos:arg name="replacement" type="xs:string"/>
            <fos:arg name="flags" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a string produced from the input string by replacing any substrings that match a
            given regular expression with a supplied replacement string.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of calling the first version of this function (omitting the argument
               <code>$flags</code>) is the same as the effect of calling the second version with the
               <code>$flags</code> argument set to a zero-length string. Flags are defined in
               <specref ref="flags"/>.</p>
         <p>The <code>$flags</code> argument is interpreted in the same manner as for the
               <code>fn:matches</code> function. </p>
         <p>If <code>$input</code> is the empty sequence, it is interpreted as the zero-length
            string.</p>
         <p>The function returns the <code>xs:string</code> that is obtained by replacing each
            non-overlapping substring of <code>$input</code> that matches the given
               <code>$pattern</code> with an occurrence of the <code>$replacement</code> string.</p>
         <p>If two overlapping substrings of <code>$input</code> both match the
               <code>$pattern</code>, then only the first one (that is, the one whose first <termref
               def="character">character</termref> comes first in the <code>$input</code> string) is
            replaced.</p>
         <p>If the <code>q</code> flag is present, the replacement string is used <emph>as
            is</emph>.</p>
         <p>Otherwise, within the <code>$replacement</code> string, a variable <code>$N</code> may
            be used to refer to the substring captured by the Nth parenthesized sub-expression in
            the regular expression. For each match of the pattern, these variables are assigned the
            value of the content matched by the relevant sub-expression, and the modified
            replacement string is then substituted for the <termref def="character"
               >characters</termref> in <code>$input</code> that matched the pattern.
               <code>$0</code> refers to the substring captured by the regular expression as a
            whole.</p>
         <p>More specifically, the rules are as follows, where <code>S</code> is the number of
            parenthesized sub-expressions in the regular expression, and <code>N</code> is the
            decimal number formed by taking all the digits that consecutively follow the
               <code>$</code> character:</p>

         <olist>
            <item>
               <p>If <code>N</code>=<code>0</code>, then the variable is replaced by the substring
                  matched by the regular expression as a whole.</p>
            </item>
            <item>
               <p>If <code>1</code>&lt;=<code>N</code>&lt;=<code>S</code>, then the variable is
                  replaced by the substring captured by the Nth parenthesized sub-expression. If the
                     <code>Nth</code> parenthesized sub-expression was not matched, then the
                  variable is replaced by the zero-length string.</p>
            </item>
            <item>
               <p>If <code>S</code>&lt;<code>N</code>&lt;=<code>9</code>, then the variable is
                  replaced by the zero-length string.</p>
            </item>
            <item>
               <p>Otherwise (if <code>N</code>&gt;<code>S</code> and
                     <code>N</code>&gt;<code>9</code>), the last digit of <code>N</code> is taken to
                  be a literal character to be included "as is" in the replacement string, and the
                  rules are reapplied using the number <code>N</code> formed by stripping off this
                  last digit.</p>
            </item>
         </olist>

         <p>For example, if the replacement string is 
               <code>"$23"</code>
             and there are 5 substrings, the result contains the value of the substring that
            matches the second sub-expression, followed by the digit 
               <code>3</code>.</p>
         <p>Unless the <code>q</code> flag is used, a literal <code>$</code> character within the
            replacement string must be written as <code>\$</code>, and a literal <code>\</code>
            character must be written as <code>\\</code>.</p>

         <p> If two alternatives within the pattern both match at the same position in the
               <code>$input</code>, then the match that is chosen is the one matched by the first
            alternative. For example:</p>
         <eg xml:space="preserve"> fn:replace("abcd", "(ab)|(a)", "[1=$1][2=$2]") returns "[1=ab][2=]cd"</eg>

      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="RX" code="0002"/> if the value of
               <code>$pattern</code> is invalid according to the rules described in section <specref
               ref="regex-syntax"/>. </p>
         <p>A dynamic error is raised <errorref class="RX" code="0001"/> if the value of
               <code>$flags</code> is invalid according to the rules described in section <specref
               ref="flags"/>. </p>
         <p>A dynamic error is raised <errorref class="RX" code="0003"/> if the pattern matches a
            zero-length string, that is, if the expression <code>fn:matches("", $pattern,
               $flags)</code> returns <code>true</code>. It is not an error, however, if a captured
            substring is zero-length.</p>
         <p><phrase diff="add" at="E">In the absence of the <code>q</code> flag,</phrase>
            a dynamic error is raised <errorref class="RX" code="0004"/> if the value of
               <code>$replacement</code> contains a dollar sign (<code>$</code>) character that is not
            immediately followed by a digit <code>0-9</code> and not immediately preceded by a
            backslash (<code>\</code>).</p>
         <p><phrase diff="add" at="E">In the absence of the <code>q</code> flag,</phrase>
            a dynamic error is raised <errorref class="RX" code="0004"/> if the value of
               <code>$replacement</code> contains a backslash (<code>\</code>) character that is not part of a
               <code>\\</code> pair, unless it is immediately followed by a dollar sign (<code>$</code>)
            character.</p>
      </fos:errors>
      <fos:notes>
         <p><!--bug 10261-->If the input string contains no substring that matches the regular
            expression, the result of the function is a single string identical to the input
            string.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:replace("abracadabra", "bra", "*")</fos:expression>
               <fos:result>"a*cada*"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:replace("abracadabra", "a.*a", "*")</fos:expression>
               <fos:result>"*"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:replace("abracadabra", "a.*?a", "*")</fos:expression>
               <fos:result>"*c*bra"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:replace("abracadabra", "a", "")</fos:expression>
               <fos:result>"brcdbr"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:replace("abracadabra", "a(.)", "a$1$1")</fos:expression>
               <fos:result>"abbraccaddabbra"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>The expression <code>fn:replace("abracadabra", ".*?", "$1")</code> raises an error,
               because the pattern matches the zero-length string </p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:replace("AAAA", "A+", "b")</fos:expression>
               <fos:result>"b"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:replace("AAAA", "A+?", "b")</fos:expression>
               <fos:result>"bbbb"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:replace("darted", "^(.*?)d(.*)$", "$1c$2")</fos:expression>
               <fos:result>"carted"</fos:result>
               <fos:postamble>The first <code>d</code> is replaced.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="tokenize" prefix="fn">
      <fos:signatures>
         <fos:proto name="tokenize" return-type="xs:string*">
            <fos:arg name="input" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="tokenize" return-type="xs:string*">
            <fos:arg name="input" type="xs:string?"/>
            <fos:arg name="pattern" type="xs:string"/>
         </fos:proto>
         <fos:proto name="tokenize" return-type="xs:string*">
            <fos:arg name="input" type="xs:string?"/>
            <fos:arg name="pattern" type="xs:string"/>
            <fos:arg name="flags" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a sequence of strings constructed by splitting the input wherever a separator is
            found; the separator is any substring that matches a given regular expression.</p>
      </fos:summary>
      <fos:rules>
         <p diff="add" at="B">The one-argument form of this function
         splits the supplied string at whitespace boundaries. More specifically, calling <code>fn:tokenize($input)</code>
         is equivalent to calling <code>fn:tokenize(fn:normalize-space($input), ' '))</code> where the second argument
         is a single space character (x20).</p>
         <p>The effect of calling the two-argument form of this function (omitting the argument
               <code>$flags</code>) is the same as the effect of calling the three-argument version with the
               <code>$flags</code> argument set to a zero-length string. Flags are defined in
               <specref ref="flags"/>.</p>
         <p>The following rules apply to the three-argument form of the function:</p>
         <ulist><item><p>The <code>$flags</code> argument is interpreted in the same way as for the
               <code>fn:matches</code> function.</p></item>
         <item><p>If <code>$input</code> is the empty sequence, or if <code>$input</code> is the
            zero-length string, the function returns the empty sequence.</p></item>

         <item><p>The function returns a sequence of strings formed by breaking the <code>$input</code>
            string into a sequence of strings, treating any substring that matches
               <code>$pattern</code> as a separator. The separators themselves are not returned.</p></item>
         <item><p><phrase diff="chg" at="B">Except with the one-argument form of the function,</phrase>
            if a separator occurs at the start of the <code>$input</code> string, the result
            sequence will start with a zero-length string. Similarly, zero-length strings will also occur in
            the result sequence if a separator occurs at the end of the <code>$input</code> string,
            or if two adjacent substrings match the supplied <code>$pattern</code>.</p></item>
         <item><p>If two alternatives within the supplied <code>$pattern</code> both match at the same
            position in the <code>$input</code> string, then the match that is chosen is the first.
            For example:</p>
         <eg xml:space="preserve"> fn:tokenize("abracadabra", "(ab)|(a)") returns ("", "r", "c", "d", "r", "")</eg></item>
         </ulist>

      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="RX" code="0002"/> if the value of
               <code>$pattern</code> is invalid according to the rules described in section <specref
               ref="regex-syntax"/>.</p>
         <p>A dynamic error is raised <errorref class="RX" code="0001"/> if the value of
               <code>$flags</code> is invalid according to the rules described in section <specref
               ref="flags"/>.</p>
         <p>A dynamic error is raised <errorref class="RX" code="0003"/> if the supplied
               <code>$pattern</code> matches a zero-length string, that is, if <code>fn:matches("",
               $pattern, $flags)</code> returns <code>true</code>. </p>

      </fos:errors>
      <fos:notes>
         <p><!--bug 10261-->If the input string is not zero length, and no separators are found in
            the input string, the result of the function is a single string identical to the input
            string.</p>
         <p diff="add" at="B">The one-argument form of the function has a similar effect to
         the two-argument form with <code>\s+</code> as the separator pattern, except that the one-argument
         form strips leading and trailing whitespace, whereas the two-argument form delivers an extra
         zero-length token if leading or trailing whitespace is present.</p>
         <p diff="add" at="B">The function returns no information about the separators that were found
         in the string. If this information is required, the <code>fn:analyze-string</code> function
         can be used instead.</p>
         <p diff="add" at="B">The separator used by the one-argument form of the function is any sequence
            of tab (x09), newline (x0A), carriage return (x0D) or space (x20) characters. This is the same as the
         separator recognized by list-valued attributes as defined in XSD. It is not the same as the separator
         recognized by list-valued attributes in HTML5, which also treats form-feed (x0C) as whitespace.
         If it is necessary to treat form-feed as a separator, an explicit separator pattern should be used.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:tokenize(" red green blue ")</fos:expression>
               <fos:result>("red", "green", "blue")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:tokenize("The cat sat on the mat", "\s+")</fos:expression>
               <fos:result>("The", "cat", "sat", "on", "the", "mat")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:tokenize(" red green blue ", "\s+")</fos:expression>
               <fos:result>("", "red", "green", "blue", "")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:tokenize("1, 15, 24, 50", ",\s*")</fos:expression>
               <fos:result>("1", "15", "24", "50")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:tokenize("1,15,,24,50,", ",")</fos:expression>
               <fos:result>("1", "15", "", "24", "50", "")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p><code>fn:tokenize("abba", ".?")</code> raises the dynamic error <errorref class="RX"
                  code="0003"/>.</p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:tokenize("Some unparsed &lt;br&gt; HTML &lt;BR&gt; text",
                  "\s*&lt;br&gt;\s*", "i")</fos:expression>
               <fos:result>("Some unparsed", "HTML", "text")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="analyze-string" prefix="fn">
      <fos:signatures>
         <fos:proto name="analyze-string" return-type="element(fn:analyze-string-result)">
            <fos:arg name="input" type="xs:string?"/>
            <fos:arg name="pattern" type="xs:string"/>
         </fos:proto>
         <fos:proto name="analyze-string" return-type="element(fn:analyze-string-result)">
            <fos:arg name="input" type="xs:string?"/>
            <fos:arg name="pattern" type="xs:string"/>
            <fos:arg name="flags" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>nondeterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Analyzes a string using a regular expression, returning an XML structure that identifies
            which parts of the input string matched or failed to match the regular expression, and
            in the case of matched substrings, which substrings matched each capturing group in the
            regular expression.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of calling the first version of this function (omitting the argument
               <code>$flags</code>) is the same as the effect of calling the second version with the
               <code>$flags</code> argument set to a zero-length string. Flags are defined in
               <specref ref="flags"/>.</p>
         <p>The <code>$flags</code> argument is interpreted in the same way as for the
               <code>fn:matches</code> function.</p>
         <p>If <code>$input</code> is the empty sequence the function behaves as if
               <code>$input</code> were the zero-length string. In this situation the result will be
            an element node with no children.</p>
         <p>The function returns an element node whose local name is
               <code>analyze-string-result</code>. This element and all its descendant elements have
            the namespace URI <code>http://www.w3.org/2005/xpath-functions</code>. The namespace
            prefix is <termref def="implementation-dependent">implementation-dependent</termref>. The children of this element are a
            sequence of <code>fn:match</code> and <code>fn:non-match</code> elements. This sequence
            is formed by breaking the <code>$input</code> string into a sequence of strings,
            returning any substring that matches <code>$pattern</code> as the content of a
               <code>match</code> element, and any intervening substring as the content of a
               <code>non-match</code> element.</p>
         <p>More specifically, the function starts at the beginning of the input string and attempts
            to find the first substring that matches the regular expression. If there are several
            matches, the first match is defined to be the one whose starting position comes first in
            the string. If several alternatives within the regular expression both match at the same
            position in the input string, then the match that is chosen is the first alternative
            that matches. For example, if the input string is <code>The quick brown fox jumps</code>
            and the regular expression is <code>jump|jumps</code>, then the match that is chosen is
               <code>jump</code>.</p>

         <p>Having found the first match, the instruction proceeds to find the second and subsequent
            matches by repeating the search, starting at the first <termref def="character"
               >character</termref> that was not included in the previous match.</p>

         <p>The input string is thus partitioned into a sequence of substrings, some of which match
            the regular expression, others which do not match it. Each substring will contain at
            least one character. This sequence is represented in the result by the sequence of
               <code>fn:match</code> and <code>fn:non-match</code> children of the returned element
            node; the string value of the <code>fn:match</code> or <code>fn:non-match</code> element
            will be the corresponding substring of <code>$input</code>, and the string value of the
            returned element node will therefore be the same as <code>$input</code>.</p>

         <p>The content of an <code>fn:non-match</code> element is always a single text node.</p>

         <p>The content of a <code>fn:match</code> element, however, is in general a sequence of
            text nodes and <code>fn:group</code> element children. An <code>fn:group</code> element
            with a <code>nr</code> attribute having the integer value <var>N</var> identifies the
            substring captured by the <var>Nth</var> parenthesized sub-expression in the regular
            expression. For each capturing subexpression there will be at most one corresponding
               <code>fn:group</code> element in each <code>fn:match</code> element in the
            result.</p>

         <p>If the function is called twice with the same arguments, it is <termref
            def="implementation-dependent">implementation-dependent</termref> whether the two calls return the same element node
            or distinct (but deep equal) element nodes. In this respect it is <termref
               def="nondeterministic">non-deterministic with respect to node identity</termref>.</p>

         <p>The base URI of the element nodes in the result is <termref
            def="implementation-dependent">implementation-dependent</termref>.</p>

         <p>A schema is defined for the structure of the returned element: see <specref ref="schema-for-analyze-string"/>.</p>
         
         <p diff="chg" at="D">The result of the function will always be such that validation against this schema would succeed.
         However, it is <termref def="dt-implementation-defined">implementation-defined</termref> whether the result is typed or untyped,
         that is, whether the elements and attributes in the returned tree have type annotations that reflect
         the result of validating against this schema.</p>
         
         
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="RX" code="0002"/> if the value of
               <code>$pattern</code> is invalid according to the rules described in section <specref
               ref="regex-syntax"/>.</p>
         <p>A dynamic error is raised <errorref class="RX" code="0001"/> if the value of
               <code>$flags</code> is invalid according to the rules described in section <specref
               ref="flags"/>.</p>
         <p>A dynamic error is raised <errorref class="RX" code="0003"/> if the supplied
               <code>$pattern</code> matches a zero-length string, that is, if <code>fn:matches("",
               $pattern, $flags)</code> returns <code>true</code>.</p>
      </fos:errors>
      <fos:notes>
         <p>It is <rfc2119>recommended</rfc2119> that a processor that implements schema awareness should return typed nodes.
            The concept of "schema awareness", however, is a matter for host languages to define and is outside
            the scope of the function library specification.</p>
         <p>The declarations and definitions in the schema are not automatically available in
            the static context of the <code>fn:analyze-string</code> call (or of any other
            expression). The contents of the static context are host-language defined, and in some
            host languages are implementation-defined.</p>
         <p diff="add" at="E">The schema defines the outermost element, <code>analyze-string-result</code>, in such
         a way that mixed content is permitted. In fact the element will only have element nodes (<code>match</code>
         and <code>non-match</code>) as its children, never text nodes. Although this might have originally been an
            oversight, defining the <code>analyze-string-result</code> element with <code>mixed="true"</code> allows it
         to be atomized, which is potentially useful (the atomized value will be the original input string),
         and the capability has therefore been retained for compatibility with the 3.0 version of this
         specification.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p>In the following examples, the result document is shown in serialized form, with
               whitespace between the element nodes. This whitespace is not actually present in the
               result.</p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:analyze-string("The cat sat on the mat.", "\w+")</fos:expression>
               <fos:result normalize-space="true" ignore-prefixes="true" as="element()"><![CDATA[
<analyze-string-result xmlns="http://www.w3.org/2005/xpath-functions">
  <match>The</match>
  <non-match> </non-match>
  <match>cat</match>
  <non-match> </non-match>
  <match>sat</match>
  <non-match> </non-match>
  <match>on</match>
  <non-match> </non-match>
  <match>the</match>
  <non-match> </non-match>
  <match>mat</match>
  <non-match>.</non-match>
</analyze-string-result>]]></fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:analyze-string("2008-12-03",
                  "^(\d+)\-(\d+)\-(\d+)$")</fos:expression>
               <fos:result normalize-space="true" ignore-prefixes="true" as="element()"><![CDATA[
<analyze-string-result xmlns="http://www.w3.org/2005/xpath-functions">
  <match><group nr="1">2008</group>-<group nr="2"
          >12</group>-<group nr="3">03</group></match>
</analyze-string-result>]]></fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:analyze-string("A1,C15,,D24, X50,",
                  "([A-Z])([0-9]+)")</fos:expression>
               <fos:result normalize-space="true" ignore-prefixes="true" as="element()"><![CDATA[
<analyze-string-result xmlns="http://www.w3.org/2005/xpath-functions">                  
  <match><group nr="1">A</group><group nr="2">1</group></match>
  <non-match>,</non-match>
  <match><group nr="1">C</group><group nr="2">15</group></match>
  <non-match>,,</non-match>
  <match><group nr="1">D</group><group nr="2">24</group></match>
  <non-match>, </non-match>
  <match><group nr="1">X</group><group nr="2">50</group></match>
  <non-match>,</non-match>
</analyze-string-result>]]></fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="contains-token" prefix="fn">
      <fos:signatures>
         <fos:proto name="contains-token" return-type="xs:boolean">
            <fos:arg name="input" type="xs:string*"/>
            <fos:arg name="token" type="xs:string"/>
         </fos:proto>
         <fos:proto name="contains-token" return-type="xs:boolean">
            <fos:arg name="input" type="xs:string*"/>
            <fos:arg name="token" type="xs:string"/>
            <fos:arg name="collation" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="3">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Determines whether or not any of the supplied strings, when tokenized at whitespace boundaries, contains the supplied token,
            under the rules of the supplied collation.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$input</code> is the empty sequence, the function returns <code>false</code>.</p>
         <p>Leading and trailing whitespace is trimmed from the supplied value of <code>$token</code>. If the trimmed value of <code>$token</code>
            is a zero-length string, the function returns <code>false</code>.</p>
         <p>The collation used by this function is determined according to the rules in <specref
            ref="choosing-a-collation"/>.</p>
         <p>The function returns true if and only if there is string in <code>$input</code> which, 
            after tokenizing at whitespace boundaries, contains a token
         that is equal to the trimmed value of <code>$token</code> under
         the rules of the selected collation.</p>
         <p>That is, the function returns the value of the expression:</p>
         <eg><![CDATA[some $t in $input!fn:tokenize(.) satisfies 
                 compare($t, fn:replace($token, '^\s*|\s*$', ''), $collation) eq 0)]]></eg>
      </fos:rules>
      <fos:notes>
         <p>Interior whitespace within <code>$token</code> will cause the function to return <code>false</code>,
         unless such whitespace is ignored by the selected collation.</p>
         <p>This function can be used for processing space-separated attribute values
            (for example, the XHTML and DITA class attribute),
            where one often needs to test for the presence
            of a single token in a space-separated list. The function is designed to work
            both when the attribute has been validated against an XSD list type, and when it
            appears as a single untyped string. It differs from the
            HTML 5 definition in that HTML 5 recognizes form feed (x0C) as a separator.
            To reproduce the HTML token matching behavior, the HTML ASCII case-insensitive collation
            should be used: see <specref ref="html-ascii-case-insensitive-collation"/>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:contains-token("red green blue ", "red")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:contains-token(("red", "green", "blue"), " red ")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:contains-token("red, green, blue", "red")</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:contains-token("red green blue", "RED", "http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="resolve-uri" prefix="fn">
      <fos:signatures>
         <fos:proto name="resolve-uri" return-type="xs:anyURI?">
            <fos:arg name="relative" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="resolve-uri" return-type="xs:anyURI?">
            <fos:arg name="relative" type="xs:string?"/>
            <fos:arg name="base" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Resolves a relative IRI reference against an absolute IRI.</p>
      </fos:summary>
      <fos:rules>
         

         <p>The function is defined to operate on IRI references as defined in <bibref ref="rfc3987"
            />, and the implementation <rfc2119>must</rfc2119> permit all arguments that are valid
            according to that specification. In addition, the implementation <rfc2119>may</rfc2119>
            accept some or all strings that conform to the rules for (absolute or relative) Legacy
            Extended IRI references as defined in <bibref ref="LEIRI"/>. For the purposes of this
            section, the terms IRI and IRI reference include these extensions, insofar as the
            implementation chooses to support them.</p>
         
         <p>The following rules apply in order:</p>
         
         <olist diff="chg" at="B">
            <item><p>If <code>$relative</code> is the empty sequence, the function returns the empty
               sequence.</p></item>
            <item><p>If <code>$relative</code> is an absolute IRI (as defined above), then it is returned
               unchanged.</p></item>
            <item><p>If the <code>$base</code> argument is not supplied, then:</p>
            <olist>
               <item><p>If the static base URI in the static context is not absent, it is used as the effective
               value of <code>$base</code>.</p></item>
               <item><p>Otherwise, a dynamic error is raised: <phrase diff="chg" at="D"><errorref class="NS" code="0005"/></phrase>.</p></item>
            </olist>
            </item>
            <item><p>The function resolves the relative IRI reference <code>$relative</code>
               against the base IRI <code>$base</code> using the algorithm defined in <bibref
                  ref="rfc3986"/>, adapted by treating any <termref def="character">character</termref>
               that would not be valid in an RFC3986 URI or relative reference in the same way that
               RFC3986 treats unreserved characters. No percent-encoding takes place.</p></item>
         </olist>

         

         

         



      </fos:rules>
      <fos:errors>
         <p>The first form of this function resolves <code>$relative</code> against the value of the
            base-uri property from the static context. A dynamic error is raised <errorref
               class="NS" code="0005"/> if the base-uri property is not initialized in the static
            context. </p>
         <p>A dynamic error is raised <errorref class="RG" code="0002"/> if <code>$relative</code>
            is not a valid IRI according to the rules of RFC3987, extended with an
            implementation-defined subset of the extensions permitted in LEIRI, or if it is not a
            suitable relative reference to use as input to the RFC3986 resolution algorithm extended
            to handle additional unreserved characters. </p>
         <p>A dynamic error is raised <errorref class="RG" code="0002"/> if <code>$base</code> is
            not a valid IRI according to the rules of RFC3987, extended with an
            implementation-defined subset of the extensions permitted in LEIRI, or if it is not a
            suitable IRI to use as input to the chosen resolution algorithm (for example, if it is a
            relative IRI reference, if it is a non-hierarchic URI, or if it contains a fragment
            identifier). </p>
         <p>A dynamic error is raised <errorref class="RG" code="0009"/> if the chosen resolution
            algorithm fails for any other reason. </p>
      </fos:errors>
      <fos:notes>
         <p>Resolving a URI does not dereference it. This is merely a syntactic operation on two
               <termref def="string">strings</termref>.</p>
         <p>The algorithms in the cited RFCs include some variations that are optional or
            recommended rather than mandatory; they also describe some common practices that are not
            recommended, but which are permitted for backwards compatibility. Where the cited RFCs
            permit variations in behavior, so does this specification. </p>
         <p>Throughout this family of specifications, the phrase "resolving a relative URI (or IRI)
            reference" should be understood as using the rules of this function, unless otherwise
            stated.</p>
         <p diff="add" at="D">RFC3986 defines an algorithm for resolving relative references 
            in the context of the URI syntax defined in that RFC. RFC3987 describes a modification 
            to that algorithm to make it applicable to IRIs (specifically: additional characters 
            permitted in an IRI are handled the same way that RFC3986 handles unreserved characters). 
            The LEIRI specification does not explicitly define a resolution algorithm, but suggests 
            that it <emph>should not</emph> be done by converting the LEIRI to a URI, and 
            <emph>should not</emph> involve percent-encoding. This specification fills this gap 
            by defining resolution for LEIRIs in the same way that RFC3987 defines resolution for IRIs,
            that is by specifying that additional characters are handled as unreserved characters.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="true" prefix="fn">
      <fos:signatures>
         <fos:proto name="true" return-type="xs:boolean"/>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the <code>xs:boolean</code> value <code>true</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>The result is equivalent to <code>xs:boolean("1")</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:true()</fos:expression>
               <fos:result>xs:boolean(1)</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="false" prefix="fn">
      <fos:signatures>
         <fos:proto name="false" return-type="xs:boolean"/>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the <code>xs:boolean</code> value <code>false</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>The result is equivalent to <code>xs:boolean("0")</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:false()</fos:expression>
               <fos:result>xs:boolean(0)</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="boolean-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="boolean-equal" return-type="xs:boolean">
            <fos:arg name="value1" type="xs:boolean"/>
            <fos:arg name="value2" type="xs:boolean"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="eq" types="xs:boolean numeric">Defines the semantics of the "eq"
         operator when applied to two <code>xs:boolean</code> values.</fos:opermap>
      <fos:summary>
         <p>Returns <code>true</code> if the two arguments are the same boolean value.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns <code>true</code> if both arguments are <code>true</code> or if
            both arguments are <code>false</code>. It returns <code>false</code> if one of the
            arguments is <code>true</code> and the other argument is <code>false</code>. </p>
      </fos:rules>
   </fos:function>
   <fos:function name="boolean-less-than" prefix="op">
      <fos:signatures>
         <fos:proto name="boolean-less-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:boolean"/>
            <fos:arg name="arg2" type="xs:boolean"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="lt" types="xs:boolean numeric" other-operators="ge">Defines the
         semantics of the "lt" operator when applied to two <code>xs:boolean</code> values. Also
         used in the definition of the "ge" operator.</fos:opermap>
      <fos:summary>
         <p>Returns true if the first argument is false and the second is true.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns <code>true</code> if <code>$arg1</code> is <code>false</code> and
               <code>$arg2</code> is <code>true</code>. Otherwise, it returns
            <code>false</code>.</p>
      </fos:rules>
   </fos:function>
   <fos:function name="boolean-greater-than" prefix="op">
      <fos:signatures>
         <fos:proto name="boolean-greater-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:boolean"/>
            <fos:arg name="arg2" type="xs:boolean"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="gt" types="xs:boolean numeric" other-operators="le">Defines the
         semantics of the "gt" operator when applied to two <code>xs:boolean</code> values. Also
         used in the definition of the "le" operator.</fos:opermap>
      <fos:summary>
         <p>Returns true if the first argument is true and the second is false.</p>
      </fos:summary>
      <fos:rules>
         <p>The function call <code>op:boolean-greater-than($A, $B)</code> is defined to return the
            same result as <code>op:boolean-less-than($B, $A)</code></p>
      </fos:rules>
   </fos:function>
   <fos:function name="boolean" prefix="fn">
      <fos:signatures>
         <fos:proto name="boolean" return-type="xs:boolean">
            <fos:arg name="arg" type="item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:summary>
         <p>Computes the effective boolean value of the sequence <code>$arg</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>The function computes the effective boolean value of a sequence, defined according to
            the following rules. See also <xspecref spec="XP31" ref="id-ebv"/>.</p>
         <ulist>
            <item>
               <p>If <code>$arg</code> is the empty sequence, <code>fn:boolean</code> returns
                     <code>false</code>.</p>
            </item>
            <item>
               <p>If <code>$arg</code> is a sequence whose first item is a node,
                     <code>fn:boolean</code> returns <code>true</code>.</p>
            </item>
            <item>
               <p>If <code>$arg</code> is a singleton value of type <code>xs:boolean</code> or a
                  derived from <code>xs:boolean</code>, <code>fn:boolean</code> returns
                     <code>$arg</code>.</p>
            </item>
            <item>
               <p>If <code>$arg</code> is a singleton value of type <code>xs:string</code> or a type
                  derived from <code>xs:string</code>, <code>xs:anyURI</code> or a type derived from
                     <code>xs:anyURI</code>, or <code>xs:untypedAtomic</code>,
                     <code>fn:boolean</code> returns <code>false</code> if the operand value has
                  zero length; otherwise it returns <code>true</code>.</p>
            </item>
            <item>
               <p>If <code>$arg</code> is a singleton value of any numeric type or a type derived
                  from a numeric type, <code>fn:boolean</code> returns <code>false</code> if the
                  operand value is <code>NaN</code> or is numerically equal to zero; otherwise it
                  returns <code>true</code>.</p>
            </item>
         </ulist>
      </fos:rules>
      <fos:errors>
         <p>In all cases other than those listed above, <code>fn:boolean</code> raises a type error <errorref
            class="RG" code="0006"/>.</p>
      </fos:errors>
      <fos:notes>
         <p>The result of this function is not necessarily the same as <code>$arg cast as
               xs:boolean</code>. For example, <code>fn:boolean("false")</code> returns the value
               <code>true</code> whereas <code>"false" cast as xs:boolean</code> (which can also be
            written <code>xs:boolean("false")</code>) returns <code>false</code>.</p>
      </fos:notes>
      <fos:examples>
         <fos:variable name="abc" id="v-boolean-abc" select="(&quot;a&quot;, &quot;b&quot;, &quot;&quot;)"/>
         <fos:example>
            <p><code>fn:boolean($abc)</code> raises a type error <errorref class="RG" code="0006"
               />.</p>
         </fos:example>
         <fos:example>
            <fos:test use="v-boolean-abc">
               <fos:expression>fn:boolean($abc[1])</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-boolean-abc">
               <fos:expression>fn:boolean($abc[0])</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-boolean-abc">
               <fos:expression>fn:boolean($abc[3])</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p><code>fn:boolean([])</code> raises a type error <errorref class="RG" code="0006"
               />.</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="not" prefix="fn">
      <fos:signatures>
         <fos:proto name="not" return-type="xs:boolean">
            <fos:arg name="arg" type="item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns <code>true</code> if the effective boolean value of <code>$arg</code> is
               <code>false</code>, or <code>false</code> if it is <code>true</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>The value of <code>$arg</code> is first reduced to an effective boolean value by
            applying the <code>fn:boolean()</code> function. The function returns <code>true</code>
            if the effective boolean value is <code>false</code>, or <code>false</code> if the
            effective boolean value is <code>true</code>. </p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:not(fn:true())</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:not(())</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:not("false")</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p><code>fn:not(1 to 10)</code> raises a type error <errorref class="RG" code="0006"/>.</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="yearMonthDuration-less-than" prefix="op">
      <fos:signatures>
         <fos:proto name="yearMonthDuration-less-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:yearMonthDuration"/>
            <fos:arg name="arg2" type="xs:yearMonthDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="lt" types="xs:yearMonthDuration numeric" other-operators="ge">Defines
         the semantics of the "lt" operator when applied to two <code>xs:yearMonthDuration</code>
         values. Also used in the definition of the "ge" operator.</fos:opermap>
      <fos:summary>
         <p>Returns true if <code>$arg1</code> is a shorter duration than <code>$arg2</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If the number of months in the value of <code>$arg1</code> is numerically less than the
            number of months in the value of <code>$arg2</code>, the function returns true.</p>
         <p>Otherwise, the function returns false.</p>
      </fos:rules>
      <fos:notes>
         <p>Either or both durations may be negative.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="yearMonthDuration-greater-than" prefix="op">
      <fos:signatures>
         <fos:proto name="yearMonthDuration-greater-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:yearMonthDuration"/>
            <fos:arg name="arg2" type="xs:yearMonthDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="gt" types="xs:yearMonthDuration numeric" other-operators="le">Defines
         the semantics of the "gt" operator when applied to two <code>xs:yearMonthDuration</code>
         values. Also used in the definition of the "le" operator.</fos:opermap>
      <fos:summary>
         <p>Returns true if <code>$arg1</code> is a longer duration than <code>$arg2</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>The function call <code>op:yearMonthDuration-greater-than($A, $B)</code> is defined to
            return the same result as <code>op:yearMonthDuration-less-than($B, $A)</code></p>
      </fos:rules>
   </fos:function>
   <fos:function name="dayTimeDuration-less-than" prefix="op">
      <fos:signatures>
         <fos:proto name="dayTimeDuration-less-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:dayTimeDuration"/>
            <fos:arg name="arg2" type="xs:dayTimeDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="lt" types="xs:dayTimeDuration numeric" other-operators="ge">Defines the
         semantics of the "lt" operator when applied to two <code>xs:dayTimeDuration</code> values.
         Also used in the definition of the "ge" operator.</fos:opermap>
      <fos:summary>
         <p>Returns true if <code>$arg1</code> is a shorter duration than <code>$arg2</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If the number of seconds in the value of <code>$arg1</code> is numerically less than the
            number of seconds in the value of <code>$arg2</code>, the function returns true.</p>
         <p>Otherwise, the function returns false.</p>
      </fos:rules>
      <fos:notes>
         <p>Either or both durations may be negative</p>
      </fos:notes>
   </fos:function>
   <fos:function name="dayTimeDuration-greater-than" prefix="op">
      <fos:signatures>
         <fos:proto name="dayTimeDuration-greater-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:dayTimeDuration"/>
            <fos:arg name="arg2" type="xs:dayTimeDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="gt" types="xs:dayTimeDuration numeric" other-operators="le">Defines the
         semantics of the "gt" operator when applied to two <code>xs:dayTimeDuration</code> values.
         Also used in the definition of the "le" operator.</fos:opermap>
      <fos:summary>
         <p>Returns true if <code>$arg1</code> is a longer duration than <code>$arg2</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>The function call <code>op:dayTimeDuration-greater-than($A, $B)</code> is defined to
            return the same result as <code>op:dayTimeDuration-less-than($B, $A)</code></p>
      </fos:rules>
   </fos:function>
   <fos:function name="duration-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="duration-equal" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:duration"/>
            <fos:arg name="arg2" type="xs:duration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="eq" types="xs:duration numeric" other-operators="ne">Defines the
         semantics of the "eq" operators when applied to two <code>xs:duration</code> values. Also
         used in the definition of the "ne" operator.</fos:opermap>
      <fos:summary>
         <p>Returns true if <code>$arg1</code> and <code>$arg2</code> are durations of the same
            length.</p>
      </fos:summary>
      <fos:rules>
         <p>If the <code>xs:yearMonthDuration</code> components of <code>$arg1</code> and
               <code>$arg2</code> are equal and the <code>xs:dayTimeDuration</code> components of
               <code>$arg1</code> and <code>$arg2</code> are equal, the function returns
               <code>true</code>.</p>
         <p>Otherwise, the function returns false.</p>
         <p>The semantics of this function are:</p>
         <eg xml:space="preserve">
xs:yearMonthDuration($arg1) div xs:yearMonthDuration('P1M')  eq
xs:yearMonthDuration($arg2) div xs:yearMonthDuration('P1M')
    and
xs:dayTimeDuration($arg1) div xs:dayTimeDuration('PT1S')  eq
xs:dayTimeDuration($arg2) div xs:dayTimeDuration('PT1S')
</eg>
         <p>that is, the function returns <code>true</code> if the months and seconds values of the
            two durations are equal.</p>
      </fos:rules>
      <fos:notes>
         <p>Note that this function, like any other, may be applied to arguments that are derived
            from the types given in the function signature, including the two subtypes
               <code>xs:dayTimeDuration</code> and <code>xs:yearMonthDuration</code>. With the
            exception of the zero-length duration, no instance of <code>xs:dayTimeDuration</code>
            can ever be equal to an instance of <code>xs:yearMonthDuration</code>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:duration-equal(xs:duration("P1Y"),
                  xs:duration("P12M"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:duration-equal(xs:duration("PT24H"),
                  xs:duration("P1D"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:duration-equal(xs:duration("P1Y"),
                  xs:duration("P365D"))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:duration-equal(xs:yearMonthDuration("P0Y"),
                  xs:dayTimeDuration("P0D"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:duration-equal(xs:yearMonthDuration("P1Y"),
                  xs:dayTimeDuration("P365D"))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:duration-equal(xs:yearMonthDuration("P2Y"),
                  xs:yearMonthDuration("P24M"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:duration-equal(xs:dayTimeDuration("P10D"),
                  xs:dayTimeDuration("PT240H"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:duration-equal(xs:duration("P2Y0M0DT0H0M0S"),
                  xs:yearMonthDuration("P24M"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:duration-equal(xs:duration("P0Y0M10D"),
                  xs:dayTimeDuration("PT240H"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="years-from-duration" prefix="fn">
      <fos:signatures>
         <fos:proto name="years-from-duration" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:duration?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the number of years in a duration.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> representing the years
            component in the value of <code>$arg</code>. <phrase diff="chg" at="B">Given that a duration
            is a <code>($months, $seconds)</code> tuple, the result is the value of <code>($months idiv 12)</code></phrase>.</p>
         <p>If <code>$arg</code> is a negative duration then the result will be negative.</p>
         <p>If <code>$arg</code> is an <code>xs:dayTimeDuration</code> the function returns 0.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:years-from-duration(xs:yearMonthDuration("P20Y15M"))</fos:expression>
               <fos:result>21</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:years-from-duration(xs:yearMonthDuration("-P15M"))</fos:expression>
               <fos:result>-1</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:years-from-duration(xs:dayTimeDuration("-P2DT15H"))</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="months-from-duration" prefix="fn">
      <fos:signatures>
         <fos:proto name="months-from-duration" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:duration?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the number of months in a duration.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> representing the months
            component in the value of <code>$arg</code>. <phrase diff="chg" at="B">Given that a duration
               is a <code>($months, $seconds)</code> tuple, the result is the value of <code>($months mod 12)</code></phrase>.</p>
         <p>If <code>$arg</code> is a negative duration then the result will be negative.</p>
         <p>If <code>$arg</code> is an <code>xs:dayTimeDuration</code> the function returns 0.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:months-from-duration(xs:yearMonthDuration("P20Y15M"))</fos:expression>
               <fos:result>3</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:months-from-duration(xs:yearMonthDuration("-P20Y18M"))</fos:expression>
               <fos:result>-6</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:months-from-duration(xs:dayTimeDuration("-P2DT15H0M0S"))</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="days-from-duration" prefix="fn">
      <fos:signatures>
         <fos:proto name="days-from-duration" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:duration?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the number of days in a duration.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> representing the days
            component in the value of <code>$arg</code>. <phrase diff="chg" at="B">Given that a duration
               is a <code>($months, $seconds)</code> tuple, the result is the value of <code>($seconds idiv 86400)</code></phrase>.</p>
         <p>If <code>$arg</code> is a negative duration then the result will be negative.</p>
         <p>If <code>$arg</code> is an <code>xs:yearMonthDuration</code> the function returns 0.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:days-from-duration(xs:dayTimeDuration("P3DT10H"))</fos:expression>
               <fos:result>3</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:days-from-duration(xs:dayTimeDuration("P3DT55H"))</fos:expression>
               <fos:result>5</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:days-from-duration(xs:yearMonthDuration("P3Y5M"))</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="hours-from-duration" prefix="fn">
      <fos:signatures>
         <fos:proto name="hours-from-duration" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:duration?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the number of hours in a duration.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> representing the hours
            component in the value of <code>$arg</code>. <phrase diff="chg" at="B">Given that a duration
               is a <code>($months, $seconds)</code> tuple, the result is the value of <code>($seconds mod 86400) idiv 3600</code></phrase>.</p>
         <p>If <code>$arg</code> is a negative duration then the result will be negative.</p>
         <p>If <code>$arg</code> is an <code>xs:yearMonthDuration</code> the function returns 0.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-duration(xs:dayTimeDuration("P3DT10H"))</fos:expression>
               <fos:result>10</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-duration(xs:dayTimeDuration("P3DT12H32M12S"))</fos:expression>
               <fos:result>12</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-duration(xs:dayTimeDuration("PT123H"))</fos:expression>
               <fos:result>3</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-duration(xs:dayTimeDuration("-P3DT10H"))</fos:expression>
               <fos:result>-10</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="minutes-from-duration" prefix="fn">
      <fos:signatures>
         <fos:proto name="minutes-from-duration" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:duration?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the number of minutes in a duration.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> representing the minutes
            component in the value of <code>$arg</code>. <phrase diff="chg" at="B">Given that a duration
               is a <code>($months, $seconds)</code> tuple, the result is the value of <code>($seconds mod 3600) idiv 60</code></phrase>.</p>
         <p>If <code>$arg</code> is a negative duration then the result will be negative.</p>
         <p>If <code>$arg</code> is an <code>xs:yearMonthDuration</code> the function returns 0.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:minutes-from-duration(xs:dayTimeDuration("P3DT10H"))</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:minutes-from-duration(xs:dayTimeDuration("-P5DT12H30M"))</fos:expression>
               <fos:result>-30</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="seconds-from-duration" prefix="fn">
      <fos:signatures>
         <fos:proto name="seconds-from-duration" return-type="xs:decimal?">
            <fos:arg name="arg" type="xs:duration?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the number of seconds in a duration.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:decimal</code> representing the seconds
            component in the value of <code>$arg</code>. <phrase diff="chg" at="B">Given that a duration
               is a <code>($months, $seconds)</code> tuple, the result is the value of <code>($seconds mod 60)</code>
            as an <code>xs:decimal</code></phrase>.</p>
         <p>If <code>$arg</code> is a negative duration then the result will be negative.</p>
         <p>If <code>$arg</code> is an <code>xs:yearMonthDuration</code> the function returns 0.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:seconds-from-duration(xs:dayTimeDuration("P3DT10H12.5S"))</fos:expression>
               <fos:result>12.5</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:seconds-from-duration(xs:dayTimeDuration("-PT256S"))</fos:expression>
               <fos:result>-16.0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="add-yearMonthDurations" prefix="op">
      <fos:signatures>
         <fos:proto name="add-yearMonthDurations" return-type="xs:yearMonthDuration">
            <fos:arg name="arg1" type="xs:yearMonthDuration"/>
            <fos:arg name="arg2" type="xs:yearMonthDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="+" types="xs:yearMonthDuration numeric">Defines the semantics of the
         "+" operator when applied to two <code>xs:yearMonthDuration</code> values.</fos:opermap>
      <fos:summary>
         <p>Returns the result of adding two <code>xs:yearMonthDuration</code> values. </p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of adding the value of <code>$arg1</code> to the value
            of <code>$arg2</code>. The result will be an <code>xs:yearMonthDuration</code> whose
            length in months is equal to the length in months of <code>$arg1</code> plus the length
            in months of <code>$arg2</code>.</p>
         <p>For handling of overflow, see <specref ref="duration-limits"/>.</p>
      </fos:rules>
      <fos:notes>
         <p>Either duration (and therefore the result) may be negative.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:add-yearMonthDurations(xs:yearMonthDuration("P2Y11M"),
                  xs:yearMonthDuration("P3Y3M"))</fos:expression>
               <fos:result>xs:yearMonthDuration("P6Y2M")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="subtract-yearMonthDurations" prefix="op">
      <fos:signatures>
         <fos:proto name="subtract-yearMonthDurations" return-type="xs:yearMonthDuration">
            <fos:arg name="arg1" type="xs:yearMonthDuration"/>
            <fos:arg name="arg2" type="xs:yearMonthDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="-" types="xs:yearMonthDuration numeric">Defines the semantics of the
         "-" operator when applied to two <code>xs:yearMonthDuration</code> values.</fos:opermap>
      <fos:summary>
         <p>Returns the result of subtracting one <code>xs:yearMonthDuration</code> value from
            another. </p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of subtracting the value of <code>$arg2</code> from the
            value of <code>$arg1</code>. The result will be an <code>xs:yearMonthDuration</code>
            whose length in months is equal to the length in months of <code>$arg1</code> minus the
            length in months of <code>$arg2</code>.</p>
         <p>For handling of overflow, see <specref ref="duration-limits"/>.</p>
      </fos:rules>
      <fos:notes>
         <p>Either duration (and therefore the result) may be negative.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-yearMonthDurations(xs:yearMonthDuration("P2Y11M"),
                  xs:yearMonthDuration("P3Y3M"))</fos:expression>
               <fos:result>xs:yearMonthDuration("-P4M")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="multiply-yearMonthDuration" prefix="op">
      <fos:signatures>
         <fos:proto name="multiply-yearMonthDuration" return-type="xs:yearMonthDuration">
            <fos:arg name="arg1" type="xs:yearMonthDuration"/>
            <fos:arg name="arg2" type="xs:double"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="*" types="xs:yearMonthDuration numeric">Defines the semantics of the
         "*" operator when applied to an <code>xs:yearMonthDuration</code> and a numeric
         value.</fos:opermap>
      <fos:summary>
         <p>Returns the result of multiplying the value of <code>$arg1</code> by <code>$arg2</code>.
            The result is rounded to the nearest month.</p>
      </fos:summary>
      <fos:rules>
         <p>The result is the <code>xs:yearMonthDuration</code> whose length in months is equal to
            the result of applying the <code>fn:round</code> function to the value obtained by
            multiplying the length in months of <code>$arg1</code> by the value of
               <code>$arg2</code>.</p>
         <p>If <code>$arg2</code> is positive or negative zero, the result is a zero-length
            duration. If <code>$arg2</code> is positive or negative infinity, the result overflows
            and is handled as described in <specref ref="duration-limits"/>. </p>
         <p>For handling of overflow and underflow, see <specref ref="duration-limits"/>.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="CA" code="0005"/> if <code>$arg2</code> is
               <code>NaN</code>.</p>
      </fos:errors>
      <fos:notes>
         <p>Either duration (and therefore the result) may be negative.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:multiply-yearMonthDuration(xs:yearMonthDuration("P2Y11M"),
                  2.3)</fos:expression>
               <fos:result>xs:yearMonthDuration("P6Y9M")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="divide-yearMonthDuration" prefix="op">
      <fos:signatures>
         <fos:proto name="divide-yearMonthDuration" return-type="xs:yearMonthDuration">
            <fos:arg name="arg1" type="xs:yearMonthDuration"/>
            <fos:arg name="arg2" type="xs:double"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="div" types="xs:yearMonthDuration numeric">Defines the semantics of the
         "div" operator when applied to an <code>xs:yearMonthDuration</code> and a numeric
         value.</fos:opermap>
      <fos:summary>
         <p>Returns the result of dividing the value of <code>$arg1</code> by <code>$arg2</code>.
            The result is rounded to the nearest month.</p>
      </fos:summary>
      <fos:rules>
         <p>The result is the <code>xs:yearMonthDuration</code> whose length in months is equal to
            the result of applying the <code>fn:round</code> function to the value obtained by
            dividing the length in months of <code>$arg1</code> by the value of
            <code>$arg2</code>.</p>
         <p>If <code>$arg2</code> is positive or negative infinity, the result is a zero-length
            duration. If <code>$arg2</code> is positive or negative zero, the result overflows and
            is handled as described in <specref ref="duration-limits"/>. </p>
         <p>For handling of overflow and underflow, see <specref ref="duration-limits"/>.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="CA" code="0005"/> if <code>$arg2</code> is
               <code>NaN</code>.</p>
      </fos:errors>
      <fos:notes>
         <p>Either operand (and therefore the result) may be negative.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:divide-yearMonthDuration(xs:yearMonthDuration("P2Y11M"),
                  1.5)</fos:expression>
               <fos:result>xs:yearMonthDuration("P1Y11M")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="divide-yearMonthDuration-by-yearMonthDuration" prefix="op">
      <fos:signatures>
         <fos:proto name="divide-yearMonthDuration-by-yearMonthDuration" return-type="xs:decimal">
            <fos:arg name="arg1" type="xs:yearMonthDuration"/>
            <fos:arg name="arg2" type="xs:yearMonthDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="div" types="xs:yearMonthDuration numeric">Defines the semantics of the
         "div" operator when applied to two <code>xs:yearMonthDuration</code> values.</fos:opermap>
      <fos:summary>
         <p>Returns the ratio of two <code>xs:yearMonthDuration</code> values.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of dividing the length in months of <code>$arg1</code>
            by the length in months of <code>$arg2</code>, according to the rules of the
               <code>op:numeric-divide</code> function for integer operands.</p>
         <p>For handling of overflow and underflow, see <specref ref="duration-limits"/>.</p>
      </fos:rules>
      <fos:notes>
         <p>Either duration (and therefore the result) may be negative.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:divide-yearMonthDuration-by-yearMonthDuration(xs:yearMonthDuration("P3Y4M"),
                  xs:yearMonthDuration("-P1Y4M"))</fos:expression>
               <fos:result>-2.5</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>The following example demonstrates how to calculate the length of an
                  <code>xs:yearMonthDuration</code> value in months:</p>
            <fos:test>
               <fos:expression>op:divide-yearMonthDuration-by-yearMonthDuration(xs:yearMonthDuration("P3Y4M"),
                  xs:yearMonthDuration("P1M"))</fos:expression>
               <fos:result>40</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="add-dayTimeDurations" prefix="op">
      <fos:signatures>
         <fos:proto name="add-dayTimeDurations" return-type="xs:dayTimeDuration">
            <fos:arg name="arg1" type="xs:dayTimeDuration"/>
            <fos:arg name="arg2" type="xs:dayTimeDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="+" types="xs:dayTimeDuration numeric">Defines the semantics of the "+"
         operator when applied to two <code>xs:dayTimeDuration</code> values.</fos:opermap>
      <fos:summary>
         <p>Returns the sum of two <code>xs:dayTimeDuration</code> values.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of adding the value of <code>$arg1</code> to the value
            of <code>$arg2</code>. The result is the <code>xs:dayTimeDuration</code> whose length in
            seconds is equal to the sum of the length in seconds of the two input durations.</p>
         <p>For handling of overflow, see <specref ref="duration-limits"/>.</p>
      </fos:rules>
      <fos:notes>
         <p>Either duration (and therefore the result) may be negative.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:add-dayTimeDurations(xs:dayTimeDuration("P2DT12H5M"),
                  xs:dayTimeDuration("P5DT12H"))</fos:expression>
               <fos:result>xs:dayTimeDuration('P8DT5M')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="subtract-dayTimeDurations" prefix="op">
      <fos:signatures>
         <fos:proto name="subtract-dayTimeDurations" return-type="xs:dayTimeDuration">
            <fos:arg name="arg1" type="xs:dayTimeDuration"/>
            <fos:arg name="arg2" type="xs:dayTimeDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="-" types="xs:dayTimeDuration numeric">Defines the semantics of the "-"
         operator when applied to two <code>xs:dayTimeDuration</code> values.</fos:opermap>
      <fos:summary>
         <p>Returns the result of subtracting one <code>xs:dayTimeDuration</code> from another.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of subtracting the value of <code>$arg2</code> from the
            value of <code>$arg1</code>. The result is the <code>xs:dayTimeDuration</code> whose
            length in seconds is equal to the length in seconds of <code>$arg1</code> minus the
            length in seconds of <code>$arg2</code>.</p>
         <p>For handling of overflow, see <specref ref="duration-limits"/>.</p>
      </fos:rules>
      <fos:notes>
         <p>Either duration (and therefore the result) may be negative.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-dayTimeDurations(xs:dayTimeDuration("P2DT12H"),
                  xs:dayTimeDuration("P1DT10H30M"))</fos:expression>
               <fos:result>xs:dayTimeDuration('P1DT1H30M')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="multiply-dayTimeDuration" prefix="op">
      <fos:signatures>
         <fos:proto name="multiply-dayTimeDuration" return-type="xs:dayTimeDuration">
            <fos:arg name="arg1" type="xs:dayTimeDuration"/>
            <fos:arg name="arg2" type="xs:double"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="*" types="xs:dayTimeDuration numeric">Defines the semantics of the "*"
         operator when applied to an <code>xs:dayTimeDuration</code> and a numeric
         value.</fos:opermap>
      <fos:summary>
         <p>Returns the result of multiplying a <code>xs:dayTimeDuration</code> by a number.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of multiplying the value of <code>$arg1</code> by
               <code>$arg2</code>. The result is the <code>xs:dayTimeDuration</code> whose length in
            seconds is equal to the length in seconds of <code>$arg1</code> multiplied by the
            numeric value <code>$arg2</code>.</p>
         <!--<ednote>
            <edtext>We ought to say whether the calculation is performed using double or decimal
               arithmetic.</edtext>
         </ednote>-->
         <p>If <code>$arg2</code> is positive or negative zero, the result is a zero-length
            duration. If <code>$arg2</code> is positive or negative infinity, the result overflows
            and is handled as described in <specref ref="date-time-duration-conformance"/>. </p>
         <p>For handling of overflow and underflow, see <specref ref="duration-limits"/>.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="CA" code="0005"/> if <code>$arg2</code> is
               <code>NaN</code>.</p>
      </fos:errors>
      <fos:notes>
         <p>Either operand (and therefore the result) may be negative.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:multiply-dayTimeDuration(xs:dayTimeDuration("PT2H10M"),
                  2.1)</fos:expression>
               <fos:result>xs:dayTimeDuration('PT4H33M')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="divide-dayTimeDuration" prefix="op">
      <fos:signatures>
         <fos:proto name="divide-dayTimeDuration" return-type="xs:dayTimeDuration">
            <fos:arg name="arg1" type="xs:dayTimeDuration"/>
            <fos:arg name="arg2" type="xs:double"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="div" types="xs:dayTimeDuration numeric">Defines the semantics of the
         "div" operator when applied to two <code>xs:dayTimeDuration</code> values.</fos:opermap>
      <fos:summary>
         <p>Returns the result of multiplying a <code>xs:dayTimeDuration</code> by a number.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of dividing the value of <code>$arg1</code> by
               <code>$arg2</code>. The result is the <code>xs:dayTimeDuration</code> whose length in
            seconds is equal to the length in seconds of <code>$arg1</code> divided by the numeric
            value <code>$arg2</code>.</p>
         <p>If <code>$arg2</code> is positive or negative infinity, the result is a zero-length
            duration. If <code>$arg2</code> is positive or negative zero, the result overflows and
            is handled as described in <specref ref="date-time-duration-conformance"/>. </p>
         <!--<ednote>
            <edtext>We ought to say whether the calculation is performed using double or decimal
               arithmetic.</edtext>
         </ednote>-->
         <p>For handling of overflow and underflow, see <specref ref="duration-limits"/>.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="CA" code="0005"/> if <code>$arg2</code> is
               <code>NaN</code>.</p>
      </fos:errors>
      <fos:notes>
         <p>Either operand (and therefore the result) may be negative.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:divide-dayTimeDuration(xs:dayTimeDuration("P1DT2H30M10.5S"),
                  1.5)</fos:expression>
               <fos:result>xs:duration("PT17H40M7S")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="divide-dayTimeDuration-by-dayTimeDuration" prefix="op">
      <fos:signatures>
         <fos:proto name="divide-dayTimeDuration-by-dayTimeDuration" return-type="xs:decimal">
            <fos:arg name="arg1" type="xs:dayTimeDuration"/>
            <fos:arg name="arg2" type="xs:dayTimeDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="div" types="xs:dayTimeDuration numeric">Defines the semantics of the
         "div" operator when applied to two <code>xs:dayTimeDuration</code> values.</fos:opermap>
      <fos:summary>
         <p>Returns the ratio of two <code>xs:dayTimeDuration</code> values, as a decimal
            number.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of dividing the value of <code>$arg1</code> by
               <code>$arg2</code>. The result is the <code>xs:dayTimeDuration</code> whose length in
            seconds is equal to the length in seconds of <code>$arg1</code> divided by the length in
            seconds of <code>$arg2</code>. The calculation is performed by applying
               <code>op:numeric-divide</code> to the two <code>xs:decimal</code> operands.</p>
         <p>For handling of overflow and underflow, see <specref ref="duration-limits"/>.</p>
      </fos:rules>
      <fos:notes>
         <p>Either operand (and therefore the result) may be negative.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:round-half-to-even( op:divide-dayTimeDuration-by-dayTimeDuration(
                  xs:dayTimeDuration("P2DT53M11S"), xs:dayTimeDuration("P1DT10H")),
                  4)</fos:expression>
               <fos:result>1.4378</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>This examples shows how to determine the number of seconds in a duration.</p>
            <fos:test>
               <fos:expression>op:divide-dayTimeDuration-by-dayTimeDuration(xs:dayTimeDuration("P2DT53M11S"),
                  xs:dayTimeDuration("PT1S"))</fos:expression>
               <fos:result>175991.0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="dateTime" prefix="fn">
      <fos:signatures>
         <fos:proto name="dateTime" return-type="xs:dateTime?">
            <fos:arg name="arg1" type="xs:date?"/>
            <fos:arg name="arg2" type="xs:time?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns an <code>xs:dateTime</code> value created by combining an <code>xs:date</code>
            and an <code>xs:time</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If either <code>$arg1</code> or <code>$arg2</code> is the empty sequence the function
            returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:dateTime</code> whose date component is
            equal to <code>$arg1</code> and whose time component is equal to <code>$arg2</code>.</p>
         <p>The timezone of the result is computed as follows:</p>
         <ulist>
            <item>
               <p>If neither argument has a timezone, the result has no timezone.</p>
            </item>
            <item>
               <p>If exactly one of the arguments has a timezone, or if both arguments have the same
                  timezone, the result has this timezone.</p>
            </item>
         </ulist>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="RG" code="0008"/> if the two arguments both
            have timezones and the timezones are different. </p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:dateTime(xs:date("1999-12-31"),
                  xs:time("12:00:00"))</fos:expression>
               <fos:result>xs:dateTime("1999-12-31T12:00:00")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:dateTime(xs:date("1999-12-31"),
                  xs:time("24:00:00"))</fos:expression>
               <fos:result>xs:dateTime("1999-12-31T00:00:00")</fos:result>
               <fos:postamble>This is because <code>"24:00:00"</code> is an alternate lexical form
                  for <code>"00:00:00"</code></fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="dateTime-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="dateTime-equal" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:dateTime"/>
            <fos:arg name="arg2" type="xs:dateTime"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="eq" types="xs:dateTime numeric" other-operators="ne le ge">Defines the
         semantics of the "eq" operator when applied to two <code>xs:dateTime</code> values. Also
         used in the definition of the "ne", "le" and "ge" operators.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if the two supplied <code>xs:dateTime</code> values refer to the same
            instant in time.</p>
      </fos:summary>
      <fos:rules>
         <p>If either <code>$arg1</code> or <code>$arg2</code> has no timezone component, the
            effective value of the argument is obtained by substituting the implicit timezone from
            the dynamic evaluation context.</p>
         <p>The function then returns <code>true</code> if and only if the effective value of
               <code>$arg1</code> is equal to the effective value of <code>$arg2</code> according to
            the algorithm defined in section 3.2.7.4 of <bibref ref="xmlschema-2"/>
            <quote>Order relation on dateTime</quote> for <code>xs:dateTime</code> values with
            timezones. Otherwise the function returns <code>false</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <p>Assume that the dynamic context provides an implicit timezone value of
                  <code>-05:00</code></p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:dateTime-equal(xs:dateTime("2002-04-02T12:00:00-01:00"),
                  xs:dateTime("2002-04-02T17:00:00+04:00"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test implicit-timezone="-PT5H">
               <fos:expression>op:dateTime-equal(xs:dateTime("2002-04-02T12:00:00"),
                  xs:dateTime("2002-04-02T23:00:00+06:00"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:dateTime-equal(xs:dateTime("2002-04-02T12:00:00"),
                  xs:dateTime("2002-04-02T17:00:00"))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:dateTime-equal(xs:dateTime("2002-04-02T12:00:00"),
                  xs:dateTime("2002-04-02T12:00:00"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:dateTime-equal(xs:dateTime("2002-04-02T23:00:00-04:00"),
                  xs:dateTime("2002-04-03T02:00:00-01:00"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:dateTime-equal(xs:dateTime("1999-12-31T24:00:00"),
                  xs:dateTime("2000-01-01T00:00:00"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:dateTime-equal(xs:dateTime("2005-04-04T24:00:00"),
                  xs:dateTime("2005-04-04T00:00:00"))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="dateTime-less-than" prefix="op">
      <fos:signatures>
         <fos:proto name="dateTime-less-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:dateTime"/>
            <fos:arg name="arg2" type="xs:dateTime"/>
         </fos:proto>
      </fos:signatures>

      <fos:opermap operator="lt" types="xs:dateTime numeric" other-operators="ge">Defines the
         semantics of the "lt" operator when applied to two <code>xs:dateTime</code> values. Also
         used in the definition of the "ge" operator.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns <code>true</code> if the first argument represents an earlier instant in time
            than the second argument.</p>
      </fos:summary>
      <fos:rules>
         <p>If either <code>$arg1</code> or <code>$arg2</code> has no timezone component, the
            effective value of the argument is obtained by substituting the implicit timezone from
            the dynamic evaluation context.</p>
         <p>The function then returns <code>true</code> if and only if the effective value of
               <code>$arg1</code> is less than the effective value of <code>$arg2</code> according
            to the algorithm defined in section 3.2.7.4 of <bibref ref="xmlschema-2"/>
            <quote>Order relation on dateTime</quote> for <code>xs:dateTime</code> values with
            timezones. Otherwise the function returns <code>false</code>.</p>
      </fos:rules>
   </fos:function>
   <fos:function name="dateTime-greater-than" prefix="op">
      <fos:signatures>
         <fos:proto name="dateTime-greater-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:dateTime"/>
            <fos:arg name="arg2" type="xs:dateTime"/>
         </fos:proto>
      </fos:signatures>

      <fos:opermap operator="gt" types="xs:dateTime numeric" other-operators="le">Defines the
         semantics of the "gt" operator when applied to two <code>xs:dateTime</code> values. Also
         used in the definition of the "le" operator.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns <code>true</code> if the first argument represents a later instant in time than
            the second argument.</p>
      </fos:summary>
      <fos:rules>
         <p>The function call <code>op:dateTime-greater-than($A, $B)</code> is defined to return the
            same result as <code>op:dateTime-less-than($B, $A)</code></p>
      </fos:rules>
   </fos:function>
   <fos:function name="date-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="date-equal" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:date"/>
            <fos:arg name="arg2" type="xs:date"/>
         </fos:proto>
      </fos:signatures>

      <fos:opermap operator="eq" types="xs:date numeric" other-operators="ne le ge">Defines the
         semantics of the "eq" operator when applied to two <code>xs:date</code> values. Also used
         in the definition of the "ne", "le" and "ge" operators.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns <code>true</code> if and only if the starting instants of the two supplied
               <code>xs:date</code> values are the same.</p>
      </fos:summary>
      <fos:rules>
         <p>The starting instant of an <code>xs:date</code> is the <code>xs:dateTime</code> at time
               <code>00:00:00</code> on that date.</p>
         <p>The function returns the result of the expression:</p>
         <eg xml:space="preserve">op:dateTime-equal(xs:dateTime($arg1), xs:dateTime($arg2))</eg>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:date-equal(xs:date("2004-12-25Z"),
                  xs:date("2004-12-25+07:00"))</fos:expression>
               <fos:result>false()</fos:result>
               <fos:postamble>The starting instants are
                     <code>xs:dateTime("2004-12-25T00:00:00Z")</code> and
                     <code>xs:dateTime("2004-12-25T00:00:00+07:00")</code>. These are normalized to
                     <code>xs:dateTime("2004-12-25T00:00:00Z")</code> and
                     <code>xs:dateTime("2004-12-24T17:00:00Z")</code>. </fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:date-equal(xs:date("2004-12-25-12:00"),
                  xs:date("2004-12-26+12:00"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="date-less-than" prefix="op">
      <fos:signatures>
         <fos:proto name="date-less-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:date"/>
            <fos:arg name="arg2" type="xs:date"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="lt" types="xs:date numeric" other-operators="ge">Defines the semantics
         of the "lt" operator when applied to two <code>xs:date</code> values. Also used in the
         definition of the "ge" operator.</fos:opermap>
      <fos:summary>
         <p>Returns <code>true</code> if and only if the starting instant of <code>$arg1</code> is
            less than the starting instant of <code>$arg2</code>. Returns <code>false</code>
            otherwise.</p>
      </fos:summary>
      <fos:rules>
         <p>The starting instant of an <code>xs:date</code> is the <code>xs:dateTime</code> at time
               <code>00:00:00</code> on that date.</p>
         <p>The function returns the result of the expression:</p>
         <eg xml:space="preserve">op:dateTime-less-than(xs:dateTime($arg1), xs:dateTime($arg2))</eg>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:date-less-than(xs:date("2004-12-25Z"),
                  xs:date("2004-12-25-05:00"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:date-less-than(xs:date("2004-12-25-12:00"),
                  xs:date("2004-12-26+12:00"))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="date-greater-than" prefix="op">
      <fos:signatures>
         <fos:proto name="date-greater-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:date"/>
            <fos:arg name="arg2" type="xs:date"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="gt" types="xs:date numeric" other-operators="le">Defines the semantics
         of the "gt" operator when applied to two <code>xs:date</code> values. Also used in the
         definition of the "le" operator.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns <code>true</code> if and only if the starting instant of <code>$arg1</code> is
            greater than the starting instant of <code>$arg2</code>. Returns <code>false</code>
            otherwise.</p>
      </fos:summary>
      <fos:rules>
         <p>The function call <code>op:date-greater-than($A, $B)</code> is defined to return the
            same result as <code>op:date-less-than($B, $A)</code></p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:date-greater-than(xs:date("2004-12-25Z"),
                  xs:date("2004-12-25+07:00"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:date-greater-than(xs:date("2004-12-25-12:00"),
                  xs:date("2004-12-26+12:00"))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="time-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="time-equal" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:time"/>
            <fos:arg name="arg2" type="xs:time"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="eq" types="xs:time numeric" other-operators="ne le ge">Defines the
         semantics of the "eq" operator when applied to two <code>xs:time</code> values. Also used
         in the definition of the "ne", "le" and "ge" operators.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns <code>true</code> if the two <code>xs:time</code> values represent the same
            instant in time, when treated as being times on the same date, before adjusting the
            timezone.</p>
      </fos:summary>
      <fos:rules>
         <p>Each of the supplied <code>xs:time</code> values is expanded to an
               <code>xs:dateTime</code> value by associating the time with an arbitrary date. The
            function returns the result of comparing these two <code>xs:dateTime</code> values using
               <code>op:dateTime-equal</code>.</p>
         <p>The result of the function is thus the same as the value of the expression:</p>
         <eg xml:space="preserve">op:dateTime-equal(
        fn:dateTime(xs:date('1972-12-31'), $arg1), 
        fn:dateTime(xs:date('1972-12-31'), $arg2))</eg>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <p>Assume that the date components from the reference <code>xs:dateTime</code>
               correspond to <code>1972-12-31</code>.</p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:time-equal(xs:time("08:00:00+09:00"),
                  xs:time("17:00:00-06:00"))</fos:expression>
               <fos:result>false()</fos:result>
               <fos:postamble>The <code>xs:dateTime</code>s calculated using the reference date
                  components are <code>1972-12-31T08:00:00+09:00</code> and
                     <code>1972-12-31T17:00:00-06:00</code>. These normalize to
                     <code>1972-12-30T23:00:00Z</code> and <code>1972-12-31T23:00:00Z</code>.
               </fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:time-equal(xs:time("21:30:00+10:30"),
                  xs:time("06:00:00-05:00"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:time-equal(xs:time("24:00:00+01:00"),
                  xs:time("00:00:00+01:00"))</fos:expression>
               <fos:result>true()</fos:result>
               <fos:postamble>This not the result one might expect. For <code>xs:dateTime</code>
                  values, a time of <code>24:00:00</code> is equivalent to <code>00:00:00</code> on
                  the following day. For <code>xs:time</code>, the normalization from
                     <code>24:00:00</code> to <code>00:00:00</code> happens before the
                     <code>xs:time</code> is converted into an <code>xs:dateTime</code> for the
                  purpose of the equality comparison. For <code>xs:time</code>, any operation on
                     <code>24:00:00</code> produces the same result as the same operation on
                     <code>00:00:00</code> because these are two different lexical representations
                  of the same value. </fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="time-less-than" prefix="op">
      <fos:signatures>
         <fos:proto name="time-less-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:time"/>
            <fos:arg name="arg2" type="xs:time"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="lt" types="xs:time numeric" other-operators="ge">Defines the semantics
         of the "lt" operator when applied to two <code>xs:time</code> values. Also used in the
         definition of the "ge" operator.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns <code>true</code> if the first <code>xs:time</code> value represents an earlier
            instant in time than the second, when both are treated as being times on the same date,
            before adjusting the timezone.</p>
      </fos:summary>
      <fos:rules>
         <p>Each of the supplied <code>xs:time</code> values is expanded to an
               <code>xs:dateTime</code> value by associating the time with an arbitrary date. The
            function returns the result of comparing these two <code>xs:dateTime</code> values using
               <code>op:dateTime-less-than</code>.</p>
         <p>The result of the function is thus the same as the value of the expression:</p>
         <eg xml:space="preserve">op:dateTime-less-than(
        fn:dateTime(xs:date('1972-12-31'), $arg1), 
        fn:dateTime(xs:date('1972-12-31'), $arg2))</eg>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <p>Assume that the dynamic context provides an implicit timezone value of
                  <code>-05:00</code>.</p>
         </fos:example>
         <fos:example>
            <fos:test implicit-timezone="-PT5H">
               <fos:expression>op:time-less-than(xs:time("12:00:00"),
                  xs:time("23:00:00+06:00"))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:time-less-than(xs:time("11:00:00"),
                  xs:time("17:00:00Z"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:time-less-than(xs:time("23:59:59"),
                  xs:time("24:00:00"))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="time-greater-than" prefix="op">
      <fos:signatures>
         <fos:proto name="time-greater-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:time"/>
            <fos:arg name="arg2" type="xs:time"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="gt" types="xs:time numeric" other-operators="le">Defines the semantics
         of the "gt" operator when applied to two <code>xs:time</code> values. Also used in the
         definition of the "le" operator.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns <code>true</code> if the first <code>xs:time</code> value represents a later
            instant in time than the second, when both are treated as being times on the same date,
            before adjusting the timezone.</p>
      </fos:summary>
      <fos:rules>
         <p>The function call <code>op:time-greater-than($A, $B)</code> is defined to return the
            same result as <code>op:time-less-than($B, $A)</code></p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:time-greater-than(xs:time("08:00:00+09:00"),
                  xs:time("17:00:00-06:00"))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="gYearMonth-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="gYearMonth-equal" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:gYearMonth"/>
            <fos:arg name="arg2" type="xs:gYearMonth"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="eq" types="xs:gYearMonth numeric" other-operators="ne">Defines the
         semantics of the "eq" operator when applied to two <code>xs:gYearMonth</code> values. Also
         used in the definition of the "ne" operator.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if the two <code>xs:gYearMonth</code> values have the same starting
            instant.</p>
      </fos:summary>
      <fos:rules>
         <p>The starting instants of <code>$arg1</code> and <code>$arg2</code> are calculated by
            supplying the missing components of <code>$arg1</code> and <code>$arg2</code> from the
               <code>xs:dateTime</code> template <code>xxxx-xx-01T00:00:00</code>. The function
            returns the result of comparing these two starting instants using
               <code>op:dateTime-equal</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <p>Assume that the dynamic context provides an implicit timezone value of
                  <code>-05:00</code>.</p>
         </fos:example>
         <fos:example>
            <p><code>op:gYearMonth-equal(xs:gYearMonth("1986-02"), xs:gYearMonth("1986-03"))</code>
               returns <code>false()</code>. The starting instants are
                  <code>1986-02-01T00:00:00-05:00</code> and <code>1986-03-01T00:00:00</code>,
               respectively.</p>
         </fos:example>
         <fos:example>
            <p><code>op:gYearMonth-equal(xs:gYearMonth("1978-03"), xs:gYearMonth("1986-03Z"))</code>
               returns <code>false()</code>. The starting instants are
                  <code>1978-03-01T00:00:00-05:00</code> and <code>1986-03-01T00:00:00Z</code>,
               respectively.</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="gYear-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="gYear-equal" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:gYear"/>
            <fos:arg name="arg2" type="xs:gYear"/>
         </fos:proto>
      </fos:signatures>

      <fos:opermap operator="eq" types="xs:gYear numeric" other-operators="ne">Defines the semantics
         of the "eq" operator when applied to two <code>xs:gYear</code> values. Also used in the
         definition of the "ne" operator.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if the two <code>xs:gYear</code> values have the same starting instant.</p>
      </fos:summary>
      <fos:rules>
         <p>The starting instants of <code>$arg1</code> and <code>$arg2</code> are calculated by
            supplying the missing components of <code>$arg1</code> and <code>$arg2</code> from the
               <code>xs:dateTime</code> template <code>xxxx-01-01T00:00:00</code>. The function
            returns the result of comparing these two starting instants using
               <code>op:dateTime-equal</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <p>Assume that the dynamic context provides an implicit timezone value of
                  <code>-05:00</code>. Assume, also, that the <code>xs:dateTime</code> template is
                  <code>xxxx-01-01T00:00:00</code>. </p>
         </fos:example>
         <fos:example>
            <p><code>op:gYear-equal(xs:gYear("2005-12:00"), xs:gYear("2005+12:00"))</code> returns
                  <code>false()</code>. The starting instants are
                  <code>2005-01-01T00:00:00-12:00</code> and <code>2005-01-01T00:00:00+12:00</code>,
               respectively, and normalize to <code>2005-01-01T12:00:00Z</code> and
                  <code>2004-12-31T12:00:00Z</code>.</p>
         </fos:example>
         <fos:example>
            <fos:test implicit-timezone="-PT5H">
               <fos:expression>op:gYear-equal(xs:gYear("1976-05:00"),
                  xs:gYear("1976"))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="gMonthDay-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="gMonthDay-equal" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:gMonthDay"/>
            <fos:arg name="arg2" type="xs:gMonthDay"/>
         </fos:proto>
      </fos:signatures>

      <fos:opermap operator="eq" types="xs:gMonthDay numeric" other-operators="ne">Defines the
         semantics of the "eq" operator when applied to two <code>xs:gMonthDay</code> values. Also
         used in the definition of the "ne" operator.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if the two <code>xs:gMonthDay</code> values have the same starting instant,
            when considered as days in the same year.</p>
      </fos:summary>
      <fos:rules>
         <p>The starting instants of <code>$arg1</code> and <code>$arg2</code> are calculated by
            supplying the missing components of <code>$arg1</code> and <code>$arg2</code> from the
               <code>xs:dateTime</code> template <code>1972-xx-xxT00:00:00</code> or an equivalent.
            The function returns the result of comparing these two starting instants using
               <code>op:dateTime-equal</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <p>Assume that the dynamic context provides an implicit timezone value of
                  <code>-05:00</code>. Assume for the purposes of illustration that the
                  <code>xs:dateTime</code> template used is <code>1972-xx-xxT00:00:00</code> (this
               does not affect the result). </p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:gMonthDay-equal(xs:gMonthDay("--12-25-14:00"),
                  xs:gMonthDay("--12-26+10:00"))</fos:expression>
               <fos:result>true()</fos:result>
               <fos:postamble> The starting instants are <code>1972-12-25T00:00:00-14:00</code> and
                     <code>1972-12-26T00:00:00+10:00</code>, respectively, and normalize to
                     <code>1972-12-25T14:00:00Z</code> and <code>1972-12-25T14:00:00Z</code>.
               </fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:gMonthDay-equal(xs:gMonthDay("--12-25"),
                  xs:gMonthDay("--12-26Z"))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="gMonth-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="gMonth-equal" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:gMonth"/>
            <fos:arg name="arg2" type="xs:gMonth"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="eq" types="xs:gMonth numeric" other-operators="ne">Defines the
         semantics of the "eq" operator when applied to two <code>xs:gMonth</code> values. Also used
         in the definition of the "ne" operator.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if the two <code>xs:gMonth</code> values have the same starting instant,
            when considered as months in the same year.</p>
      </fos:summary>
      <fos:rules>
         <p>The starting instants of <code>$arg1</code> and <code>$arg2</code> are calculated by
            supplying the missing components of <code>$arg1</code> and <code>$arg2</code> from the
               <code>xs:dateTime</code> template <code>1972-xx-01T00:00:00</code> or an equivalent.
            The function returns the result of comparing these two starting instants using
               <code>op:dateTime-equal</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <p>Assume that the dynamic context provides an implicit timezone value of
                  <code>-05:00</code>. Assume, also, that the <code>xs:dateTime</code> template
               chosen is <code>1972-xx-01T00:00:00</code>. </p>
         </fos:example>
         <fos:example>
            <fos:test implicit-timezone="-PT5H">
               <fos:expression>op:gMonth-equal(xs:gMonth("--12-14:00"),
                  xs:gMonth("--12+10:00"))</fos:expression>
               <fos:result>false()</fos:result>
               <fos:postamble> The starting instants are <code>1972-12-01T00:00:00-14:00</code> and
                     <code>1972-12-01T00:00:00+10:00</code>, respectively, and normalize to
                     <code>1972-11-30T14:00:00Z</code> and <code>1972-12-01T14:00:00Z</code>.
               </fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test implicit-timezone="-PT5H">
               <fos:expression>op:gMonth-equal(xs:gMonth("--12"),
                  xs:gMonth("--12Z"))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="gDay-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="gDay-equal" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:gDay"/>
            <fos:arg name="arg2" type="xs:gDay"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="eq" types="xs:gDay numeric" other-operators="ne">Defines the semantics
         of the "eq" operator when applied to two <code>xs:gDay</code> values. Also used in the
         definition of the "ne" operator.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if the two <code>xs:gDay</code> values have the same starting instant, when
            considered as days in the same month of the same year.</p>
      </fos:summary>
      <fos:rules>
         <p>The starting instants of <code>$arg1</code> and <code>$arg2</code> are calculated by
            supplying the missing components of <code>$arg1</code> and <code>$arg2</code> from the
               <code>xs:dateTime</code> template <code>1972-12-xxT00:00:00</code> or an equivalent.
            The function returns the result of comparing these two starting instants using
               <code>op:dateTime-equal</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <p>Assume that the dynamic context provides an implicit timezone value of
                  <code>-05:00</code>. Assume, also, that the <code>xs:dateTime</code> template is
                  <code>1972-12-xxT00:00:00</code>. </p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:gDay-equal(xs:gDay("---25-14:00"),
                  xs:gDay("---25+10:00"))</fos:expression>
               <fos:result>false()</fos:result>
               <fos:postamble> The starting instants are <code>1972-12-25T00:00:00-14:00</code> and
                     <code>1972-12-25T00:00:00+10:00</code>, respectively, and normalize to
                     <code>1972-12-25T14:00:00Z</code> and <code>1972-12-24T14:00:00Z</code>.
               </fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test implicit-timezone="-PT5H">
               <fos:expression>op:gDay-equal(xs:gDay("---12"), xs:gDay("---12Z"))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="year-from-dateTime" prefix="fn">
      <fos:signatures>
         <fos:proto name="year-from-dateTime" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:dateTime?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the year component of an <code>xs:dateTime</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> representing the year
            component in the local value of <code>$arg</code>. The result may be negative.</p>
      </fos:rules>
      <fos:notes>
         <p diff="add" at="F-bug30041">Ignoring complications that arise with midnight on the last day
            of the year, the year returned is the same numeric value that appears in the lexical
         representation, which for negative years means the meaning may vary depending on whether
         XSD 1.0 or XSD 1.1 conventions are in use.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:year-from-dateTime(xs:dateTime("1999-05-31T13:20:00-05:00"))</fos:expression>
               <fos:result>1999</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:year-from-dateTime(xs:dateTime("1999-05-31T21:30:00-05:00"))</fos:expression>
               <fos:result>1999</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:year-from-dateTime(xs:dateTime("1999-12-31T19:20:00"))</fos:expression>
               <fos:result>1999</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:year-from-dateTime(xs:dateTime("1999-12-31T24:00:00"))</fos:expression>
               <fos:result>2000</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:year-from-dateTime(xs:dateTime("-0002-06-06T00:00:00"))</fos:expression>
               <fos:result>-2</fos:result>
               <fos:postamble>The result is the same whether XSD 1.0 or 1.1 is in use, despite
                  the absence of a year 0 in the XSD 1.0 value space.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="month-from-dateTime" prefix="fn">
      <fos:signatures>
         <fos:proto name="month-from-dateTime" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:dateTime?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the month component of an <code>xs:dateTime</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> between 1 and 12, both
            inclusive, representing the month component in the local value of <code>$arg</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:month-from-dateTime(xs:dateTime("1999-05-31T13:20:00-05:00"))</fos:expression>
               <fos:result>5</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:month-from-dateTime(xs:dateTime("1999-12-31T19:20:00-05:00"))</fos:expression>
               <fos:result>12</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:month-from-dateTime(fn:adjust-dateTime-to-timezone(xs:dateTime("1999-12-31T19:20:00-05:00"),
                  xs:dayTimeDuration("PT0S")))</fos:expression>
               <fos:result>1</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="day-from-dateTime" prefix="fn">
      <fos:signatures>
         <fos:proto name="day-from-dateTime" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:dateTime?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the day component of an <code>xs:dateTime</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> between 1 and 31, both
            inclusive, representing the day component in the local value of <code>$arg</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:day-from-dateTime(xs:dateTime("1999-05-31T13:20:00-05:00"))</fos:expression>
               <fos:result>31</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:day-from-dateTime(xs:dateTime("1999-12-31T20:00:00-05:00"))</fos:expression>
               <fos:result>31</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:day-from-dateTime(fn:adjust-dateTime-to-timezone(xs:dateTime("1999-12-31T19:20:00-05:00"),
                  xs:dayTimeDuration("PT0S")))</fos:expression>
               <fos:result>1</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="hours-from-dateTime" prefix="fn">
      <fos:signatures>
         <fos:proto name="hours-from-dateTime" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:dateTime?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the hours component of an <code>xs:dateTime</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> between 0 and 23, both
            inclusive, representing the hours component in the local value of <code>$arg</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-dateTime(xs:dateTime("1999-05-31T08:20:00-05:00"))</fos:expression>
               <fos:result>8</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-dateTime(xs:dateTime("1999-12-31T21:20:00-05:00"))</fos:expression>
               <fos:result>21</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-dateTime(fn:adjust-dateTime-to-timezone(xs:dateTime("1999-12-31T21:20:00-05:00"),
                  xs:dayTimeDuration("PT0S")))</fos:expression>
               <fos:result>2</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-dateTime(xs:dateTime("1999-12-31T12:00:00"))</fos:expression>
               <fos:result>12</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-dateTime(xs:dateTime("1999-12-31T24:00:00"))</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="minutes-from-dateTime" prefix="fn">
      <fos:signatures>
         <fos:proto name="minutes-from-dateTime" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:dateTime?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the minute component of an <code>xs:dateTime</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> value between 0 and 59, both
            inclusive, representing the minute component in the local value of
            <code>$arg</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:minutes-from-dateTime(xs:dateTime("1999-05-31T13:20:00-05:00"))</fos:expression>
               <fos:result>20</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:minutes-from-dateTime(xs:dateTime("1999-05-31T13:30:00+05:30"))</fos:expression>
               <fos:result>30</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="seconds-from-dateTime" prefix="fn">
      <fos:signatures>
         <fos:proto name="seconds-from-dateTime" return-type="xs:decimal?">
            <fos:arg name="arg" type="xs:dateTime?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the seconds component of an <code>xs:dateTime</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:decimal</code> value greater than or equal
            to zero and less than 60, representing the seconds and fractional seconds in the local
            value of <code>$arg</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:seconds-from-dateTime(xs:dateTime("1999-05-31T13:20:00-05:00"))</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="timezone-from-dateTime" prefix="fn">
      <fos:signatures>
         <fos:proto name="timezone-from-dateTime" return-type="xs:dayTimeDuration?">
            <fos:arg name="arg" type="xs:dateTime?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the timezone component of an <code>xs:dateTime</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns the timezone component of <code>$arg</code>, if any. If
               <code>$arg</code> has a timezone component, then the result is an
               <code>xs:dayTimeDuration</code> that indicates deviation from UTC; its value may
            range from +14:00 to -14:00 hours, both inclusive. If <code>$arg</code> has no timezone
            component, the result is the empty sequence.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:timezone-from-dateTime(xs:dateTime("1999-05-31T13:20:00-05:00"))</fos:expression>
               <fos:result>xs:dayTimeDuration("-PT5H")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:timezone-from-dateTime(xs:dateTime("2000-06-12T13:20:00Z"))</fos:expression>
               <fos:result>xs:dayTimeDuration("PT0S")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:timezone-from-dateTime(xs:dateTime("2004-08-27T00:00:00"))</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="year-from-date" prefix="fn">
      <fos:signatures>
         <fos:proto name="year-from-date" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:date?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the year component of an <code>xs:date</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> representing the year in the
            local value of <code>$arg</code>. The value may be negative. </p>
      </fos:rules>
      <fos:notes>
         <p diff="add" at="F-bug30041">The year returned is the same numeric value that appears in the lexical
            representation, which for negative years means the meaning may vary depending on whether
            XSD 1.0 or XSD 1.1 conventions are in use.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:year-from-date(xs:date("1999-05-31"))</fos:expression>
               <fos:result>1999</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:year-from-date(xs:date("2000-01-01+05:00"))</fos:expression>
               <fos:result>2000</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:year-from-date(xs:date("-0002-06-01"))</fos:expression>
               <fos:result>-2</fos:result>
               <fos:postamble>The result is the same whether XSD 1.0 or 1.1 is in use, despite
               the absence of a year 0 in the XSD 1.0 value space.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="month-from-date" prefix="fn">
      <fos:signatures>
         <fos:proto name="month-from-date" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:date?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the month component of an <code>xs:date</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> between 1 and 12, both
            inclusive, representing the month component in the local value of <code>$arg</code>.
         </p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:month-from-date(xs:date("1999-05-31-05:00"))</fos:expression>
               <fos:result>5</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:month-from-date(xs:date("2000-01-01+05:00"))</fos:expression>
               <fos:result>1</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="day-from-date" prefix="fn">
      <fos:signatures>
         <fos:proto name="day-from-date" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:date?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the day component of an <code>xs:date</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> between 1 and 31, both
            inclusive, representing the day component in the localized value of
            <code>$arg</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:day-from-date(xs:date("1999-05-31-05:00"))</fos:expression>
               <fos:result>31</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:day-from-date(xs:date("2000-01-01+05:00"))</fos:expression>
               <fos:result>1</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="timezone-from-date" prefix="fn">
      <fos:signatures>
         <fos:proto name="timezone-from-date" return-type="xs:dayTimeDuration?">
            <fos:arg name="arg" type="xs:date?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the timezone component of an <code>xs:date</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns the timezone component of <code>$arg</code>, if any. If
               <code>$arg</code> has a timezone component, then the result is an
               <code>xs:dayTimeDuration</code> that indicates deviation from UTC; its value may
            range from +14:00 to -14:00 hours, both inclusive. If <code>$arg</code> has no timezone
            component, the result is the empty sequence.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:timezone-from-date(xs:date("1999-05-31-05:00"))</fos:expression>
               <fos:result>xs:dayTimeDuration("-PT5H")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:timezone-from-date(xs:date("2000-06-12Z"))</fos:expression>
               <fos:result>xs:dayTimeDuration("PT0S")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="hours-from-time" prefix="fn">
      <fos:signatures>
         <fos:proto name="hours-from-time" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:time?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the hours component of an <code>xs:time</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> between 0 and 23, both
            inclusive, representing the value of the hours component in the local value of
               <code>$arg</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <p>Assume that the dynamic context provides an implicit timezone value of
                  <code>-05:00</code>. </p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-time(xs:time("11:23:00"))</fos:expression>
               <fos:result>11</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-time(xs:time("21:23:00"))</fos:expression>
               <fos:result>21</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-time(xs:time("01:23:00+05:00"))</fos:expression>
               <fos:result>1</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-time(fn:adjust-time-to-timezone(xs:time("01:23:00+05:00"),
                  xs:dayTimeDuration("PT0S")))</fos:expression>
               <fos:result>20</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:hours-from-time(xs:time("24:00:00"))</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="minutes-from-time" prefix="fn">
      <fos:signatures>
         <fos:proto name="minutes-from-time" return-type="xs:integer?">
            <fos:arg name="arg" type="xs:time?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the minutes component of an <code>xs:time</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:integer</code> value between 0 and 59, both
            inclusive, representing the value of the minutes component in the local value of
               <code>$arg</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:minutes-from-time(xs:time("13:00:00Z"))</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="seconds-from-time" prefix="fn">
      <fos:signatures>
         <fos:proto name="seconds-from-time" return-type="xs:decimal?">
            <fos:arg name="arg" type="xs:time?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the seconds component of an <code>xs:time</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:decimal</code> value greater than or equal
            to zero and less than 60, representing the seconds and fractional seconds in the local
            value of <code>$arg</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:seconds-from-time(xs:time("13:20:10.5"))</fos:expression>
               <fos:result>10.5</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="timezone-from-time" prefix="fn">
      <fos:signatures>
         <fos:proto name="timezone-from-time" return-type="xs:dayTimeDuration?">
            <fos:arg name="arg" type="xs:time?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the timezone component of an <code>xs:time</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>Otherwise, the function returns the timezone component of <code>$arg</code>, if any. If
               <code>$arg</code> has a timezone component, then the result is an
               <code>xs:dayTimeDuration</code> that indicates deviation from UTC; its value may
            range from +14:00 to -14:00 hours, both inclusive. If <code>$arg</code> has no timezone
            component, the result is the empty sequence.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:timezone-from-time(xs:time("13:20:00-05:00"))</fos:expression>
               <fos:result>xs:dayTimeDuration("-PT5H")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:timezone-from-time(xs:time("13:20:00"))</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="adjust-dateTime-to-timezone" prefix="fn">
      <fos:signatures>
         <fos:proto name="adjust-dateTime-to-timezone" return-type="xs:dateTime?">
            <fos:arg name="arg" type="xs:dateTime?"/>
         </fos:proto>
         <fos:proto name="adjust-dateTime-to-timezone" return-type="xs:dateTime?">
            <fos:arg name="arg" type="xs:dateTime?"/>
            <fos:arg name="timezone" type="xs:dayTimeDuration?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Adjusts an <code>xs:dateTime</code> value to a specific timezone, or to no timezone at
            all.</p>
      </fos:summary>
      <fos:rules>
         <p> If <code>$timezone</code> is not specified, then the effective value of
               <code>$timezone</code> is the value of the implicit timezone in the dynamic
            context.</p>
         <p> If <code>$arg</code> is the empty sequence, then the function returns the empty
            sequence.</p>
         <p> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is
            the empty sequence, then the result is <code>$arg</code>.</p>
         <p> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is
            not the empty sequence, then the result is <code>$arg</code> with <code>$timezone</code>
            as the timezone component.</p>
         <p> If <code>$arg</code> has a timezone component and <code>$timezone</code> is the empty
            sequence, then the result is the local value of <code>$arg</code> without its timezone
            component.</p>
         <p> If <code>$arg</code> has a timezone component and <code>$timezone</code> is not the
            empty sequence, then the result is the <code>xs:dateTime</code> value that is equal to
               <code>$arg</code> and that has a timezone component equal to
            <code>$timezone</code>.</p>
      </fos:rules>
      <fos:errors>
         <p> A dynamic error is raised <errorref class="DT" code="0003"/> if <code>$timezone</code>
            is less than <code>-PT14H</code> or greater than <code>PT14H</code> or is not an
            integral number of minutes.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <p> Assume the dynamic context provides an implicit timezone of <code>-05:00
                  (-PT5H0M)</code>.</p>
         </fos:example>
         <fos:variable name="tz-10" id="v-adjust-dateTime-to-timezone-tz10" select="xs:dayTimeDuration(&quot;-PT10H&quot;)"/>
         <fos:example>
            <fos:test implicit-timezone="-PT5H">
               <fos:expression>fn:adjust-dateTime-to-timezone(xs:dateTime('2002-03-07T10:00:00'))</fos:expression>
               <fos:result>xs:dateTime('2002-03-07T10:00:00-05:00')</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-adjust-dateTime-to-timezone-tz10">
               <fos:expression>fn:adjust-dateTime-to-timezone(xs:dateTime('2002-03-07T10:00:00-07:00'))</fos:expression>
               <fos:result>xs:dateTime('2002-03-07T12:00:00-05:00')</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-adjust-dateTime-to-timezone-tz10">
               <fos:expression>fn:adjust-dateTime-to-timezone(xs:dateTime('2002-03-07T10:00:00'),
                  $tz-10)</fos:expression>
               <fos:result>xs:dateTime('2002-03-07T10:00:00-10:00')</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-adjust-dateTime-to-timezone-tz10">
               <fos:expression>fn:adjust-dateTime-to-timezone(xs:dateTime('2002-03-07T10:00:00-07:00'),
                  $tz-10)</fos:expression>
               <fos:result>xs:dateTime('2002-03-07T07:00:00-10:00')</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:adjust-dateTime-to-timezone(xs:dateTime('2002-03-07T10:00:00-07:00'),
                  xs:dayTimeDuration("PT10H"))</fos:expression>
               <fos:result>xs:dateTime('2002-03-08T03:00:00+10:00')</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:adjust-dateTime-to-timezone(xs:dateTime('2002-03-07T00:00:00+01:00'),
                  xs:dayTimeDuration("-PT8H"))</fos:expression>
               <fos:result>xs:dateTime('2002-03-06T15:00:00-08:00')</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:adjust-dateTime-to-timezone(xs:dateTime('2002-03-07T10:00:00'),
                  ())</fos:expression>
               <fos:result>xs:dateTime('2002-03-07T10:00:00')</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:adjust-dateTime-to-timezone(xs:dateTime('2002-03-07T10:00:00-07:00'),
                  ())</fos:expression>
               <fos:result>xs:dateTime('2002-03-07T10:00:00')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="adjust-date-to-timezone" prefix="fn">
      <fos:signatures>
         <fos:proto name="adjust-date-to-timezone" return-type="xs:date?">
            <fos:arg name="arg" type="xs:date?"/>
         </fos:proto>
         <fos:proto name="adjust-date-to-timezone" return-type="xs:date?">
            <fos:arg name="arg" type="xs:date?"/>
            <fos:arg name="timezone" type="xs:dayTimeDuration?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Adjusts an <code>xs:date</code> value to a specific timezone, or to no timezone at all;
            the result is the date in the target timezone that contains the starting instant of the
            supplied date.</p>
      </fos:summary>
      <fos:rules>
         <p> If <code>$timezone</code> is not specified, then the effective value of
               <code>$timezone</code> is the value of the implicit timezone in the dynamic
            context.</p>
         <p> If <code>$arg</code> is the empty sequence, then the function returns the empty
            sequence.</p>
         <p> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is
            the empty sequence, then the result is the value of <code>$arg</code>.</p>
         <p> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is
            not the empty sequence, then the result is <code>$arg</code> with <code>$timezone</code>
            as the timezone component.</p>
         <p> If <code>$arg</code> has a timezone component and <code>$timezone</code> is the empty
            sequence, then the result is the local value of <code>$arg</code> without its timezone
            component.</p>
         <p> If <code>$arg</code> has a timezone component and <code>$timezone</code> is not the
            empty sequence, then the function returns the value of the expression:</p>
         <ulist>
            <item>
               <p>Let <code>$dt</code> be the value of <code>fn:dateTime($arg,
                     xs:time('00:00:00'))</code>.</p>
            </item>
            <item>
               <p>Let <code>$adt</code> be the value of <code>fn:adjust-dateTime-to-timezone($dt,
                     $timezone)</code></p>
            </item>
            <item>
               <p>The function returns the value of <code>xs:date($adt)</code></p>
            </item>
         </ulist>
         <!--<ednote>
            <edtext>I suspect this procedure actually gives the right result in all cases, so the
               whole description can be simplified.</edtext>
         </ednote>-->
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="DT" code="0003"/> if <code>$timezone</code>
            is less than <code>-PT14H</code> or greater than <code>PT14H</code> or is not an
            integral number of minutes.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <p>Assume the dynamic context provides an implicit timezone of <code>-05:00
                  (-PT5H0M)</code>.</p>
         </fos:example>
         <fos:variable  id="v-adjust-date-to-timezone-tz10" name="tz-10" select="xs:dayTimeDuration(&quot;-PT10H&quot;)"/>
         <fos:example>
            <fos:test implicit-timezone="-PT5H">
               <fos:expression>fn:adjust-date-to-timezone(xs:date("2002-03-07"))</fos:expression>
               <fos:result>xs:date("2002-03-07-05:00")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test implicit-timezone="-PT5H">
               <fos:expression>fn:adjust-date-to-timezone(xs:date("2002-03-07-07:00"))</fos:expression>
               <fos:result>xs:date("2002-03-07-05:00")</fos:result>
               <fos:postamble><code>$arg</code> is converted to
                     <code>xs:dateTime("2002-03-07T00:00:00-07:00")</code>. This is adjusted to the
                  implicit timezone, giving <code>"2002-03-07T02:00:00-05:00"</code>.
               </fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-adjust-date-to-timezone-tz10">
               <fos:expression>fn:adjust-date-to-timezone(xs:date("2002-03-07"),
                  $tz-10)</fos:expression>
               <fos:result>xs:date("2002-03-07-10:00")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-adjust-date-to-timezone-tz10">
               <fos:expression>fn:adjust-date-to-timezone(xs:date("2002-03-07-07:00"),
                  $tz-10)</fos:expression>
               <fos:result>xs:date("2002-03-06-10:00")</fos:result>
               <fos:postamble><code>$arg</code> is converted to the <code>xs:dateTime
                     "2002-03-07T00:00:00-07:00"</code>. This is adjusted to the given timezone,
                  giving <code>"2002-03-06T21:00:00-10:00"</code>. </fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:adjust-date-to-timezone(xs:date("2002-03-07"),
                  ())</fos:expression>
               <fos:result>xs:date("2002-03-07")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:adjust-date-to-timezone(xs:date("2002-03-07-07:00"),
                  ())</fos:expression>
               <fos:result>xs:date("2002-03-07")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="adjust-time-to-timezone" prefix="fn">
      <fos:signatures>
         <fos:proto name="adjust-time-to-timezone" return-type="xs:time?">
            <fos:arg name="arg" type="xs:time?"/>
         </fos:proto>
         <fos:proto name="adjust-time-to-timezone" return-type="xs:time?">
            <fos:arg name="arg" type="xs:time?"/>
            <fos:arg name="timezone" type="xs:dayTimeDuration?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Adjusts an <code>xs:time</code> value to a specific timezone, or to no timezone at
            all.</p>
      </fos:summary>
      <fos:rules>
         <p> If <code>$timezone</code> is not specified, then the effective value of
               <code>$timezone</code> is the value of the implicit timezone in the dynamic
            context.</p>
         <p> If <code>$arg</code> is the empty sequence, then the function returns the empty
            sequence.</p>
         <p> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is
            the empty sequence, then the result is <code>$arg</code>.</p>
         <p> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is
            not the empty sequence, then the result is <code>$arg</code> with <code>$timezone</code>
            as the timezone component.</p>
         <p> If <code>$arg</code> has a timezone component and <code>$timezone</code> is the empty
            sequence, then the result is the localized value of <code>$arg</code> without its
            timezone component.</p>
         <p> If <code>$arg</code> has a timezone component and <code>$timezone</code> is not the
            empty sequence, then:</p>
         <ulist>
            <item>
               <p>Let <code>$dt</code> be the <code>xs:dateTime</code> value
                     <code>fn:dateTime(xs:date('1972-12-31'), $arg)</code>.</p>
            </item>
            <item>
               <p>Let <code>$adt</code> be the value of <code>fn:adjust-dateTime-to-timezone($dt,
                     $timezone)</code>
               </p>
            </item>
            <item>
               <p>The function returns the <code>xs:time</code> value
                  <code>xs:time($adt)</code>.</p>
            </item>
         </ulist>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="DT" code="0003"/> if <code>$timezone</code>
            is less than <code>-PT14H</code> or greater than <code>PT14H</code> or if does not
            contain an integral number of minutes.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <p>Assume the dynamic context provides an implicit timezone of <code>-05:00
                  (-PT5H0M)</code>.</p>
         </fos:example>
         <fos:variable  id="v-adjust-time-to-timezone-tz10" name="tz-10" select="xs:dayTimeDuration(&quot;-PT10H&quot;)"/>
         <fos:example>
            <fos:test implicit-timezone="-PT5H">
               <fos:expression>fn:adjust-time-to-timezone(xs:time("10:00:00"))</fos:expression>
               <fos:result>xs:time("10:00:00-05:00")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:adjust-time-to-timezone(xs:time("10:00:00-07:00"))</fos:expression>
               <fos:result>xs:time("12:00:00-05:00")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-adjust-time-to-timezone-tz10">
               <fos:expression>fn:adjust-time-to-timezone(xs:time("10:00:00"),
                  $tz-10)</fos:expression>
               <fos:result>xs:time("10:00:00-10:00")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-adjust-time-to-timezone-tz10">
               <fos:expression>fn:adjust-time-to-timezone(xs:time("10:00:00-07:00"),
                  $tz-10)</fos:expression>
               <fos:result>xs:time("07:00:00-10:00")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:adjust-time-to-timezone(xs:time("10:00:00"), ())</fos:expression>
               <fos:result>xs:time("10:00:00")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:adjust-time-to-timezone(xs:time("10:00:00-07:00"),
                  ())</fos:expression>
               <fos:result>xs:time("10:00:00")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:adjust-time-to-timezone(xs:time("10:00:00-07:00"),
                  xs:dayTimeDuration("PT10H"))</fos:expression>
               <fos:result>xs:time("03:00:00+10:00")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="subtract-dateTimes" prefix="op">
      <fos:signatures>
         <fos:proto name="subtract-dateTimes" return-type="xs:dayTimeDuration">
            <fos:arg name="arg1" type="xs:dateTime"/>
            <fos:arg name="arg2" type="xs:dateTime"/>
         </fos:proto>
      </fos:signatures>

      <fos:opermap operator="-" types="xs:dateTime numeric">Defines the semantics of the "-"
         operator when applied to two <code>xs:dateTime</code> values.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns an <code>xs:dayTimeDuration</code> representing the amount of elapsed time
            between the instants <code>arg2</code> and <code>arg1</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If either <code>$arg1</code> or <code>$arg2</code> do not contain an explicit timezone
            then, for the purpose of the operation, the implicit timezone provided by the dynamic
            context (See <xspecref spec="XP31" ref="id-xp-evaluation-context-components"/>.) is
            assumed to be present as part of the value.</p>
         <p>The function returns the elapsed time between the date/time instant <code>arg2</code>
            and the date/time instant <code>arg1</code>, computed according to the algorithm given
            in Appendix E of <bibref ref="xmlschema-2"/>, and expressed as a
               <code>xs:dayTimeDuration</code>.</p>
         <p>If the normalized value of <code>$arg1</code> precedes in time the normalized value of
               <code>$arg2</code>, then the returned value is a negative duration.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <p>Assume that the dynamic context provides an implicit timezone value of
                  <code>-05:00</code>.</p>
         </fos:example>
         <fos:example>
            <fos:test implicit-timezone="-PT5H">
               <fos:expression>op:subtract-dateTimes(xs:dateTime("2000-10-30T06:12:00"),
                  xs:dateTime("1999-11-28T09:00:00Z"))</fos:expression>
               <fos:result>xs:dayTimeDuration("P337DT2H12M")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="subtract-dates" prefix="op">
      <fos:signatures>
         <fos:proto name="subtract-dates" return-type="xs:dayTimeDuration">
            <fos:arg name="arg1" type="xs:date"/>
            <fos:arg name="arg2" type="xs:date"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="-" types="xs:date numeric">Defines the semantics of the "-" operator
         when applied to two <code>xs:date</code> values.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the <code>xs:dayTimeDuration</code> that corresponds to the elapsed time between
            the starting instant of <code>$arg2</code> and the starting instant of
               <code>$arg2</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If either <code>$arg1</code> or <code>$arg2</code> do not contain an explicit timezone
            then, for the purpose of the operation, the implicit timezone provided by the dynamic
            context (See <xspecref spec="XP31" ref="id-xp-evaluation-context-components"/>.) is
            assumed to be present as part of the value.</p>
         <p>The starting instant of an <code>xs:date</code> is the <code>xs:dateTime</code> at
               <code>00:00:00</code> on that date. </p>
         <p>The function returns the result of subtracting the two starting instants using
               <code>op:subtract-dateTimes</code>.</p>
         <p>If the starting instant of <code>$arg1</code> precedes in time the starting instant of
               <code>$arg2</code>, then the returned value is a negative duration.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <p>Assume that the dynamic context provides an implicit timezone value of
               <code>Z</code>. </p>
         </fos:example>
         <fos:example>
            <fos:test implicit-timezone="PT0S">
               <fos:expression>op:subtract-dates(xs:date("2000-10-30"),
                  xs:date("1999-11-28"))</fos:expression>
               <fos:result>xs:dayTimeDuration("P337D")</fos:result>
               <fos:postamble>The normalized values of the two starting instants are <code>{2000,
                     10, 30, 0, 0, 0, PT0S}</code> and <code>{1999, 11, 28, 0, 0, 0,
                  PT0S}</code>.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>Now assume that the dynamic context provides an implicit timezone value of
                  <code>+05:00</code>.</p>
         </fos:example>
         <fos:example>
            <fos:test implicit-timezone="PT5H">
               <fos:expression>op:subtract-dates(xs:date("2000-10-30"),
                  xs:date("1999-11-28Z"))</fos:expression>
               <fos:result>xs:dayTimeDuration("P336DT19H")</fos:result>
               <fos:postamble> The normalized values of the two starting instants are <code>{2000,
                     10, 29, 19, 0, 0, PT0S}</code> and <code>{1999, 11, 28, 0, 0, 0,
                  PT0S}</code>.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-dates(xs:date("2000-10-15-05:00"),
                  xs:date("2000-10-10+02:00"))</fos:expression>
               <fos:result>xs:dayTimeDuration("P5DT7H")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="subtract-times" prefix="op">
      <fos:signatures>
         <fos:proto name="subtract-times" return-type="xs:dayTimeDuration">
            <fos:arg name="arg1" type="xs:time"/>
            <fos:arg name="arg2" type="xs:time"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="-" types="xs:time numeric">Defines the semantics of the "-" operator
         when applied to two <code>xs:time</code> values.</fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the <code>xs:dayTimeDuration</code> that corresponds to the elapsed time between
            the values of <code>$arg2</code> and <code>$arg1</code> treated as times on the same
            date.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of the expression:</p>
         <eg xml:space="preserve">op-subtract-dateTimes(
        fn:dateTime(xs:date('1972-12-31'), $arg1),
        fn:dateTime(xs:date('1972-12-31'), $arg2))</eg>
      </fos:rules>
      <fos:notes>
         <p>Any other reference date would work equally well.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p>Assume that the dynamic context provides an implicit timezone value of
                  <code>-05:00</code>. Assume, also, that the date components of the reference
                  <code>xs:dateTime</code> correspond to <code>"1972-12-31"</code>.</p>
         </fos:example>
         <fos:example>
            <fos:test implicit-timezone="-PT5H">
               <fos:expression>op:subtract-times(xs:time("11:12:00Z"),
                  xs:time("04:00:00"))</fos:expression>
               <fos:result>xs:dayTimeDuration("PT2H12M")</fos:result>
               <fos:postamble>This is obtained by subtracting from the <code>xs:dateTime</code>
                  value <code>{1972, 12, 31, 11, 12, 0, PT0S}</code> the <code>xs:dateTime</code>
                  value <code>{1972, 12, 31, 9, 0, 0, PT0S}</code>.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-times(xs:time("11:00:00-05:00"),
                  xs:time("21:30:00+05:30"))</fos:expression>
               <fos:result>xs:dayTimeDuration("PT0S")</fos:result>
               <fos:postamble>The two <code>xs:dateTime</code> values are <code>{1972, 12, 31, 11,
                     0, 0, -PT5H}</code> and <code>{1972, 12, 31, 21, 30, 0, PT5H30M}</code>. These
                  normalize to <code>{1972, 12, 31, 16, 0, 0, PT0S}</code> and <code>{1972, 12, 31,
                     16, 0, 0, PT0S}</code>. </fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-times(xs:time("17:00:00-06:00"),
                  xs:time("08:00:00+09:00"))</fos:expression>
               <fos:result>xs:dayTimeDuration("P1D")</fos:result>
               <fos:postamble>The two normalized <code>xs:dateTime</code> values are <code>{1972,
                     12, 31, 23, 0, 0, PT0S}</code> and <code>{1972, 12, 30, 23, 0, 0,
                  PT0S}</code>.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-times(xs:time("24:00:00"),
                  xs:time("23:59:59"))</fos:expression>
               <fos:result>xs:dayTimeDuration("-PT23H59M59S")</fos:result>
               <fos:postamble>The two normalized <code>xs:dateTime</code> values are <code>{1972,
                     12, 31, 0, 0, 0, ()}</code> and <code>{1972, 12, 31, 23, 59, 59.0,
                  ()}</code>.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="add-yearMonthDuration-to-dateTime" prefix="op">
      <fos:signatures>
         <fos:proto name="add-yearMonthDuration-to-dateTime" return-type="xs:dateTime">
            <fos:arg name="arg1" type="xs:dateTime"/>
            <fos:arg name="arg2" type="xs:yearMonthDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="+" types="xs:dateTime xs:yearMonthDuration numeric">Defines the
         semantics of the "+" operator when applied to an <code>xs:dateTime</code> and an
            <code>xs:yearMonthDuration</code> value. </fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the <code>xs:dateTime</code> that is a given duration after a specified
               <code>xs:dateTime</code> (or before, if the duration is negative).</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of adding <code>$arg2</code> to the value of
               <code>$arg1</code> using the algorithm described in Appendix E of <bibref
               ref="xmlschema-2"/>, disregarding the rule about leap seconds. If <code>$arg2</code>
            is negative, then the result <code>xs:dateTime</code> precedes <code>$arg1</code>.</p>
         <p>The result has the same timezone as <code>$arg1</code>. If <code>$arg1</code> has no
            timezone, the result has no timezone. </p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:add-yearMonthDuration-to-dateTime(xs:dateTime("2000-10-30T11:12:00"),
                  xs:yearMonthDuration("P1Y2M"))</fos:expression>
               <fos:result>xs:dateTime("2001-12-30T11:12:00")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="add-dayTimeDuration-to-dateTime" prefix="op">
      <fos:signatures>
         <fos:proto name="add-dayTimeDuration-to-dateTime" return-type="xs:dateTime">
            <fos:arg name="arg1" type="xs:dateTime"/>
            <fos:arg name="arg2" type="xs:dayTimeDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="+" types="xs:dateTime xs:dayTimeDuration numeric">Defines the semantics
         of the "+" operator when applied to an <code>xs:dateTime</code> and an
            <code>xs:dayTimeDuration</code> value. </fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the <code>xs:dateTime</code> that is a given duration after a specified
               <code>xs:dateTime</code> (or before, if the duration is negative).</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of adding <code>$arg2</code> to the value of
               <code>$arg1</code> using the algorithm described in Appendix E of <bibref
               ref="xmlschema-2"/>, disregarding the rule about leap seconds. If <code>$arg2</code>
            is negative, then the result <code>xs:dateTime</code> precedes <code>$arg1</code>.</p>
         <p>The result has the same timezone as <code>$arg1</code>. If <code>$arg1</code> has no
            timezone, the result has no timezone. </p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:add-dayTimeDuration-to-dateTime(xs:dateTime("2000-10-30T11:12:00"),
                  xs:dayTimeDuration("P3DT1H15M"))</fos:expression>
               <fos:result>xs:dateTime("2000-11-02T12:27:00")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="subtract-yearMonthDuration-from-dateTime" prefix="op">
      <fos:signatures>
         <fos:proto name="subtract-yearMonthDuration-from-dateTime" return-type="xs:dateTime">
            <fos:arg name="arg1" type="xs:dateTime"/>
            <fos:arg name="arg2" type="xs:yearMonthDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="-" types="xs:dateTime xs:yearMonthDuration numeric">Defines the
         semantics of the "-" operator when applied to an <code>xs:dateTime</code> and an
            <code>xs:yearMonthDuration</code> value. </fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the <code>xs:dateTime</code> that is a given duration before a specified
               <code>xs:dateTime</code> (or after, if the duration is negative).</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the <code>xs:dateTime</code> computed by negating
               <code>$arg2</code> and adding the result to the value of <code>$arg1</code> using the
            function <code>op:add-yearMonthDuration-to-dateTime</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-yearMonthDuration-from-dateTime(xs:dateTime("2000-10-30T11:12:00"),
                  xs:yearMonthDuration("P1Y2M"))</fos:expression>
               <fos:result>xs:dateTime("1999-08-30T11:12:00")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="subtract-dayTimeDuration-from-dateTime" prefix="op">
      <fos:signatures>
         <fos:proto name="subtract-dayTimeDuration-from-dateTime" return-type="xs:dateTime">
            <fos:arg name="arg1" type="xs:dateTime"/>
            <fos:arg name="arg2" type="xs:dayTimeDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="-" types="xs:dateTime xs:dayTimeDuration numeric">Defines the semantics
         of the "-" operator when applied to an <code>xs:dateTime</code> an and
            <code>xs:dayTimeDuration</code> values</fos:opermap>
      <fos:summary>
         <p>Returns the <code>xs:dateTime</code> that is a given duration before a specified
               <code>xs:dateTime</code> (or after, if the duration is negative).</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the <code>xs:dateTime</code> computed by negating
               <code>$arg2</code> and adding the result to the value of <code>$arg1</code> using the
            function <code>op:add-dayTimeDuration-to-dateTime</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-dayTimeDuration-from-dateTime(xs:dateTime("2000-10-30T11:12:00"),
                  xs:dayTimeDuration("P3DT1H15M"))</fos:expression>
               <fos:result>xs:dateTime("2000-10-27T09:57:00")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="add-yearMonthDuration-to-date" prefix="op">
      <fos:signatures>
         <fos:proto name="add-yearMonthDuration-to-date" return-type="xs:date">
            <fos:arg name="arg1" type="xs:date"/>
            <fos:arg name="arg2" type="xs:yearMonthDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="+" types="xs:date xs:yearMonthDuration numeric">Defines the semantics
         of the "+" operator when applied to an <code>xs:date</code> and an
            <code>xs:yearMonthDuration</code> value. </fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the <code>xs:date</code> that is a given duration after a specified
               <code>xs:date</code> (or before, if the duration is negative).</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of casting <code>$arg1</code> to an
               <code>xs:dateTime</code>, adding <code>$arg2</code> using the function
               <code>op:add-yearMonthDuration-to-dateTime</code>, and casting the result back to an
               <code>xs:date</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:add-yearMonthDuration-to-date(xs:date("2000-10-30"),
                  xs:yearMonthDuration("P1Y2M"))</fos:expression>
               <fos:result>xs:date("2001-12-30")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="add-dayTimeDuration-to-date" prefix="op">
      <fos:signatures>
         <fos:proto name="add-dayTimeDuration-to-date" return-type="xs:date">
            <fos:arg name="arg1" type="xs:date"/>
            <fos:arg name="arg2" type="xs:dayTimeDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="+" types="xs:date xs:dayTimeDuration numeric">Defines the semantics of
         the "+" operator when applied to an <code>xs:date</code> and an
            <code>xs:dayTimeDuration</code> value. </fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the <code>xs:date</code> that is a given duration after a specified
               <code>xs:date</code> (or before, if the duration is negative).</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of casting <code>$arg1</code> to an
               <code>xs:dateTime</code>, adding <code>$arg2</code> using the function
               <code>op:add-dayTimeDuration-to-dateTime</code>, and casting the result back to an
               <code>xs:date</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:add-dayTimeDuration-to-date(xs:date("2004-10-30Z"),
                  xs:dayTimeDuration("P2DT2H30M0S"))</fos:expression>
               <fos:result>xs:date("2004-11-01Z")</fos:result>
               <fos:postamble> The starting instant of the first argument is the
                     <code>xs:dateTime</code> value <code>{2004, 10, 30, 0, 0, 0, PT0S}</code>.
                  Adding the second argument to this gives the <code>xs:dateTime</code> value
                     <code>{2004, 11, 1, 2, 30, 0, PT0S}</code>. The time components are then
                  discarded. </fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="subtract-yearMonthDuration-from-date" prefix="op">
      <fos:signatures>
         <fos:proto name="subtract-yearMonthDuration-from-date" return-type="xs:date">
            <fos:arg name="arg1" type="xs:date"/>
            <fos:arg name="arg2" type="xs:yearMonthDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="-" types="xs:date xs:yearMonthDuration numeric">Defines the semantics
         of the "-" operator when applied to an <code>xs:date</code> and an
            <code>xs:yearMonthDuration</code> value. </fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the <code>xs:date</code> that is a given duration before a specified
               <code>xs:date</code> (or after, if the duration is negative).</p>
      </fos:summary>
      <fos:rules>
         <p>Returns the <code>xs:date</code> computed by negating <code>$arg2</code> and adding the
            result to <code>$arg1</code> using the function
               <code>op:add-yearMonthDuration-to-date</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-yearMonthDuration-from-date(xs:date("2000-10-30"),
                  xs:yearMonthDuration("P1Y2M"))</fos:expression>
               <fos:result>xs:date("1999-08-30")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-yearMonthDuration-from-date(xs:date("2000-02-29Z"),
                  xs:yearMonthDuration("P1Y"))</fos:expression>
               <fos:result>xs:date("1999-02-28Z")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-yearMonthDuration-from-date(xs:date("2000-10-31-05:00"),
                  xs:yearMonthDuration("P1Y1M"))</fos:expression>
               <fos:result>xs:date("1999-09-30-05:00")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="subtract-dayTimeDuration-from-date" prefix="op">
      <fos:signatures>
         <fos:proto name="subtract-dayTimeDuration-from-date" return-type="xs:date">
            <fos:arg name="arg1" type="xs:date"/>
            <fos:arg name="arg2" type="xs:dayTimeDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="-" types="xs:date xs:dayTimeDuration numeric">Defines the semantics of
         the "-" operator when applied to an <code>xs:date</code> and an
            <code>xs:dayTimeDuration</code>. </fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the <code>xs:date</code> that is a given duration before a specified
               <code>xs:date</code> (or after, if the duration is negative).</p>
      </fos:summary>
      <fos:rules>
         <p>Returns the <code>xs:date</code> computed by negating <code>$arg2</code> and adding the
            result to <code>$arg1</code> using the function
               <code>op:add-dayTimeDuration-to-date</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-dayTimeDuration-from-date(xs:date("2000-10-30"),
                  xs:dayTimeDuration("P3DT1H15M"))</fos:expression>
               <fos:result>xs:date("2000-10-26")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="add-dayTimeDuration-to-time" prefix="op">
      <fos:signatures>
         <fos:proto name="add-dayTimeDuration-to-time" return-type="xs:time">
            <fos:arg name="arg1" type="xs:time"/>
            <fos:arg name="arg2" type="xs:dayTimeDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="+" types="xs:time xs:dayTimeDuration numeric">Defines the semantics of
         the "+" operator when applied to an <code>xs:time</code> and an
            <code>xs:dayTimeDuration</code> value.</fos:opermap>
      <fos:summary>
         <p>Returns the <code>xs:time</code> value that is a given duration after a specified
               <code>xs:time</code> (or before, if the duration is negative or causes wrap-around
            past midnight)</p>
      </fos:summary>
      <fos:rules>
         <p>First, the days component in the canonical lexical representation of <code>$arg2</code>
            is set to zero (0) and the value of the resulting <code>xs:dayTimeDuration</code> is
            calculated. Alternatively, the value of <code>$arg2</code> modulus 86,400 is used as the
            second argument. This value is added to the value of <code>$arg1</code> converted to an
               <code>xs:dateTime</code> using a reference date such as <code>1972-12-31</code>, and
            the time component of the result is returned. Note that the <code>xs:time</code>
            returned may occur in a following or preceding day and may be less than
               <code>$arg1</code>.</p>
         <p>The result has the same timezone as <code>$arg1</code>. If <code>$arg1</code> has no
            timezone, the result has no timezone.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:add-dayTimeDuration-to-time(xs:time("11:12:00"),
                  xs:dayTimeDuration("P3DT1H15M"))</fos:expression>
               <fos:result>xs:time("12:27:00")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:add-dayTimeDuration-to-time(xs:time("23:12:00+03:00"),
                  xs:dayTimeDuration("P1DT3H15M"))</fos:expression>
               <fos:result>xs:time("02:27:00+03:00")</fos:result>
               <fos:postamble>That is, <code>{0, 0, 0, 2, 27, 0, PT3H}</code></fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="subtract-dayTimeDuration-from-time" prefix="op">
      <fos:signatures>
         <fos:proto name="subtract-dayTimeDuration-from-time" return-type="xs:time">
            <fos:arg name="arg1" type="xs:time"/>
            <fos:arg name="arg2" type="xs:dayTimeDuration"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="-" types="xs:time xs:dayTimeDuration numeric">Defines the semantics of
         the "-" operator when applied to an <code>xs:time</code> and an
            <code>xs:dayTimeDuration</code> value. </fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the <code>xs:time</code> value that is a given duration before a specified
               <code>xs:time</code> (or after, if the duration is negative or causes wrap-around
            past midnight)</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of negating <code>$arg2</code> and adding the result to
               <code>$arg1</code> using the function <code>op:add-dayTimeDuration-to-time</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-dayTimeDuration-from-time(xs:time("11:12:00"),
                  xs:dayTimeDuration("P3DT1H15M"))</fos:expression>
               <fos:result>xs:time("09:57:00")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>op:subtract-dayTimeDuration-from-time(xs:time("08:20:00-05:00"),
                  xs:dayTimeDuration("P23DT10H10M"))</fos:expression>
               <fos:result>xs:time("22:10:00-05:00")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="format-dateTime" prefix="fn">
      <fos:signatures>
         <fos:proto name="format-dateTime" return-type="xs:string?">
            <fos:arg name="value" type="xs:dateTime?"/>
            <fos:arg name="picture" type="xs:string"/>
         </fos:proto>
         <fos:proto name="format-dateTime" return-type="xs:string?">
            <fos:arg name="value" type="xs:dateTime?"/>
            <fos:arg name="picture" type="xs:string"/>
            <fos:arg name="language" type="xs:string?"/>
            <fos:arg name="calendar" type="xs:string?"/>
            <fos:arg name="place" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="default-calendar default-language default-place implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="5">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone namespaces">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a string containing an <code>xs:dateTime</code> value formatted for display.</p>
      </fos:summary>
      <fos:rules>
         <p>See <specref ref="rules-for-datetime-formatting"/>.</p>
      </fos:rules>
   </fos:function>
   <fos:function name="format-date" prefix="fn">
      <fos:signatures>
         <fos:proto name="format-date" return-type="xs:string?">
            <fos:arg name="value" type="xs:date?"/>
            <fos:arg name="picture" type="xs:string"/>
         </fos:proto>
         <fos:proto name="format-date" return-type="xs:string?">
            <fos:arg name="value" type="xs:date?"/>
            <fos:arg name="picture" type="xs:string"/>
            <fos:arg name="language" type="xs:string?"/>
            <fos:arg name="calendar" type="xs:string?"/>
            <fos:arg name="place" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="default-calendar default-language default-place implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="5">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone namespaces">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a string containing an <code>xs:date</code> value formatted for display.</p>
      </fos:summary>
      <fos:rules>
         <p>See <specref ref="rules-for-datetime-formatting"/>.</p>
      </fos:rules>
   </fos:function>
   <fos:function name="format-time" prefix="fn">
      <fos:signatures>
         <fos:proto name="format-time" return-type="xs:string?">
            <fos:arg name="value" type="xs:time?"/>
            <fos:arg name="picture" type="xs:string"/>
         </fos:proto>
         <fos:proto name="format-time" return-type="xs:string?">
            <fos:arg name="value" type="xs:time?"/>
            <fos:arg name="picture" type="xs:string"/>
            <fos:arg name="language" type="xs:string?"/>
            <fos:arg name="calendar" type="xs:string?"/>
            <fos:arg name="place" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="default-calendar default-language default-place implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="5">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone namespaces">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a string containing an <code>xs:time</code> value formatted for display.</p>
      </fos:summary>
      <fos:rules>
         <p>See <specref ref="rules-for-datetime-formatting"/>.</p>
      </fos:rules>
   </fos:function>

   <fos:function name="parse-ietf-date"  prefix="fn" diff="add" at="A">
      <fos:signatures>
         <fos:proto name="parse-ietf-date" return-type="xs:dateTime?">
            <fos:arg name="value" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>

      <fos:summary>
         <p>Parses a string containing the date and time in IETF format, returning the corresponding
               <code>xs:dateTime</code> value.</p>
      </fos:summary>
      <fos:rules>
         <p>The function accepts a string matching the production <code>input</code> in the
            following grammar:</p>
         <table role="scrap">
            <tr>
               <td>
                  <code>input</code>
               </td>
               <td><code>::=</code></td>
               <td diff="chg" at="B">
                  <code>S? (dayname ","? S)? ((datespec S time) | asctime) S?</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>dayname</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code>"Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | "Sun" | "Monday | "Tuesday"
                     | "Wednesday" | "Thursday" | "Friday" | "Saturday" | "Sunday"</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>datespec</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code>daynum dsep monthname dsep year</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>asctime</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code>monthname dsep daynum S time S year</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>dsep</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code>S | (S? "-" S?)</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>daynum</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code>digit digit?</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>year</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code>digit digit (digit digit)?</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>digit</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code>[0-9]</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>monthname</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code>"Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" | "Jul" | "Aug" | "Sep" |
                     "Oct" | "Nov" | "Dec"</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>time</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code>hours ":" minutes (":" seconds)? (S? timezone)?</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>hours</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <phrase diff="chg" at="E"><code>digit digit?</code></phrase>
               </td>
            </tr>
            <tr>
               <td>
                  <code>minutes</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code>digit digit</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>seconds</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code>digit digit ("." digit+)?</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>timezone</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code>tzname | tzoffset (S? "(" S? tzname S? ")")?</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>tzname</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code>"UT" | "UTC" | "GMT" | "EST" | "EDT" | "CST" | "CDT" | "MST" | "MDT" | "PST"
                     | "PDT" </code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>tzoffset</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <phrase diff="chg" at="E"><code>("+"|"-") hours ":"? minutes?</code></phrase>
               </td>
            </tr>
            <tr>
               <td>
                  <code>S</code>
               </td>
               <td><code>::=</code></td>
               <td>
                  <code diff="chg" at="C">( x09 | x0A | x0D | x20 )+</code>
               </td>
            </tr>
         </table>

         <p>The input is case-insensitive: upper-case and lower-case distinctions in the above
            grammar show the conventional usage, but otherwise have no significance.</p>
         <p diff="add" at="D">If the input is an empty sequence, the result is an empty sequence.</p>
         <p>The <code>dayname</code>, if present, is ignored.</p>
         <p>The <code>daynum</code>, <code>monthname</code>, and <code>year</code> supply the day,
            month, and year of the resulting <code>xs:dateTime</code> value. A two-digit year
               <rfc2119>must</rfc2119> have 1900 added to it. A year such as 0070 is to be treated
            as given; negative years are not permitted.</p>
         <p>The <code>hours</code>, <code>minutes</code>, and <code>seconds</code> (including
            fractional seconds) values supply the corresponding components of the resulting
               <code>xs:dateTime</code> value; if the <code>seconds</code> value 
            <phrase diff="add" at="E">or the fractional seconds value</phrase> is absent then zero
            is assumed.</p>
         <p>If both a <code>tzoffset</code> and a <code>tzname</code> are supplied then the
               <code>tzname</code> is ignored.</p>
         <p>If a <code>tzoffset</code> is supplied then this defines the hours and minutes parts of the timezone offset:</p>
         <ulist diff="chg" at="E">
            <item><p>If it contains a colon, this separates the hours part from the minutes part.</p></item>
            <item><p>Otherwise, the grammar allows a sequence of from one to four digits. These are interpreted
            as <code>H</code>, <code>HH</code>, <code>HMM</code>, or <code>HHMM</code> respectively, where <code>H</code>
            or <code>HH</code> is the hours part, and <code>MM</code> (if present) is the minutes part.</p></item>
            <item>If the minutes part is absent it defaults to <code>00</code>.</item>
         </ulist>
         
         <p>If a <code>tzname</code> is supplied with no <code>tzoffset</code> then it is translated
            to a timezone offset as follows:</p>
         <table class="data">
            <thead>
               <tr>
                  <th>tzname</th>
                  <th>Offset</th>
               </tr>
            </thead>
            <tbody>
               <tr>
                  <td>UT, UTC, GMT</td>
                  <td>00:00</td>
               </tr>
               <tr>
                  <td>EST</td>
                  <td>-05:00</td>
               </tr>
               <tr>
                  <td>EDT</td>
                  <td>-04:00</td>
               </tr>
               <tr>
                  <td>CST</td>
                  <td>-06:00</td>
               </tr>
               <tr>
                  <td>CDT</td>
                  <td>-05:00</td>
               </tr>
               <tr>
                  <td>MST</td>
                  <td>-07:00</td>
               </tr>
               <tr>
                  <td>MDT</td>
                  <td>-06:00</td>
               </tr>
               <tr>
                  <td>PST</td>
                  <td>-08:00</td>
               </tr>
               <tr>
                  <td>PDT</td>
                  <td>-07:00</td>
               </tr>
            </tbody>
         </table>
         <p>If neither a <code>tzoffset</code> nor <code>tzname</code> is supplied, a timezone
            offset of <code>00:00</code> is assumed.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref spec="FO" class="RG" code="0010"/> if the input does
            not match the grammar, or if the resulting date/time value is invalid (for example, 31
            February).</p>
      </fos:errors>
      <fos:notes>
         <p>The <code>parse-ietf-date</code> function attempts to interpret its input as a date
            in any of the three formats specified by HTTP <bibref ref="rfc2616"/>.</p>

         <p>These formats are used widely on the Internet to represent timestamps, and were
            specified in:</p>
         <ulist>
            <item><bibref ref="rfc822"/> (electronic mail), extended in <bibref ref="rfc1123"/> to allow four-digit years;</item>
            <item><bibref ref="rfc850"/> (Usenet Messages), obsoleted by <bibref ref="rfc1036"/>;</item>
            <item>POSIX <code>asctime()</code> format</item>
         </ulist>
         <p><bibref ref="rfc2616"/> (HTTP) officially uses a subset of those three formats restricted to GMT.</p>

         <p diff="chg" at="E">The grammar for this function is slightly more liberal than the RFCs (reflecting the internet tradition of being liberal in what is accepted).
            For example the function:</p>

         <olist>
            <item>
               <p>Accepts a single-digit value where appropriate in place of a two-digit value with a leading zero (so
                  "Wed 1 Jun" is acceptable in place of "Wed 01 Jun", <phrase diff="add" at="E">and the timezone offset "-5:00" is equivalent
                  to "-05:00")</phrase></p>
            </item>
            <item>
               <p>Accepts one or more whitespace characters (x20, x09, x0A, x0D) wherever a single
                  space is required, and allows whitespace to be omitted where it is not required
                  for parsing</p>
            </item>
            <item>
               <p>Accepts and ignores whitespace characters (x20, x09, x0A, x0D) at the start or end
                  of the string.</p>
            </item>
         </olist>

         <p>In new protocols IETF recommends the format of <bibref ref="rfc3339"/> which is based on a profile of
            ISO 8601 similar to that already used in XPath and XSD, but the "approximate" <bibref ref="rfc822"/>
            format described here is very widely used.</p>

         <p>An <bibref ref="rfc1123"/> date can be generated approximately using <code>fn:format-dateTime</code> with a picture
            string of <code>"[FNn3], [D01] [MNn3] [Y04] [H01]:[m01]:[s01] [Z0000]"</code>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:parse-ietf-date("Wed, 06 Jun 1994 07:29:35 GMT")</fos:expression>
               <fos:result>xs:dateTime("1994-06-06T07:29:35Z")</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:parse-ietf-date("Wed, 6 Jun 94 07:29:35 GMT")</fos:expression>
               <fos:result>xs:dateTime("1994-06-06T07:29:35Z")</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:parse-ietf-date("Wed Jun 06 11:54:45 EST 2013")</fos:expression>
               <fos:result>xs:dateTime("2013-06-06T11:54:45-05:00")</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:parse-ietf-date("Sunday, 06-Nov-94 08:49:37 GMT")</fos:expression>
               <fos:result>xs:dateTime("1994-11-06T08:49:37Z")</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:parse-ietf-date("Wed, 6 Jun 94 07:29:35 +0500")</fos:expression>
               <fos:result>xs:dateTime("1994-06-06T07:29:35+05:00")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>

   </fos:function>

   <fos:function name="resolve-QName" prefix="fn">
      <fos:signatures>
         <fos:proto name="resolve-QName" return-type="xs:QName?">
            <fos:arg name="qname" type="xs:string?"/>
            <fos:arg name="element" type="element()" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns an <code>xs:QName</code> value (that is, an expanded-QName) by taking an
               <code>xs:string</code> that has the lexical form of an <code>xs:QName</code> (a
            string in the form "prefix:local-name" or "local-name") and resolving it using the
            in-scope namespaces for a given element.</p>
      </fos:summary>
      <fos:rules>

         <p>If <code>$qname</code> is the empty sequence, returns the empty sequence.</p>
         <p>More specifically, the function searches the namespace bindings of <code>$element</code>
            for a binding whose name matches the prefix of <code>$qname</code>, or the zero-length
            string if it has no prefix, and returns an expanded-QName whose local name is taken
            from the supplied <code>$qname</code>, and whose namespace URI is taken from the string
            value of the namespace binding.</p>

         <p>If the <code>$qname</code> has no prefix, and there is no namespace binding for
               <code>$element</code> corresponding to the default (unnamed) namespace, then the
            resulting expanded-QName has no namespace part.</p>
         <p>The prefix (or absence of a prefix) in the supplied <code>$qname</code> argument is
            retained in the returned expanded-QName, as described in <xspecref spec="DM31"
               ref="terminology"/>.</p>

      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="CA" code="0002"/> if <code>$qname</code> does
            not have the correct lexical form for an instance of <code>xs:QName</code>.</p>
         <p>A dynamic error is raised <errorref class="NS" code="0004"/> if <code>$qname</code> has
            a prefix and there is no namespace binding for <code>$element</code> that matches this
            prefix.</p>
      </fos:errors>
      <fos:notes>
         <p>Sometimes the requirement is to construct an <code>xs:QName</code> without using the
            default namespace. This can be achieved by writing:</p>
         <eg xml:space="preserve"> if (contains($qname, ":")) then fn:resolve-QName($qname, $element) else
            fn:QName("", $qname)</eg>
         <p>If the requirement is to construct an <code>xs:QName</code> using the namespaces in the
            static context, then the <code>xs:QName</code> constructor should be used.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p>Assume that the element bound to <code>$element</code> has a single namespace binding
               bound to the prefix <code>eg</code>.</p>
         </fos:example>

         <fos:example>
            <p>
               <code>fn:resolve-QName("hello", $element)</code> returns a QName with local name
               "hello" that is in no namespace.</p>
         </fos:example>
         <fos:example>
            <p>
               <code>fn:resolve-QName("eg:myFunc", $element)</code> returns an <code>xs:QName</code>
               whose namespace URI is specified by the namespace binding corresponding to the prefix
               "eg" and whose local name is "myFunc".</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="QName" prefix="fn">
      <fos:signatures>
         <fos:proto name="QName" return-type="xs:QName">
            <fos:arg name="paramURI" type="xs:string?"/>
            <fos:arg name="paramQName" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p diff="chg" at="C">Returns an <code>xs:QName</code> value formed using a supplied namespace URI and lexical QName.</p>
      </fos:summary>
      <fos:rules>
         <p>The namespace URI in the returned QName is taken from <code>$paramURI</code>. If
               <code>$paramURI</code> is the zero-length string or the empty sequence, it represents
            "no namespace".</p>
         <p>The prefix (or absence of a prefix) in <code>$paramQName</code> is retained in the
            returned <code>xs:QName</code> value.</p>
         <p>The local name in the result is taken from the local part of
            <code>$paramQName</code>.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="CA" code="0002"/> if <code>$paramQName</code>
            does not have the correct lexical form for an instance of <code>xs:QName</code>.</p>
         <p>A dynamic error is raised <errorref class="CA" code="0002"/> if <code>$paramURI</code>
            is the zero-length string or the empty sequence, and the value of
               <code>$paramQName</code> contains a colon (<code>:</code>).</p>
         <p>A dynamic error <rfc2119>may</rfc2119> be raised <errorref class="CA" code="0002"/> if
               <code>$paramURI</code> is not a valid URI (XML Namespaces 1.0) or IRI (XML Namespaces
            1.1). </p>
      </fos:errors>

      <fos:examples>
         <fos:example>
            <p>
               <code>fn:QName("http://www.example.com/example", "person")</code> returns an
                  <code>xs:QName</code> with namespace URI = "http://www.example.com/example", local
               name = "person" and prefix = "".</p>
         </fos:example>
         <fos:example>
            <p>
               <code>fn:QName("http://www.example.com/example", "ht:person")</code> returns an
                  <code>xs:QName</code> with namespace URI = "http://www.example.com/example", local
               name = "person" and prefix = "ht".</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="QName-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="QName-equal" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:QName"/>
            <fos:arg name="arg2" type="xs:QName"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="eq" types="xs:QName numeric" other-operators="ne">Defines the semantics
         of the "eq" and "ne" operators when applied to two values of type <code>xs:QName</code>. </fos:opermap>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns <code>true</code> if two supplied QNames have the same namespace URI and the
            same local part.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns <code>true</code> if the namespace URIs of <code>$arg1</code> and
               <code>$arg2</code> are equal and the local names of <code>$arg1</code> and
               <code>$arg2</code> are equal.</p>
         <p>Otherwise, the function returns <code>false</code>.</p>
         <p>The namespace URI parts are considered equal if they are both <xtermref ref="dt-absent"
               spec="DM31">absent</xtermref>, or if they are both present and equal under the rules
            of the <code>fn:codepoint-equal</code> function.</p>
         <p>The local parts are also compared under the rules of the <code>fn:codepoint-equal</code>
            function.</p>
      </fos:rules>
      <fos:notes>
         <p>The prefix parts of <code>$arg1</code> and <code>$arg2</code>, if any, are ignored.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="prefix-from-QName" prefix="fn">
      <fos:signatures>
         <fos:proto name="prefix-from-QName" return-type="xs:NCName?">
            <fos:arg name="arg" type="xs:QName?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the prefix component of the supplied QName.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence the function returns the empty sequence.</p>
         <p>If <code>$arg</code> has no prefix component the function returns the empty
            sequence.</p>
         <p>Otherwise, the function returns an <code>xs:NCName</code> representing the prefix
            component of <code>$arg</code>.</p>
      </fos:rules>
   </fos:function>
   <fos:function name="local-name-from-QName" prefix="fn">
      <fos:signatures>
         <fos:proto name="local-name-from-QName" return-type="xs:NCName?">
            <fos:arg name="arg" type="xs:QName?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the local part of the supplied QName.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:NCName</code> representing the local part of
               <code>$arg</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:local-name-from-QName(fn:QName("http://www.example.com/example",
                  "person"))</fos:expression>
               <fos:result>"person"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="namespace-uri-from-QName" prefix="fn">
      <fos:signatures>
         <fos:proto name="namespace-uri-from-QName" return-type="xs:anyURI?">
            <fos:arg name="arg" type="xs:QName?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the namespace URI part of the supplied QName.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence the function returns the empty sequence.</p>
         <p>Otherwise, the function returns an <code>xs:anyURI</code> representing the namespace URI
            part of <code>$arg</code>.</p>
         <p>If <code>$arg</code> is in no namespace, the function returns the zero-length
               <code>xs:anyURI</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:namespace-uri-from-QName(fn:QName("http://www.example.com/example",
                  "person"))</fos:expression>
               <fos:result>xs:anyURI("http://www.example.com/example")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="namespace-uri-for-prefix" prefix="fn">
      <fos:signatures>
         <fos:proto name="namespace-uri-for-prefix" return-type="xs:anyURI?">
            <fos:arg name="prefix" type="xs:string?"/>
            <fos:arg name="element" type="element()" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the namespace URI of one of the in-scope namespaces for <code>$element</code>,
            identified by its namespace prefix.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$element</code> has an in-scope namespace whose namespace prefix is equal to
               <code>$prefix</code>, the function returns the namespace URI of that namespace.</p>
         <p>If <code>$element</code> has no in-scope namespace whose namespace prefix is equal to
               <code>$prefix</code>, the function returns the empty sequence.</p>
         <p>If <code>$prefix</code> is the zero-length string or the empty sequence, then if
               <code>$element</code> has a default namespace (that is, a namespace node with no
            name), the function returns the namespace URI of the default namespace. If
               <code>$element</code> has no default namespace, the function returns the empty
            sequence.</p>
         <p>Prefixes are equal only if their Unicode codepoints match exactly.</p>
      </fos:rules>
      <fos:examples>
         <fos:variable name="e" id="v-namespace-uri-for-prefix-e"><![CDATA[
<z:a xmlns="http://example.org/one" xmlns:z="http://example.org/two">
  <b xmlns=""/>
</z:a>]]></fos:variable>
         <fos:example>
            <fos:test use="v-namespace-uri-for-prefix-e">
               <fos:expression>fn:namespace-uri-for-prefix("z", $e)</fos:expression>
               <fos:result>"http://example.org/two"</fos:result>
            </fos:test>
            <fos:test use="v-namespace-uri-for-prefix-e">
               <fos:expression>fn:namespace-uri-for-prefix("", $e)</fos:expression>
               <fos:result>"http://example.org/one"</fos:result>
            </fos:test>
            <fos:test use="v-namespace-uri-for-prefix-e">
               <fos:expression>fn:namespace-uri-for-prefix((), $e)</fos:expression>
               <fos:result>"http://example.org/one"</fos:result>
            </fos:test>
            <fos:test use="v-namespace-uri-for-prefix-e">
               <fos:expression>fn:namespace-uri-for-prefix("xml", $e)</fos:expression>
               <fos:result>"http://www.w3.org/XML/1998/namespace"</fos:result>
            </fos:test>
            <fos:test use="v-namespace-uri-for-prefix-e">
               <fos:expression>fn:namespace-uri-for-prefix("xml", $e)</fos:expression>
               <fos:result>"http://www.w3.org/XML/1998/namespace"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="in-scope-prefixes" prefix="fn">
      <fos:signatures>
         <fos:proto name="in-scope-prefixes" return-type="xs:string*">
            <fos:arg name="element" type="element()" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>nondeterministic-wrt-ordering</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the prefixes of the in-scope namespaces for an element node.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns a sequence of strings representing the prefixes of the in-scope
            namespaces for <code>$element</code>.</p>

         <p>For namespace bindings that have a prefix, the function returns the prefix as an
               <code>xs:NCName</code>. For the default namespace, which has no prefix, it returns
            the zero-length string. </p>

         <p>The result sequence contains no duplicates.</p>

         <p>The ordering of the result sequence is <termref def="implementation-dependent"
               >implementation-dependent</termref>.</p>

      </fos:rules>
      <fos:notes>
         <p>The XML namespace is in scope for every element, so the result will always include the string "xml".</p>
      </fos:notes>
   </fos:function>
   <fos:function name="hexBinary-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="hexBinary-equal" return-type="xs:boolean">
            <fos:arg name="value1" type="xs:hexBinary"/>
            <fos:arg name="value2" type="xs:hexBinary"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="eq" types="xs:hexBinary" other-operators="ne">Defines the semantics of
         the "eq" and "ne" operators when applied to two <code>xs:hexBinary</code>
         values.</fos:opermap>
      <fos:summary>
         <p>Returns true if two <code>xs:hexBinary</code> values contain the same octet
            sequence.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns <code>true</code> if <code>$value1</code> and <code>$value2</code>
            are of the same length, measured in binary octets, and contain the same octets in the
            same order. Otherwise, it returns <code>false</code>. </p>
      </fos:rules>
   </fos:function>
   <fos:function name="hexBinary-less-than" prefix="op">
      <fos:signatures>
         <fos:proto name="hexBinary-less-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:hexBinary"/>
            <fos:arg name="arg2" type="xs:hexBinary"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="lt" types="xs:hexBinary" other-operators="ge">Defines the semantics of
         the "lt" operator when applied to two <code>xs:hexBinary</code> values. Also used in the
         definition of the "ge" operator.</fos:opermap>
      <fos:summary>
         <p>Returns true if the first argument is less than the second.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns <code>true</code> if any of the following conditions is true:</p>
         <olist>
            <item>
               <p><code>$arg1</code> is zero-length (contains no octets) and <code>$arg2</code> is
                  not zero-length.</p>
            </item>
            <item>
               <p>Neither argument is zero-length, and the first octet of <code>$arg1</code> is less
                  than the first octet of <code>$arg2</code>, treating the value of the octet as an
                  unsigned integer in the range 0 to 255.</p>
            </item>
            <item>
               <p>Neither argument is zero-length, the first octet of <code>$arg1</code> is equal to
                  the first octet of <code>$arg2</code>, and the <code>xs:hexBinary</code> value
                  formed by taking all octets of <code>arg1</code> after the first is less than the
                     <code>xs:hexBinary</code> value formed by taking all octets of
                     <code>arg2</code> after the first.</p>
            </item>
         </olist>

         <p>Otherwise, the function returns <code>false</code>.</p>
      </fos:rules>
   </fos:function>
   <fos:function name="hexBinary-greater-than" prefix="op">
      <fos:signatures>
         <fos:proto name="hexBinary-greater-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:hexBinary"/>
            <fos:arg name="arg2" type="xs:hexBinary"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="gt" types="xs:hexBinary" other-operators="le">Defines the semantics of
         the "gt" operator when applied to two <code>xs:hexBinary</code> values. Also used in the
         definition of the "le" operator.</fos:opermap>
      <fos:summary>
         <p>Returns true if the first argument is greater than the second.</p>
      </fos:summary>
      <fos:rules>
         <p>The function call <code>op:hexBinary-greater-than($A, $B)</code> is defined to return
            the same result as <code>op:hexBinary-less-than($B, $A)</code></p>
      </fos:rules>
   </fos:function>
   <fos:function name="base64Binary-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="base64Binary-equal" return-type="xs:boolean">
            <fos:arg name="value1" type="xs:base64Binary"/>
            <fos:arg name="value2" type="xs:base64Binary"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="eq" types="xs:base64Binary" other-operators="ne">Defines the semantics
         of the "eq" and "ne" operators when applied to two <code>xs:base64Binary</code>
         values.</fos:opermap>
      <fos:summary>
         <p>Returns true if two <code>xs:base64Binary</code> values contain the same octet
            sequence.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns <code>true</code> if <code>$value1</code> and <code>$value2</code>
            are of the same length, measured in binary octets, and contain the same octets in the
            same order. Otherwise, it returns <code>false</code>. </p>
      </fos:rules>
   </fos:function>
   <fos:function name="base64Binary-less-than" prefix="op">
      <fos:signatures>
         <fos:proto name="base64Binary-less-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:base64Binary"/>
            <fos:arg name="arg2" type="xs:base64Binary"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="lt" types="xs:base64Binary" other-operators="ge">Defines the semantics
         of the "lt" operator when applied to two <code>xs:base64Binary</code> values. Also used in
         the definition of the "ge" operator.</fos:opermap>
      <fos:summary>
         <p>Returns true if the first argument is less than the second.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns <code>true</code> if any of the following conditions is true:</p>
         <olist>
            <item>
               <p><code>$arg1</code> is zero-length (contains no octets) and <code>$arg2</code> is
                  not zero-length.</p>
            </item>
            <item>
               <p>Neither argument is zero-length, and the first octet of <code>$arg1</code> is less
                  than the first octet of <code>$arg2</code>, treating the value of the octet as an
                  unsigned integer in the range 0 to 255.</p>
            </item>
            <item>
               <p>Neither argument is zero-length, the first octet of <code>$arg1</code> is equal to
                  the first octet of <code>$arg2</code>, and the <code>xs:base64Binary</code> value
                  formed by taking all octets of <code>arg1</code> after the first is less than the
                     <code>xs:base64Binary</code> value formed by taking all octets of
                     <code>arg2</code> after the first.</p>
            </item>
         </olist>

         <p>Otherwise, the function returns <code>false</code>.</p>
      </fos:rules>
   </fos:function>
   <fos:function name="base64Binary-greater-than" prefix="op">
      <fos:signatures>
         <fos:proto name="base64Binary-greater-than" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:base64Binary"/>
            <fos:arg name="arg2" type="xs:base64Binary"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="gt" types="xs:base64Binary" other-operators="le">Defines the semantics
         of the "gt" operator when applied to two <code>xs:base64Binary</code> values. Also used in
         the definition of the "le" operator.</fos:opermap>
      <fos:summary>
         <p>Returns true if the first argument is greater than the second.</p>
      </fos:summary>
      <fos:rules>
         <p>The function call <code>op:base64Binary-greater-than($A, $B)</code> is defined to return
            the same result as <code>op:base64Binary-less-than($B, $A)</code></p>
      </fos:rules>
   </fos:function>
   <fos:function name="NOTATION-equal" prefix="op">
      <fos:signatures>
         <fos:proto name="NOTATION-equal" return-type="xs:boolean">
            <fos:arg name="arg1" type="xs:NOTATION"/>
            <fos:arg name="arg2" type="xs:NOTATION"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="eq" types="xs:NOTATION numeric" other-operators="ne">Defines the
         semantics of the "eq" and "ne" operators when applied to two values of type
            <code>xs:NOTATION</code>. </fos:opermap>
      <fos:summary>
         <p>Returns <code>true</code> if the two <code>xs:NOTATION</code> values have the same
            namespace URI and the same local part.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns <code>true</code> if the namespace URIs of <code>$arg1</code> and
               <code>$arg2</code> are equal and the local names of <code>$arg1</code> and
               <code>$arg2</code> are equal.</p>
         <p>Otherwise, the function returns <code>false</code>.</p>
         <p>The namespace URI parts are considered equal if they are both <xtermref ref="dt-absent"
               spec="DM31">absent</xtermref>, or if they are both present and equal under the rules
            of the <code>fn:codepoint-equal</code> function.</p>
         <p>The local parts are also compared under the rules of the <code>fn:codepoint-equal</code>
            function.</p>
      </fos:rules>
      <fos:notes>
         <p>The prefix parts of <code>$arg1</code> and <code>$arg2</code>, if any, are ignored.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="name" prefix="fn">
      <fos:signatures>
         <fos:proto name="name" return-type="xs:string"/>
         <fos:proto name="name" return-type="xs:string">
            <fos:arg name="arg" type="node()?" default="." usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the name of a node, as an <code>xs:string</code> that is either the zero-length
            string, or has the lexical form of an <code>xs:QName</code>. </p>
      </fos:summary>
      <fos:rules>
         <p>If the argument is omitted, it defaults to the context item (<code>.</code>). The
            behavior of the function if the argument is omitted is exactly the same as if the
            context item had been passed as the argument.</p>
         <p>If the argument is supplied and is the empty sequence, the function returns the
            zero-length string.</p>
         <p>If the node identified by <code>$arg</code> has no name (that is, if it is a document
            node, a comment, a text node, or a namespace node having no name), the function returns
            the zero-length string.</p>
         <p>Otherwise, the function returns the value of the expression
               <code>fn:string(fn:node-name($arg))</code>.</p>
      </fos:rules>
      <fos:errors>
         <p>The following errors may be raised when <code>$arg</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>

      </fos:errors>
      <fos:notes>
         <p>Because the result depends on the choice of namespace prefixes in the source document,
         it is not good practice to use the result of this function for anything other than display
         purposes. For example, the test <code>name(.) = 'my:profile'</code> will fail if the source
         document uses an unexpected namespace prefix. Such a test (assuming it relates to an element node) 
         is better written as <code>boolean(self::my:profile)</code>.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="local-name" prefix="fn">
      <fos:signatures>
         <fos:proto name="local-name" return-type="xs:string"/>
         <fos:proto name="local-name" return-type="xs:string">
            <fos:arg name="arg" type="node()?" default="." usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the local part of the name of <code>$arg</code> as an <code>xs:string</code>
            that is either the zero-length string, or has the lexical form of an
               <code>xs:NCName</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>If the argument is omitted, it defaults to the context item (<code>.</code>). The
            behavior of the function if the argument is omitted is exactly the same as if the
            context item had been passed as the argument.</p>
         <p>If the argument is supplied and is the empty sequence, the function returns the
            zero-length string.</p>
         <p>If the node identified by <code>$arg</code> has no name (that is, if it is a document
            node, a comment, a text node, or a namespace node having no name), the function returns
            the zero-length string.</p>
         <p>Otherwise, the function returns the local part of the expanded-QName of the node
            identified by <code>$arg</code>, as determined by the <code>dm:node-name</code> accessor
            defined in <xspecref spec="DM31" ref="dm-node-name"/>). This will be an
               <code>xs:string</code> whose lexical form is an <code>xs:NCName</code>.</p>
      </fos:rules>
      <fos:errors>
         <p>The following errors may be raised when <code>$arg</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>

      </fos:errors>
   </fos:function>
   <fos:function name="namespace-uri" prefix="fn">
      <fos:signatures>
         <fos:proto name="namespace-uri" return-type="xs:anyURI"/>
         <fos:proto name="namespace-uri" return-type="xs:anyURI">
            <fos:arg name="arg" type="node()?" default="." usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the namespace URI part of the name of <code>$arg</code>, as an
               <code>xs:anyURI</code> value.</p>
      </fos:summary>
      <fos:rules>
         <p>If the argument is omitted, it defaults to the context node (<code>.</code>). The
            behavior of the function if the argument is omitted is exactly the same as if the
            context item had been passed as the argument.</p>
         <p>If the node identified by <code>$arg</code> is neither an element nor an attribute node,
            or if it is an element or attribute node whose expanded-QName (as determined by the
               <code>dm:node-name</code> accessor in the <xspecref spec="DM31" ref="dm-node-name"/>)
            is in no namespace, then the function returns the zero-length <code>xs:anyURI</code>
            value.</p>
         <p>Otherwise, the result will be the namespace URI part of the expanded-QName of the node
            identified by <code>$arg</code>, as determined by the <code>dm:node-name</code> accessor
            defined in <xspecref spec="DM31" ref="dm-node-name"/>), returned as an
               <code>xs:anyURI</code> value.</p>
      </fos:rules>
      <fos:errors>
         <p>The following errors may be raised when <code>$arg</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>
      </fos:errors>
   </fos:function>
   <fos:function name="number" prefix="fn">
      <fos:signatures>
         <fos:proto name="number" return-type="xs:double"/>
         <fos:proto name="number" return-type="xs:double">
            <fos:arg name="arg" type="xs:anyAtomicType?" default="."/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the value indicated by <code>$arg</code> or, if <code>$arg</code> is not
            specified, the context item after atomization, converted to an <code>xs:double</code>.
         </p>
      </fos:summary>
      <fos:rules>
         <p>Calling the zero-argument version of the function is defined to give the same result as
            calling the single-argument version with the context item (<code>.</code>). That is,
               <code>fn:number()</code> is equivalent to <code>fn:number(.)</code>, as defined by
            the rules that follow.</p>
         <p>If <code>$arg</code> is the empty sequence or if <code>$arg</code> cannot be converted
            to an <code>xs:double</code>, the <code>xs:double</code> value <code>NaN</code> is
            returned. </p>
         <p>Otherwise, <code>$arg</code> is converted to an <code>xs:double</code> following the
            rules of <specref ref="casting-to-double"/>. If the conversion to <code>xs:double</code>
            fails, the <code>xs:double</code> value <code>NaN</code> is returned.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/>
            if <code>$arg</code> is omitted and the context item is <xtermref ref="dt-absent"
               spec="DM31">absent</xtermref>.</p>
         <p>As a consequence of the rules given above, a type error occurs if the context item
            cannot be atomized, or if the result of atomizing the context item is a sequence
            containing more than one atomic value.</p>
         <!-- bug 16745 -->
      </fos:errors>
      <fos:notes>
         <p>XSD 1.1 allows the string <code>+INF</code> as a representation of positive infinity;
            XSD 1.0 does not. It is <termref def="implementation-defined">implementation-defined</termref> whether XSD 1.1 is
            supported.</p>
         <p>Generally <code>fn:number</code> returns <code>NaN</code> rather than raising a dynamic
            error if the argument cannot be converted to <code>xs:double</code>. However, a type
            error is raised in the usual way if the supplied argument cannot be atomized or if the
            result of atomization does not match the required argument type.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test use="v-po v-item1">
               <fos:expression>fn:number($item1/quantity)</fos:expression>
               <fos:result>5.0e0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-po v-item2">
               <fos:expression>fn:number($item2/description)</fos:expression>
               <fos:result>xs:double('NaN')</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>Assume that the context item is the <code>xs:string</code> value "<code>15</code>".
               Then <code>fn:number()</code> returns <code>1.5e1</code>.</p>
         </fos:example>
      </fos:examples>

   </fos:function>
   <fos:function name="lang" prefix="fn">
      <fos:signatures>
         <fos:proto name="lang" return-type="xs:boolean">
            <fos:arg name="testlang" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="lang" return-type="xs:boolean">
            <fos:arg name="testlang" type="xs:string?"/>
            <fos:arg name="node" type="node()" default="." usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>This function tests whether the language of <code>$node</code>, or the context item if
            the second argument is omitted, as specified by <code>xml:lang</code> attributes is the
            same as, or is a sublanguage of, the language specified by <code>$testlang</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>The behavior of the function if the second argument is omitted is exactly the same as if
            the context item (<code>.</code>) had been passed as the second argument.</p>
         <p>The language of the argument <code>$node</code>, or the context item if the second
            argument is omitted, is determined by the value of the <code>xml:lang</code> attribute
            on the node, or, if the node has no such attribute, by the value of the
               <code>xml:lang</code> attribute on the nearest ancestor of the node that has an
               <code>xml:lang</code> attribute. If there is no such ancestor, then the function
            returns <code>false</code>. </p>

         <p>If <code>$testlang</code> is the empty sequence it is interpreted as the zero-length
            string.</p>
         <p>The relevant <code>xml:lang</code> attribute is determined by the value of the XPath
            expression:</p>
         <eg xml:space="preserve">(ancestor-or-self::*/@xml:lang)[last()]</eg>
         <p>If this expression returns an empty sequence, the function returns <code>false</code>. </p>
         <p>Otherwise, the function returns <code>true</code> if and only if, based on a caseless
            default match as specified in section 3.13 of <bibref ref="Unicode"/>, either:</p>
         <olist>
            <item>
               <p>
                  <code>$testlang</code> is equal to the string-value of the relevant
                     <code>xml:lang</code> attribute, or</p>
            </item>
            <item>
               <p>
                  <code>$testlang</code> is equal to some substring of the string-value of the
                  relevant <code>xml:lang</code> attribute that starts at the start of the
                  string-value and ends immediately before a hyphen, "-" (the character "-" is
                  HYPHEN-MINUS, #x002D).</p>
            </item>
         </olist>
      </fos:rules>
      <fos:errors>
         <p>The following errors may be raised when <code>$arg</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <p>The expression <code>fn:lang("en")</code> would return <code>true</code> if the
               context node were any of the following four elements:</p>
            <ulist>
               <item>
                  <p>
                     <code>&lt;para xml:lang="en"/&gt;</code>
                  </p>
               </item>
               <item>
                  <p>
                     <code>&lt;div xml:lang="en"&gt;&lt;para&gt;And now, and
                        forever!&lt;/para&gt;&lt;/div&gt;</code>
                  </p>
               </item>
               <item>
                  <p>
                     <code>&lt;para xml:lang="EN"/&gt;</code>
                  </p>
               </item>
               <item>
                  <p>
                     <code>&lt;para xml:lang="en-us"/&gt;</code>
                  </p>
               </item>
            </ulist>
         </fos:example>
         <fos:example>
            <p>The expression <code>fn:lang("fr")</code> would return <code>false</code> if the
               context node were <code>&lt;para xml:lang="EN"/&gt;</code>
            </p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="path" prefix="fn">
      <fos:signatures>
         <fos:proto name="path" return-type="xs:string?"/>
         <fos:proto name="path" return-type="xs:string?">
            <fos:arg name="arg" type="node()?" default="." usage="navigation"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a path expression that can be used to select the supplied node relative to the
            root of its containing document.</p>
      </fos:summary>
      <fos:rules>
         <p>The behavior of the function if the argument is omitted is exactly the same as if the
            context item (<code>.</code>) had been passed as the argument.</p>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>If <code>$arg</code> is a document node, the function returns the string
               <code>"/"</code>.</p>
         <p>Otherwise, the function returns a string that consists of a sequence of steps, one
            for each ancestor-or-self of <code>$arg</code> other than the root node. This string is
            prefixed by <code>"Q{http://www.w3.org/2005/xpath-functions}root()"</code> if the root
            node is not a document node. Each step consists of the character <code>"/"</code>
            followed by a string whose form depends on the kind of node selected by that step, as
            follows:</p>

         <olist>
            <item>
               <p>For an element node,
                        <code>Q{<emph>uri</emph>}<emph>local</emph>[<emph>position</emph>]</code>,
                  where <code><emph>uri</emph></code> is the namespace URI of the node name or the
                  empty string if the node is in no namespace, <code><emph>local</emph></code> is
                  the local part of the node name, and <code><emph>position</emph></code> is an
                  integer representing the position of the selected node among its like-named
                  siblings.</p>
            </item>
            <item>
               <p>For an attribute node:</p>
               <olist>
                  <item>
                     <p>if the node is in no namespace, <code>@<emph>local</emph></code>, where
                              <code><emph>local</emph></code> is the local part of the node name</p>
                  </item>
                  <item>
                     <p>otherwise, <code>@Q{<emph>uri</emph>}<emph>local</emph></code>, where
                              <code><emph>uri</emph></code> is the namespace URI of the node name,
                        and <code><emph>local</emph></code> is the local part of the node name</p>
                  </item>
               </olist>
            </item>
            <item>
               <p>For a text node: <code>text()[<emph>position</emph>]</code> where
                        <code><emph>position</emph></code> is an integer representing the position
                  of the selected node among its text node siblings</p>
            </item>
            <item>
               <p>For a comment node: <code>comment()[<emph>position</emph>]</code> where
                        <code><emph>position</emph></code> is an integer representing the position
                  of the selected node among its comment node siblings</p>
            </item>
            <item>
               <p>For a processing-instruction node:
                        <code>processing-instruction(<emph>local</emph>)[<emph>position</emph>]</code>
                  where <code><emph>local</emph></code> is the name of the processing instruction
                  node and <code><emph>position</emph></code> is an integer representing the
                  position of the selected node among its like-named processing-instruction node
                  siblings</p>
            </item>
            <item>
               <p>For a namespace node:</p>
               <olist>
                  <item>
                     <p>If the namespace node has a name:
                           <code>namespace::<emph>prefix</emph></code>, where
                              <code><emph>prefix</emph></code> is the local part of the name of the
                        namespace node (which represents the namespace prefix).</p>
                  </item>
                  <item>
                     <p>If the namespace node has no name (that is, it represents the default
                        namespace):
                           <code>namespace::*[Q{http://www.w3.org/2005/xpath-functions}local-name()=""]</code></p>
                  </item>
               </olist>
            </item>
         </olist>

      </fos:rules>
      <fos:errors>
         <p diff="add" at="D">The following errors may be raised when <code>$arg</code> is omitted:</p>
         <ulist diff="add" at="D">
            <item>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </item>
            <item>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                  code="0004" type="type"/>.</p>
            </item>
         </ulist>        
      </fos:errors>
      <fos:examples>
         <fos:variable name="e" id="v-path-e"><![CDATA[
document {            
<p xmlns="http://example.com/one" xml:lang="de" author="Friedrich von Schiller">
Freude, schöner Götterfunken,<br/>
Tochter aus Elysium,<br/>
Wir betreten feuertrunken,<br/>
Himmlische, dein Heiligtum.</p>}]]>
         </fos:variable>
         <fos:example>
            <fos:test use="v-path-e">
               <fos:expression>fn:path($e)</fos:expression>
               <fos:result>'/'</fos:result>
            </fos:test>
            <fos:test use="v-path-e">
               <fos:expression>fn:path($e/*:p)</fos:expression>
               <fos:result>'/Q{http://example.com/one}p[1]'</fos:result>
            </fos:test>
            <fos:test use="v-path-e">
               <fos:expression>fn:path($e/*:p/@xml:lang)</fos:expression>
               <fos:result>'/Q{http://example.com/one}p[1]/@Q{http://www.w3.org/XML/1998/namespace}lang'</fos:result>
            </fos:test>
            <fos:test use="v-path-e">
               <fos:expression>fn:path($e/*:p/@author)</fos:expression>
               <fos:result>'/Q{http://example.com/one}p[1]/@author'</fos:result>
            </fos:test>
            <fos:test use="v-path-e">
               <fos:expression>fn:path($e/*:p/*:br[2])</fos:expression>
               <fos:result>'/Q{http://example.com/one}p[1]/Q{http://example.com/one}br[2]'</fos:result>
            </fos:test>
            <fos:test use="v-path-e">
               <fos:expression>fn:path($e//text()[starts-with(normalize-space(),
                  'Tochter')])</fos:expression>
               <fos:result>'/Q{http://example.com/one}p[1]/text()[2]'</fos:result>
            </fos:test>
         </fos:example>
         <fos:variable name="emp"  id="v-path-emp" as="element()"><![CDATA[
            <employee xml:id="ID21256">
               <empnr>E21256</empnr>
               <first>John</first>
               <last>Brown</last>
            </employee>]]>
         </fos:variable>
         <fos:example>
            <fos:test use="v-path-emp">
               <fos:expression>fn:path($emp)</fos:expression>
               <fos:result>'Q{http://www.w3.org/2005/xpath-functions}root()'</fos:result>
            </fos:test>
            <fos:test use="v-path-emp">
               <fos:expression>fn:path($emp/@xml:id)</fos:expression>
               <fos:result>'Q{http://www.w3.org/2005/xpath-functions}root()/@Q{http://www.w3.org/XML/1998/namespace}id'</fos:result>
            </fos:test>
            <fos:test use="v-path-emp">
               <fos:expression>fn:path($emp/empnr)</fos:expression>
               <fos:result>'Q{http://www.w3.org/2005/xpath-functions}root()/Q{}empnr[1]'</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="root" prefix="fn">
      <fos:signatures>
         <fos:proto name="root" return-type="node()"/>
         <fos:proto name="root" return-type="node()?">
            <fos:arg name="arg" type="node()?" default="." usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
         <fos:property>special-streaming-rules</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>special-streaming-rules</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the root of the tree to which <code>$arg</code> belongs. This will usually, but
            not necessarily, be a document node.</p>
      </fos:summary>
      <fos:rules>
         <p>If the function is called without an argument, the context item (<code>.</code>) is used
            as the default argument. The behavior of the function if the argument is omitted is
            exactly the same as if the context item had been passed as the argument.</p>

         <p>The function returns the value of the expression
               <code>($arg/ancestor-or-self::node())[1]</code>.</p>
      </fos:rules>
      <fos:errors>
         <p>The following errors may be raised when <code>$arg</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <p>These examples use some variables which could be defined in <bibref ref="xquery-31"/>
               as:</p>
         </fos:example>
         <fos:example>
            <eg xml:space="preserve">let $i := &lt;tool&gt;wrench&lt;/tool&gt;
let $o := &lt;order&gt; {$i} &lt;quantity&gt;5&lt;/quantity&gt; &lt;/order&gt;
let $odoc := document {$o}
let $newi := $o/tool</eg>
         </fos:example>
         <fos:example>
            <p>Or they could be defined in <bibref ref="xslt-30"/> as:</p>
         </fos:example>
         <fos:example>
            <eg xml:space="preserve">&lt;xsl:variable name="i" as="element()"&gt;
  &lt;tool&gt;wrench&lt;/tool&gt;
&lt;/xsl:variable&gt;

&lt;xsl:variable name="o" as="element()"&gt;
  &lt;order&gt;
    &lt;xsl:copy-of select="$i"/&gt;
    &lt;quantity&gt;5&lt;/quantity&gt;
  &lt;/order&gt;
&lt;/xsl:variable&gt;

&lt;xsl:variable name="odoc"&gt;
  &lt;xsl:copy-of select="$o"/&gt;
&lt;/xsl:variable&gt;

&lt;xsl:variable name="newi" select="$o/tool"/&gt;</eg>
         </fos:example>
         <fos:example>
            <p><code>fn:root($i)</code> returns the element node <code>$i</code>
            </p>
         </fos:example>
         <fos:example>
            <p><code>fn:root($o/quantity)</code> returns the element node <code>$o</code>
            </p>
         </fos:example>
         <fos:example>
            <p><code>fn:root($odoc//quantity)</code> returns the document node <code>$odoc</code>
            </p>
         </fos:example>
         <fos:example>
            <p><code>fn:root($newi)</code> returns the element node <code>$o</code>
            </p>
         </fos:example>
         <fos:example>
            <p>The final three examples could be made type-safe by wrapping their operands with
                  <code>fn:exactly-one()</code>.</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="has-children" prefix="fn">
      <fos:signatures>
         <fos:proto name="has-children" return-type="xs:boolean"/>
         <fos:proto name="has-children" return-type="xs:boolean">
            <fos:arg name="node" type="node()?" default="." usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if the supplied node has one or more child nodes (of any kind).</p>
      </fos:summary>
      <fos:rules>
         <p>If the argument is omitted, it defaults to the context item (<code>.</code>). The
            behavior of the function if the argument is omitted is exactly the same as if the
            context item had been passed as the argument.</p>
         <p>Provided that the supplied argument <code>$node</code> matches the expected type
               <code>node()?</code>, the result of the function call
               <code>fn:has-children($node)</code> is defined to be the same as the result of the
            expression <code>fn:exists($node/child::node())</code>.</p>
      </fos:rules>
      <fos:errors>
         <p>The following errors may be raised when <code>$node</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>

      </fos:errors>
      <fos:notes>
         <p>If <code>$node</code> is an empty sequence the result is false.</p>
         <p>The motivation for this function is to support streamed evaluation. According to the
            streaming rules in <bibref ref="xslt-30"/>, the following construct is not
            streamable:</p>
         <eg><![CDATA[
<xsl:if test="exists(row)">
  <ul>
    <xsl:for-each select="row">
       <li><xsl:value-of select="."/></li>
    </xsl:for-each>
  </ul>
</xsl:if>  
]]></eg>
         <p>This is because it makes two downward selections to read the child <code>row</code>
            elements. The use of <code>fn:has-children</code> in the <code>xsl:if</code> conditional
            is intended to circumvent this restriction.</p>
         <p>Although the function was introduced to support streaming use cases, it has general
            utility as a convenience function.</p>
      </fos:notes>

   </fos:function>
   <fos:function name="innermost" prefix="fn">
      <fos:signatures>
         <fos:proto name="innermost" return-type="node()*">
            <fos:arg name="nodes" type="node()*" usage="navigation"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>special-streaming-rules</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns every node within the input sequence that is not an ancestor of another member
            of the input sequence; the nodes are returned in document order with duplicates
            eliminated.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the function call <code>fn:innermost($nodes)</code> is defined to be
            equivalent to the result of the expression:</p>
         <eg>$nodes except $nodes/ancestor::node()</eg>
         <p>That is, the function takes as input a sequence of nodes, and returns every node within
            the sequence that is not an ancestor of another node within the sequence; the nodes are
            returned in document order with duplicates eliminated.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <p>If the source document contains nested sections represented by <code>div</code>
               elements, the expression <code>innermost(//div)</code> returns those <code>div</code>
               elements that do not contain further <code>div</code> elements.</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="outermost" prefix="fn">
      <fos:signatures>
         <fos:proto name="outermost" return-type="node()*">
            <fos:arg name="nodes" type="node()*" usage="transmission"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>special-streaming-rules</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns every node within the input sequence that has no ancestor that is itself a
            member of the input sequence; the nodes are returned in document order with duplicates
            eliminated.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the function call <code>fn:outermost($nodes)</code> is defined to be
            equivalent to the result of the expression:</p>
         <eg>$nodes[not(ancestor::node() intersect $nodes)]/.</eg>
         <!--bug 17029-->
         <p>That is, the function takes as input a sequence of nodes, and returns every node within
            the sequence that does not have another node within the sequence as an ancestor; the
            nodes are returned in document order with duplicates eliminated.</p>
      </fos:rules>
      <fos:notes>
         <p>The formulation <code>$nodes except $nodes/descendant::node()</code> might appear to be
            simpler, but does not correctly account for attribute nodes, as these are not
            descendants of their parent element.</p>
         <p>The motivation for the function was based on XSLT streaming use cases. There are cases
            where the <bibref ref="xslt-30"/> streaming rules allow the construct
               <code>outermost(//section)</code> but do not allow <code>//section</code>; the
            function can therefore be useful in cases where it is known that sections will not be
            nested, as well as cases where the application actually wishes to process all sections
            except those that are nested within another.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p>If the source document contains nested sections represented by <code>div</code>
               elements, the expression <code>outermost(//div)</code> returns those <code>div</code>
               elements that are not contained within further <code>div</code> elements.</p>
         </fos:example>
      </fos:examples>
   </fos:function>  
   <fos:function name="index-of" prefix="fn">
      <fos:signatures>
         <fos:proto name="index-of" return-type="xs:integer*">
            <fos:arg name="seq" type="xs:anyAtomicType*"/>
            <fos:arg name="search" type="xs:anyAtomicType"/>
         </fos:proto>
         <fos:proto name="index-of" return-type="xs:integer*">
            <fos:arg name="seq" type="xs:anyAtomicType*"/>
            <fos:arg name="search" type="xs:anyAtomicType"/>
            <fos:arg name="collation" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="3">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations static-base-uri implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a sequence of positive integers giving the positions within the sequence
               <code>$seq</code> of items that are equal to <code>$search</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns a sequence of positive integers giving the positions within the
            sequence <code>$seq</code> of items that are equal to <code>$search</code>.</p>
         <p>The collation used by this function is determined according to the rules in <specref
               ref="choosing-a-collation"/>. This collation is used when string comparison is
            required.</p>
         <p>The items in the sequence <code>$seq</code> are compared with <code>$search</code> under
            the rules for the <code>eq</code> operator. Values of type <code>xs:untypedAtomic</code>
            are compared as if they were of type <code>xs:string</code>. Values that cannot be
            compared, because the <code>eq</code> operator is not defined for their types, are
            considered to be distinct. If an item compares equal, then the position of that item in
            the sequence <code>$seq</code> is included in the result.</p>
         <p>The first item in a sequence is at position 1, not position 0.</p>
         <p>The result sequence is in ascending numeric order.</p>
      </fos:rules>
      <fos:notes>
         <p>If the value of <code>$seq</code> is the empty sequence, or if no item in
               <code>$seq</code> matches <code>$search</code>, then the function returns the empty
            sequence.</p>
         <p>No error occurs if non-comparable values are encountered. So when comparing two atomic
            values, the effective boolean value of <code>fn:index-of($a, $b)</code> is true if
               <code>$a</code> and <code>$b</code> are equal, false if they are not equal or not
            comparable.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:index-of((10, 20, 30, 40), 35)</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:index-of((10, 20, 30, 30, 20, 10), 20)</fos:expression>
               <fos:result>(2, 5)</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:index-of(("a", "sport", "and", "a", "pastime"),
                  "a")</fos:expression>
               <fos:result>(1, 4)</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:index-of(current-date(), 23)</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:index-of([1, [5, 6], [6, 7]], 6)</fos:expression>
               <fos:result>(3, 4)</fos:result>
               <fos:postamble>The array is atomized to a sequence of five integers</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>If <code>@a</code> is an attribute of type <code>xs:NMTOKENS</code> whose string
               value is <code>"red green blue"</code>, and whose typed value is therefore
                  <code>("red", "green", "blue")</code>, then <code>fn:index-of(@a, "blue")</code>
               returns <code>3</code>. This is because the function calling mechanism atomizes the
               attribute node to produce a sequence of three <code>xs:NMTOKEN</code> values.</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="empty" prefix="fn">
      <fos:signatures>
         <fos:proto name="empty" return-type="xs:boolean">
            <fos:arg name="arg" type="item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if the argument is the empty sequence.</p>
      </fos:summary>
      <fos:rules>
         <p>If the value of <code>$arg</code> is the empty sequence, the function returns
               <code>true</code>; otherwise, the function returns <code>false</code>. </p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:empty((1,2,3)[10])</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:empty(fn:remove(("hello", "world"), 1))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:empty([])</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:empty(map{})</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:empty("")</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>Assuming <code>$in</code> is an element with no children:</p>
            <eg>
               let $break := &lt;br/&gt;
               return fn:empty($break)
            </eg>
            <p>The result is <code>false()</code>.</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="exists" prefix="fn">
      <fos:signatures>
         <fos:proto name="exists" return-type="xs:boolean">
            <fos:arg name="arg" type="item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns true if the argument is a non-empty sequence.</p>
      </fos:summary>
      <fos:rules>
         <p>If the value of <code>$arg</code> is a non-empty sequence, the function returns
               <code>true</code>; otherwise, the function returns <code>false</code>. </p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:exists(fn:remove(("hello"), 1))</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:exists(fn:remove(("hello", "world"), 1))</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:exists([])</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:exists(map{})</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:exists("")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>Assuming <code>$in</code> is an element with no children:</p>
            <eg>
               let $break := <br/>
               return fn:exists($break)
            </eg>
            <p>The result is <code>true()</code>.</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="distinct-values" prefix="fn">
      <fos:signatures>
         <fos:proto name="distinct-values" return-type="xs:anyAtomicType*">
            <fos:arg name="arg" type="xs:anyAtomicType*"/>
         </fos:proto>
         <fos:proto name="distinct-values" return-type="xs:anyAtomicType*">
            <fos:arg name="arg" type="xs:anyAtomicType*"/>
            <fos:arg name="collation" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="1">
         <fos:property>nondeterministic-wrt-ordering</fos:property>
         <fos:property dependency="collations implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations static-base-uri implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the values that appear in a sequence, with duplicates eliminated.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the sequence that results from removing from <code>$arg</code> all
            but one of a set of values that are considered equal to one another. 
            <phrase diff="chg" at="D">Two items <var>$J</var> and <var>$K</var> in the input sequence 
               (after atomization, as required by the function signature)
            are considered equal if <code>fn:deep-equal($J, $K, $coll)</code> is true,
            where <code>$coll</code> is the collation selected according to the rules in <specref
               ref="choosing-a-collation"/>.</phrase> This collation is used when string comparison is
            required.</p>
            
          
         <p>The order in which the sequence of values is returned is <termref
            def="implementation-dependent">implementation-dependent</termref>.</p>

         <p>Which value of a set of values that compare equal is returned is <termref
            def="implementation-dependent">implementation-dependent</termref>. </p>
         <p>If the input sequence contains values of different numeric types that differ from each
            other by small amounts, then the eq operator is not transitive, because of rounding
            effects occurring during type promotion. In the situation where the input contains three
            values <code>A</code>, <code>B</code>, and <code>C</code> such that <code>A eq B</code>,
               <code>B eq C</code>, but <code>A ne C</code>, then the number of items in the result
            of the function (as well as the choice of which items are returned) is <termref
               def="implementation-dependent">implementation-dependent</termref>, subject only to the constraints that (a) no two
            items in the result sequence compare equal to each other, and (b) every input item that
            does not appear in the result sequence compares equal to some item that does appear in
            the result sequence.</p>

         <p>For example, this arises when computing:</p>

         <eg><![CDATA[    distinct-values(
            (xs:float('1.0'),
            xs:decimal('1.0000000000100000000001',
            xs:double( '1.00000000001'))]]></eg>

         <p>because the values of type <code>xs:float</code> and <code>xs:double</code> both compare
            equal to the value of type <code>xs:decimal</code> but not equal to each other. </p>
      </fos:rules>
      <fos:notes>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         
         <p>Values of type <code>xs:untypedAtomic</code> are compared as if they were of type
            <code>xs:string</code>.</p>
         <p>Values that cannot be compared, because the <code>eq</code> operator is not defined for
            their types, are considered to be distinct.</p>
         
         <p>For <code>xs:float</code> and <code>xs:double</code> values, positive zero is equal to
            negative zero and, although <code>NaN</code> does not equal itself, if <code>$arg</code>
            contains multiple <code>NaN</code> values a single <code>NaN</code> is returned.</p>
         <p> If <code>xs:dateTime</code>, <code>xs:date</code> or <code>xs:time</code> values do not
            have a timezone, they are considered to have the implicit timezone provided by the
            dynamic context for the purpose of comparison. Note that <code>xs:dateTime</code>,
            <code>xs:date</code> or <code>xs:time</code> values can compare equal even if their
            timezones are different.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:distinct-values((1, 2.0, 3, 2))</fos:expression>
               <fos:result allow-permutation="true">(1, 3, 2.0)</fos:result>
               <fos:postamble>The result may include either the <code>xs:integer</code> 2 or the <code>xs:decimal</code> 2.0</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:distinct-values((xs:untypedAtomic("cherry"),
                  xs:untypedAtomic("plum"), xs:untypedAtomic("plum")))</fos:expression>
               <fos:result allow-permutation="true">(xs:untypedAtomic("cherry"),
                  xs:untypedAtomic("plum"))</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="insert-before" prefix="fn">
      <fos:signatures>
         <fos:proto name="insert-before" return-type="item()*">
            <fos:arg name="target" type="item()*" usage="transmission"/>
            <fos:arg name="position" type="xs:integer"/>
            <fos:arg name="inserts" type="item()*" usage="transmission"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a sequence constructed by inserting an item or a sequence of items at a given
            position within an existing sequence.</p>
      </fos:summary>
      <fos:rules>
         <p>The value returned by the function consists of all items of <code>$target</code> whose
            index is less than <code>$position</code>, followed by all items of
               <code>$inserts</code>, followed by the remaining elements of <code>$target</code>, in
            that order. </p>
      </fos:rules>
      <fos:notes>
         <p>If <code>$target</code> is the empty sequence, <code>$inserts</code> is returned. If
               <code>$inserts</code> is the empty sequence, <code>$target</code> is returned.</p>
         <p>If <code>$position</code> is less than one (1), the first position, the effective value
            of <code>$position</code> is one (1). If <code>$position</code> is greater than the
            number of items in <code>$target</code>, then the effective value of
               <code>$position</code> is equal to the number of items in <code>$target</code> plus
            1. </p>
         <p>The value of <code>$target</code> is not affected by the sequence construction.</p>
      </fos:notes>
      <fos:examples>
         <fos:variable id="v-insert-before-abc" name="abc" select="(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;)"/>
         <fos:example>
            <fos:test use="v-insert-before-abc">
               <fos:expression>fn:insert-before($abc, 0, "z")</fos:expression>
               <fos:result>("z", "a", "b", "c")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-insert-before-abc">
               <fos:expression>fn:insert-before($abc, 1, "z")</fos:expression>
               <fos:result>("z", "a", "b", "c")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-insert-before-abc">
               <fos:expression>fn:insert-before($abc, 2, "z")</fos:expression>
               <fos:result>("a", "z", "b", "c")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-insert-before-abc">
               <fos:expression>fn:insert-before($abc, 3, "z")</fos:expression>
               <fos:result>("a", "b", "z", "c")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-insert-before-abc">
               <fos:expression>fn:insert-before($abc, 4, "z")</fos:expression>
               <fos:result>("a", "b", "c", "z")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="remove" prefix="fn">
      <fos:signatures>
         <fos:proto name="remove" return-type="item()*">
            <fos:arg name="target" type="item()*" usage="transmission"/>
            <fos:arg name="position" type="xs:integer"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a new sequence containing all the items of <code>$target</code> except the item
            at position <code>$position</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns a sequence consisting of all items of <code>$target</code> whose
            index is less than <code>$position</code>, followed by all items of <code>$target</code>
            whose index is greater than <code>$position</code>. </p>
      </fos:rules>
      <fos:notes>
         <p>If <code>$position</code> is less than 1 or greater than the number of items in
               <code>$target</code>, <code>$target</code> is returned.</p>
         <p>If <code>$target</code> is the empty sequence, the empty sequence is returned.</p>
      </fos:notes>
      <fos:examples>
         <fos:variable id="v-remove-abc" name="abc" select="(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;)"/>
         <fos:example>
            <fos:test use="v-remove-abc">
               <fos:expression>fn:remove($abc, 0)</fos:expression>
               <fos:result>("a", "b", "c")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-remove-abc">
               <fos:expression>fn:remove($abc, 1)</fos:expression>
               <fos:result>("b", "c")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-remove-abc">
               <fos:expression>fn:remove($abc, 6)</fos:expression>
               <fos:result>("a", "b", "c")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-remove-abc">
               <fos:expression>fn:remove((), 3)</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="head" prefix="fn">
      <fos:signatures>
         <fos:proto name="head" return-type="item()?">
            <fos:arg name="arg" type="item()*" usage="transmission"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the first item in a sequence. </p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the value of the expression <code>$arg[1]</code></p>
      </fos:rules>
      <fos:notes>
         <p>If <code>$arg</code> is the empty sequence, the empty sequence is returned. Otherwise
            the first item in the sequence is returned.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:head(1 to 5)</fos:expression>
               <fos:result>1</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:head(("a", "b", "c"))</fos:expression>
               <fos:result>"a"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:head(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:head([1,2,3])</fos:expression>
               <fos:result>[1,2,3]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="tail" prefix="fn">
      <fos:signatures>
         <fos:proto name="tail" return-type="item()*">
            <fos:arg name="arg" type="item()*" usage="transmission"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns all but the first item in a sequence. </p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the value of the expression <code>subsequence($arg, 2)</code></p>
      </fos:rules>
      <fos:notes>
         <p>If <code>$arg</code> is the empty sequence, or a sequence containing a single item, then
            the empty sequence is returned. </p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:tail(1 to 5)</fos:expression>
               <fos:result>(2, 3, 4, 5)</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:tail(("a", "b", "c"))</fos:expression>
               <fos:result>("b", "c")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:tail("a")</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:tail(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:tail([1,2,3])</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="reverse" prefix="fn">
      <fos:signatures>
         <fos:proto name="reverse" return-type="item()*">
            <fos:arg name="arg" type="item()*" usage="navigation"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>special-streaming-rules</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Reverses the order of items in a sequence. </p>
      </fos:summary>
      <fos:rules>
         <p>The function returns a sequence containing the items in <code>$arg</code> in reverse
            order.</p>
      </fos:rules>
      <fos:notes>
         <p>If <code>$arg</code> is the empty sequence, the empty sequence is returned. </p>
      </fos:notes>
      <fos:examples>
         <fos:variable id="v-reverse-abc" name="abc" select="(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;)"/>
         <fos:example>
            <fos:test use="v-reverse-abc">
               <fos:expression>fn:reverse($abc)</fos:expression>
               <fos:result>("c", "b", "a")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:reverse(("hello"))</fos:expression>
               <fos:result>("hello")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:reverse(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:reverse([1,2,3])</fos:expression>
               <fos:result>[1,2,3]</fos:result>
               <fos:postamble>The input is a sequence containing a single item (the array)</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:reverse(([1,2,3],[4,5,6]))</fos:expression>
               <fos:result>([4,5,6],[1,2,3])</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="subsequence" prefix="fn">
      <fos:signatures>
         <fos:proto name="subsequence" return-type="item()*">
            <fos:arg name="sourceSeq" type="item()*" usage="transmission"/>
            <fos:arg name="startingLoc" type="xs:double"/>
         </fos:proto>
         <fos:proto name="subsequence" return-type="item()*">
            <fos:arg name="sourceSeq" type="item()*" usage="transmission"/>
            <fos:arg name="startingLoc" type="xs:double"/>
            <fos:arg name="length" type="xs:double"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the contiguous sequence of items in the value of <code>$sourceSeq</code>
            beginning at the position indicated by the value of <code>$startingLoc</code> and
            continuing for the number of items indicated by the value of <code>$length</code>. </p>
      </fos:summary>
      <fos:rules>
         <p>In the two-argument case, returns:</p>
         <eg xml:space="preserve">$sourceSeq[fn:round($startingLoc) le position()]</eg>
         <p>In the three-argument case, returns:</p>
         <eg xml:space="preserve">$sourceSeq[fn:round($startingLoc) le position() 
         and position() lt fn:round($startingLoc) + fn:round($length)]</eg>

      </fos:rules>
      <fos:notes>
         <p>The first item of a sequence is located at position 1, not position 0.</p>
         <p>If <code>$sourceSeq</code> is the empty sequence, the empty sequence is returned.</p>
         
         <p diff="chg" at="D">In the two-argument case, the function returns a sequence comprising those items of <code>$sourceSeq</code> whose index position (counting from one) 
            is greater than or equal to the value of <code>$startingLoc</code> (rounded to an integer). No error occurs if <code>$startingLoc</code> is 
            zero or negative.</p>
         
         <p diff="chg" at="D">In the three-argument case, The function returns a sequence comprising those items of <code>$sourceSeq</code> whose index position (counting from one) 
            is greater than or equal to the value of <code>$startingLoc</code> (rounded to an integer), and 
            less than the sum of <code>$startingLoc</code> and <code>$length</code> (both rounded to integers). No error occurs if <code>$startingLoc</code> is 
            zero or negative, or if <code>$startingLoc</code> plus <code>$length</code> exceeds the number of items in the sequence, or if 
            <code>$length</code> is negative.</p>
         
  
         <p>As a consequence of the general rules, if <code>$startingLoc</code> is
               <code>-INF</code> and <code>$length</code> is <code>+INF</code>, then
               <code>fn:round($startingLoc) + fn:round($length)</code> is <code>NaN</code>; since
               <code>position() lt NaN</code> is always false, the result is an empty sequence.</p>
         
         <p>The reason the function accepts arguments of type <code>xs:double</code> is that many
            computations on untyped data return an <code>xs:double</code> result; and the reason for
            the rounding rules is to compensate for any imprecision in these floating-point
            computations.</p>
      </fos:notes>

      <fos:examples>
         <fos:variable name="seq"  id="v-reverse-seq"
            select="(&quot;item1&quot;, &quot;item2&quot;, &quot;item3&quot;, &quot;item4&quot;, &quot;item5&quot;)"/>
         <fos:example>
            <fos:test use="v-reverse-seq">
               <fos:expression>fn:subsequence($seq, 4)</fos:expression>
               <fos:result>("item4", "item5")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-reverse-seq">
               <fos:expression>fn:subsequence($seq, 3, 2)</fos:expression>
               <fos:result>("item3", "item4")</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="unordered" prefix="fn">
      <fos:signatures>
         <fos:proto name="unordered" return-type="item()*">
            <fos:arg name="sourceSeq" type="item()*" usage="transmission"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>nondeterministic-wrt-ordering</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the items of <code>$sourceSeq</code> in an <termref
            def="implementation-dependent">implementation-dependent</termref> order.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the items of <code>$sourceSeq</code> in an <termref
            def="implementation-dependent">implementation-dependent</termref> order.</p>
      </fos:rules>
      <fos:notes>
         <p>Query optimizers may be able to do a better job if the order of the output sequence is
            not specified. For example, when retrieving prices from a purchase order, if an index
            exists on prices, it may be more efficient to return the prices in index order rather
            than in document order.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:unordered((1, 2, 3, 4, 5))</fos:expression>
               <fos:result allow-permutation="true">(1, 2, 3, 4, 5)</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="zero-or-one" prefix="fn">
      <fos:signatures>
         <fos:proto name="zero-or-one" return-type="item()?">
            <fos:arg name="arg" type="item()*" usage="transmission"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns <code>$arg</code> if it contains zero or one items. Otherwise, raises an
            error.</p>
      </fos:summary>
      <fos:rules>
         <p>Except in error cases, the function returns <code>$arg</code> unchanged.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="RG" code="0003"/> if <code>$arg</code>
            contains more than one item.</p>
      </fos:errors>
   </fos:function>
   <fos:function name="one-or-more" prefix="fn">
      <fos:signatures>
         <fos:proto name="one-or-more" return-type="item()+">
            <fos:arg name="arg" type="item()*" usage="transmission"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns <code>$arg</code> if it contains one or more items. Otherwise, raises an error.
         </p>
      </fos:summary>
      <fos:rules>
         <p>Except in error cases, the function returns <code>$arg</code> unchanged.</p>

      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="RG" code="0004"/> if <code>$arg</code> is an
            empty sequence.</p>
      </fos:errors>
   </fos:function>
   <fos:function name="exactly-one" prefix="fn">
      <fos:signatures>
         <fos:proto name="exactly-one" return-type="item()">
            <fos:arg name="arg" type="item()*" usage="transmission"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns <code>$arg</code> if it contains exactly one item. Otherwise, raises an error.
         </p>
      </fos:summary>
      <fos:rules>
         <p>Except in error cases, the function returns <code>$arg</code> unchanged.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="RG" code="0005"/> if <code>$arg</code> is an
            empty sequence or a sequence containing more than one item.</p>
      </fos:errors>
   </fos:function>
   <fos:function name="deep-equal" prefix="fn">
      <fos:signatures>
         <fos:proto name="deep-equal" return-type="xs:boolean">
            <fos:arg name="parameter1" type="item()*" usage="absorption"/>
            <fos:arg name="parameter2" type="item()*" usage="absorption"/>
         </fos:proto>
         <fos:proto name="deep-equal" return-type="xs:boolean">
            <fos:arg name="parameter1" type="item()*" usage="absorption"/>
            <fos:arg name="parameter2" type="item()*" usage="absorption"/>
            <fos:arg name="collation" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="3">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations static-base-uri implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p> This function assesses whether two sequences are deep-equal to each other. To be
            deep-equal, they must contain items that are pairwise deep-equal; and for two items to
            be deep-equal, they must either be atomic values that compare equal, or nodes of the
            same kind, with the same name, whose children are deep-equal<phrase diff="add" at="A">,
               or maps with matching entries, or arrays with matching members.</phrase></p>
      </fos:summary>
      <fos:rules>
         <p>The <code>$collation</code> argument identifies a collation which is used at all levels
            of recursion when strings are compared (but not when names are compared), according to
            the rules in <specref ref="choosing-a-collation"/>.</p>
         <p>If the two sequences are both empty, the function returns <code>true</code>.</p>
         <p>If the two sequences are of different lengths, the function returns
            <code>false</code>.</p>
         <p>If the two sequences are of the same length, the function returns <code>true</code> if
            and only if every item in the sequence <code>$parameter1</code> is deep-equal to the
            item at the same position in the sequence <code>$parameter2</code>. The rules for
            deciding whether two items are deep-equal follow.</p>

         <p>Call the two items <code>$i1</code> and <code>$i2</code> respectively.</p>
         <p>If <code>$i1</code> and <code>$i2</code> are both atomic values, they are deep-equal if
            and only if <code>($i1 eq $i2)</code> is <code>true</code>, or if both values are
               <code>NaN</code>. If the <code>eq</code> operator is not defined for <code>$i1</code>
            and <code>$i2</code>, the function returns <code>false</code>.</p>
         <p diff="del" at="A"> If one of the pair <code>$i1</code> or <code>$i2</code> is an atomic
            value and the other is not, <phrase diff="add" at="A">or if one is a node and the other
               is not, </phrase> the function returns <code>false</code>.</p>
         <p diff="add" at="A">If <code>$i1</code> and <code>$i2</code> are both <termref
               def="dt-map">maps</termref>, the result is <code>true</code> if and only if all the
            following conditions apply:</p>
         <olist diff="add" at="A">
            <item>
               <p>Both maps have the same number of entries.</p>
            </item>
            <item>
               <p>For every entry in the first map, there is an entry in the second map that:</p>
               <olist>
                  <item>
                     <p>has the <termref def="dt-same-key">same key</termref> (note that the
                        collation is not used when comparing keys), and </p>
                  </item>
                  <item>
                     <p>has the same associated value (compared using the <code>fn:deep-equal</code>
                        function, under the collation supplied in the original call to
                           <code>fn:deep-equal</code>).</p>
                  </item>
               </olist>
            </item>
         </olist>
         <p diff="add" at="A">If <code>$i1</code> and <code>$i2</code> are both <termref
               def="dt-array">arrays</termref>, the result is <code>true</code> if and only if all
            the following conditions apply:</p>
         <olist diff="add" at="A">
            <item>
               <p>Both arrays have the same number of members (<code>array:size($i1) eq
                     array:size($i2)</code>).</p>
            </item>
            <item>
               <p>Members in the same position of both arrays are deep-equal to each other, under
                  the collation supplied in the original call to <code>fn:deep-equal</code>: that is,
                     <code>every $p in 1 to array:size($i1) satisfies deep-equal($i1($p), $i2($p),
                     $collation)</code></p>
            </item>
         </olist>
         <p>If <code>$i1</code> and <code>$i2</code> are both nodes, they are compared as described
            below:</p>
         <olist>
            <item>
               <p>If the two nodes are of different kinds, the result is <code>false</code>.</p>
            </item>
            <item>
               <p>If the two nodes are both document nodes then they are deep-equal if and only if
                  the sequence <code>$i1/(*|text())</code> is deep-equal to the sequence
                     <code>$i2/(*|text())</code>.</p>
            </item>
            <item>
               <p> If the two nodes are both element nodes then they are deep-equal if and only if
                  all of the following conditions are satisfied:</p>
               <olist>
                  <item>
                     <p>The two nodes have the same name, that is <code>(node-name($i1) eq
                           node-name($i2))</code>.</p>
                  </item>
                  <item>
                     <!-- bug 17252 -->
                     <p>Either both nodes are annotated as having simple content or both nodes
                        are annotated as having complex content. For this purpose "simple content"
                        means either a simple type or a complex type with simple content; "complex
                        content" means a complex type whose variety is mixed, element-only, or
                        empty.</p>
                     <note>
                        <p>It is a consequence of this rule that validating a document <var>D</var>
                           against a schema will usually (but not necessarily) result in a document
                           that is not deep-equal to <var>D</var>. The exception is when the schema
                           allows all elements to have mixed content.</p>
                     </note>
                  </item>
                  <item>
                     <p>The two nodes have the same number of attributes, and for every attribute
                           <code>$a1</code> in <code>$i1/@*</code> there exists an attribute
                           <code>$a2</code> in <code>$i2/@*</code> such that <code>$a1</code> and
                           <code>$a2</code> are deep-equal.</p>
                  </item>
                  <item>
                     <p> One of the following conditions holds:</p>
                     <ulist>
                        <item>
                           <p>Both element nodes are annotated as having simple content (as defined
                              in 3(b) above), and the typed value of <code>$i1</code> is deep-equal
                              to the typed value of <code>$i2</code>.</p>
                        </item>
                        <item>
                           <p>Both element nodes have a type annotation that is a complex type with
                              variety element-only, and the sequence <code>$i1/*</code> is
                              deep-equal to the sequence <code>$i2/*</code>.</p>
                        </item>
                        <item>
                           <p>Both element nodes have a type annotation that is a complex type with
                              variety mixed, and the sequence <code>$i1/(*|text())</code> is
                              deep-equal to the sequence <code>$i2/(*|text())</code>.</p>
                        </item>
                        <item>
                           <p>Both element nodes have a type annotation that is a complex type with
                              variety empty.</p>
                        </item>
                     </ulist>
                  </item>
               </olist>
            </item>
            <item>
               <p>If the two nodes are both attribute nodes then they are deep-equal if and only if
                  both the following conditions are satisfied:</p>
               <olist>
                  <item>
                     <p>The two nodes have the same name, that is <code>(node-name($i1) eq
                           node-name($i2))</code>.</p>
                  </item>
                  <item>
                     <p>The typed value of <code>$i1</code> is deep-equal to the typed value of
                           <code>$i2</code>.</p>
                  </item>
               </olist>
            </item>
            <item>
               <p>If the two nodes are both processing instruction nodes, then they are deep-equal
                  if and only if both the following conditions are satisfied:</p>
               <olist>
                  <item>
                     <p>The two nodes have the same name, that is <code>(node-name($i1) eq
                           node-name($i2))</code>.</p>
                  </item>
                  <item>
                     <p>The string value of <code>$i1</code> is equal to the string value of
                           <code>$i2</code>.</p>
                  </item>
               </olist>
            </item>
            <item>
               <p> If the two nodes are both namespace nodes, then they are deep-equal if and only
                  if both the following conditions are satisfied:</p>
               <olist>
                  <item>
                     <p>The two nodes either have the same name or are both nameless, that is
                           <code>fn:deep-equal(node-name($i1), node-name($i2))</code>.</p>
                  </item>
                  <item>
                     <p>The string value of <code>$i1</code> is equal to the string value of
                           <code>$i2</code> when compared using the Unicode codepoint collation.</p>
                  </item>
               </olist>
            </item>
            <item>
               <p>If the two nodes are both text nodes or comment nodes, then they are deep-equal if
                  and only if their string-values are equal.</p>
            </item>
         </olist>
         <p diff="add" at="A">In all other cases the result is false.</p>
      </fos:rules>
      <fos:errors>
         <p>A type error is raised <errorref class="TY" code="0015" type="type"/> if either input
            sequence contains a function item <phrase diff="add" at="A">that is not a map or
               array</phrase>. </p>
      </fos:errors>
      <fos:notes>
         <p>The two nodes are not required to have the same type annotation, and they are not
            required to have the same in-scope namespaces. They may also differ in their parent,
            their base URI, and the values returned by the <code>is-id</code> and
               <code>is-idrefs</code> accessors (see <xspecref spec="DM31" ref="dm-is-id"/> and
               <xspecref spec="DM31" ref="dm-is-idrefs"/>). The order of children is significant,
            but the order of attributes is insignificant. </p>
         <p>The contents of comments and processing instructions are significant only if these nodes
            appear directly as items in the two sequences being compared. The content of a comment
            or processing instruction that appears as a descendant of an item in one of the
            sequences being compared does not affect the result. However, the presence of a comment
            or processing instruction, if it causes a text node to be split into two text nodes, may
            affect the result.</p>
         <p diff="add" at="A">Comparing items of different kind (for example, comparing an atomic
            value to a node, or a map to an array, or an integer to an <code>xs:date</code>) returns false, it does not return an error. So
            the result of <code>fn:deep-equal(1, current-dateTime())</code> is <code>false</code>.</p>
         <p diff="add" at="A">Comparing a function (other than a map or array) to any other value raises a type error.</p>
      </fos:notes>
      <fos:examples>
         <fos:variable name="at"  id="v-deep-equal-at" as="element()">&lt;attendees&gt; &lt;name last='Parker'
            first='Peter'/&gt; &lt;name last='Barker' first='Bob'/&gt; &lt;name last='Parker'
            first='Peter'/&gt; &lt;/attendees&gt;</fos:variable>
         <fos:example>
            <fos:test use="v-deep-equal-at">
               <fos:expression>fn:deep-equal($at, $at/*)</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-deep-equal-at">
               <fos:expression>fn:deep-equal($at/name[1], $at/name[2])</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-deep-equal-at">
               <fos:expression>fn:deep-equal($at/name[1], $at/name[3])</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-deep-equal-at">
               <fos:expression>fn:deep-equal($at/name[1], 'Peter Parker')</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:deep-equal(map{1:'a', 2:'b'}, map{2:'b', 1:'a'})</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:deep-equal([1, 2, 3], [1, 2, 3])</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:deep-equal((1, 2, 3), [1, 2, 3])</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="count" prefix="fn">
      <fos:signatures>
         <fos:proto name="count" return-type="xs:integer">
            <fos:arg name="arg" type="item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the number of items in a sequence.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the number of items in the value of <code>$arg</code>.</p>
      </fos:rules>
      <fos:notes>
         <p>Returns 0 if <code>$arg</code> is the empty sequence.</p>
      </fos:notes>
      <fos:examples>
         <fos:variable name="seq1" id="v-count-seq1" select="($item1, $item2)"/>
         <fos:variable name="seq2" id="v-count-seq2" select="(98.5, 98.3, 98.9)"/>
         <fos:variable name="seq3" id="v-count-seq3" select="()"/>
         <fos:example>
            <fos:test use="v-po v-item1 v-item2 v-count-seq1">
               <fos:expression>fn:count($seq1)</fos:expression>
               <fos:result>2</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-count-seq3">
               <fos:expression>fn:count($seq3)</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-count-seq2">
               <fos:expression>fn:count($seq2)</fos:expression>
               <fos:result>3</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-count-seq2">
               <fos:expression>fn:count($seq2[. &gt; 100])</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:count([])</fos:expression>
               <fos:result>1</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:count([1,2,3])</fos:expression>
               <fos:result>1</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="avg" prefix="fn">
      <fos:signatures>
         <fos:proto name="avg" return-type="xs:anyAtomicType?">
            <fos:arg name="arg" type="xs:anyAtomicType*" usage="absorption"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the average of the values in the input sequence <code>$arg</code>, that is, the
            sum of the values divided by the number of values.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the empty sequence is returned.</p>
         <p>If <code>$arg</code> contains values of type <code>xs:untypedAtomic</code> they are cast
            to <code>xs:double</code>. </p>
         <p>Duration values must either all be <code>xs:yearMonthDuration</code> values or must all
            be <code>xs:dayTimeDuration</code> values. For numeric values, the numeric promotion
            rules defined in <specref ref="op.numeric"/> are used to promote all values to a single
            common type. After these operations, <code>$arg</code> must satisfy the following condition:</p>        
         <p>There must be a type <var>T</var> such that:</p>
            <olist>
               <item>every item in <code>$arg</code> is an instance of <var>T</var>.</item>
               <item><var>T</var> is one of <code>xs:double</code>, <code>xs:float</code>,
                  <code>xs:decimal</code>, <code>xs:yearMonthDuration</code>, or
                  <code>xs:dayTimeDuration</code>.</item>
            </olist>
     

         <p>The function returns the average of the values as <code>sum($arg) div
            count($arg)</code>; but the implementation may use an otherwise equivalent algorithm
            that avoids arithmetic overflow.</p>

      </fos:rules>
      <fos:errors>
         <p>A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains
            items of incompatible types, as described above.</p>
      </fos:errors>
      <fos:examples>
         <fos:variable id="v-avg-d1" name="d1" select="xs:yearMonthDuration(&quot;P20Y&quot;)"/>
         <fos:variable id="v-avg-d2" name="d2" select="xs:yearMonthDuration(&quot;P10M&quot;)"/>
         <fos:variable id="v-avg-seq3" name="seq3" select="(3, 4, 5)"/>
         <fos:example>
            <fos:test use="v-avg-seq3">
               <fos:expression>fn:avg($seq3)</fos:expression>
               <fos:result>4.0</fos:result>
               <fos:postamble>The result is of type <code>xs:decimal</code>.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-avg-d1 v-avg-d2">
               <fos:expression>fn:avg(($d1, $d2))</fos:expression>
               <fos:result>xs:yearMonthDuration("P10Y5M")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p><code>fn:avg(($d1, $seq3))</code> raises a type error <errorref class="RG"
                  code="0006"/>. </p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:avg(())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:avg((xs:float('INF'), xs:float('-INF')))</fos:expression>
               <fos:result>xs:float('NaN')</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-avg-seq3">
               <fos:expression>fn:avg(($seq3, xs:float('NaN')))</fos:expression>
               <fos:result>xs:float('NaN')</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="max" prefix="fn">
      <fos:signatures>
         <fos:proto name="max" return-type="xs:anyAtomicType?">
            <fos:arg name="arg" type="xs:anyAtomicType*"/>
         </fos:proto>
         <fos:proto name="max" return-type="xs:anyAtomicType?">
            <fos:arg name="arg" type="xs:anyAtomicType*"/>
            <fos:arg name="collation" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations static-base-uri implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a value that is equal to the highest value appearing in the input sequence.</p>
      </fos:summary>
      <fos:rules>
         <p>The following conversions are applied to the input sequence <code>$arg</code>, in order:</p>
         <olist>
            <item>
               <p>Values of type <code>xs:untypedAtomic</code> in <code>$arg</code> are cast to
                     <code>xs:double</code>.</p>
            </item>
            <item diff="chg" at="B">
               <p>If the resulting sequence contains values that are instances of more than one primitive type
                  (meaning the 19 primitive types defined in <bibref ref="xmlschema11-2"/>), then:
               </p>
               <olist>
                  <item><p>If each value is an instance of one of the types <code>xs:string</code> or <code>xs:anyURI</code>,
                  then all the values are cast to type <code>xs:string</code>.</p></item>
                  <item><p>If each value is an instance of one of the types <code>xs:decimal</code> or <code>xs:float</code>,
                     then all the values are cast to type <code>xs:float</code>.</p></item>
                  <item><p>If each value is an instance of one of the types <code>xs:decimal</code>, <code>xs:float</code>,
                     or <code>xs:double</code>, then all the values are cast to type <code>xs:double</code>.</p></item>
                  <item><p>Otherwise, a type error is raised <errorref class="RG" code="0006"/>.</p></item>
               </olist>
               <note><p>The primitive type of an <code>xs:integer</code> value for this purpose is <code>xs:decimal</code>.</p></note>
            </item>
 
         </olist>
         <p>The items in the resulting sequence may be reordered in an arbitrary order. The
            resulting sequence is referred to below as the converted sequence. The function returns
            an item from the converted sequence rather than the input sequence. </p>
         <p>If the converted sequence is empty, the function returns the empty sequence.</p>
         <p>All items in the converted sequence must be derived from a single base type for which
            the <code>le</code> operator is defined. In addition, the values in the sequence must
            have a total order. If date/time values do not have a timezone, they are considered to
            have the implicit timezone provided by the dynamic context for the purpose of
            comparison. Duration values must either all be <code>xs:yearMonthDuration</code> values
            or must all be <code>xs:dayTimeDuration</code> values.</p>
         <p>If the converted sequence contains the value <code>NaN</code>, the value
               <code>NaN</code> is returned 
            <phrase diff="add" at="B">(as an <code>xs:float</code> or <code>xs:double</code> as appropriate)</phrase>.</p>
         <p>If the items in the converted sequence are of type <code>xs:string</code> or types
            derived by restriction from <code>xs:string</code>, then the determination of the item
            with the smallest value is made according to the collation that is used. If the type of
            the items in the converted sequence is not <code>xs:string</code> and
               <code>$collation</code> is specified, the collation is ignored.</p>
         <p>The collation used by this function is determined according to the rules in <specref
               ref="choosing-a-collation"/>.</p>
         <p>The function returns the result of the expression:</p>
         <eg xml:space="preserve">
   if (every $v in $c satisfies $c[1] ge $v)
   then $c[1] 
   else fn:max(fn:tail($c))</eg>
         <p>evaluated with <code>$collation</code> as the default collation if specified, and with
               <code>$c</code> as the converted sequence.</p>

      </fos:rules>
      <fos:errors>
         <p>A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains
            items of incompatible types, as described above.</p>
      </fos:errors>
      <fos:notes>
         <p>Because the rules allow the sequence to be reordered, if there are two or more items that are
            "equal highest", the specific item whose value is returned is <termref
               def="implementation-dependent">implementation-dependent</termref>. This can arise for example if two different strings
            compare equal under the selected collation, or if two different <code>xs:dateTime</code>
            values compare equal despite being in different timezones.</p>
         <p>If the converted sequence contains exactly one value then that value is returned.</p>
         <p>The default type when the <code>fn:max</code> function is applied to
               <code>xs:untypedAtomic</code> values is <code>xs:double</code>. This differs from the
            default type for operators such as <code>gt</code>, and for sorting in XQuery and XSLT,
            which is <code>xs:string</code>.</p>
         <p diff="add" at="B">The rules for the dynamic type of the result are stricter in version 3.1 of the specification than
         in earlier versions. For example, if all the values in the input sequence belong to types derived from
         <code>xs:integer</code>, version 3.0 required only that the result be an instance
         of the least common supertype of the types present in the input sequence; Version 3.1
         requires that the returned value retains its original type. This does not apply, however, where type promotion
         is needed to convert all the values to a common primitive type.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:max((3,4,5))</fos:expression>
               <fos:result>5</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:max([3,4,5])</fos:expression>
               <fos:result>5</fos:result>
               <fos:postamble>Arrays are atomized</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:max((xs:integer(5), xs:float(5.0), xs:double(0)))</fos:expression>
               <fos:result>xs:double(5.0e0)</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p><code>fn:max((3,4,"Zero"))</code> raises a type error <errorref class="RG"
                  code="0006"/>. </p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:max((fn:current-date(), xs:date("2100-01-01")))</fos:expression>
               <fos:result>xs:date("2100-01-01")</fos:result>
               <fos:postamble>Assuming that the current date is during the 21st
                  century.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:max(("a", "b", "c"))</fos:expression>
               <fos:result>"c"</fos:result>
               <fos:postamble>Assuming a typical default collation.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="min" prefix="fn">
      <fos:signatures>
         <fos:proto name="min" return-type="xs:anyAtomicType?">
            <fos:arg name="arg" type="xs:anyAtomicType*"/>
         </fos:proto>
         <fos:proto name="min" return-type="xs:anyAtomicType?">
            <fos:arg name="arg" type="xs:anyAtomicType*"/>
            <fos:arg name="collation" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations static-base-uri implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a value that is equal to the lowest value appearing in the input sequence.</p>
      </fos:summary>
      <fos:rules>
         <p>The following rules are applied to the input sequence:</p>
         <ulist>
            <item>
               <p>Values of type <code>xs:untypedAtomic</code> in <code>$arg</code> are cast to
                     <code>xs:double</code>.</p>
            </item>
            <item diff="chg" at="B">
               <p>If the resulting sequence contains values that are instances of more than one primitive type
                  (meaning the 19 primitive types defined in <bibref ref="xmlschema11-2"/>), then:
               </p>
               <olist>
                  <item><p>If each value is an instance of one of the types <code>xs:string</code> or <code>xs:anyURI</code>,
                     then all the values are cast to type <code>xs:string</code>.</p></item>
                  <item><p>If each value is an instance of one of the types <code>xs:decimal</code> or <code>xs:float</code>,
                     then all the values are cast to type <code>xs:float</code>.</p></item>
                  <item><p>If each value is an instance of one of the types <code>xs:decimal</code>, <code>xs:float</code>,
                     or <code>xs:double</code>, then all the values are cast to type <code>xs:double</code>.</p></item>
                  <item><p>Otherwise, a type error is raised <errorref class="RG" code="0006"/>.</p></item>
               </olist>
               <note><p>The primitive type of an <code>xs:integer</code> value for this purpose is <code>xs:decimal</code>.</p></note>
            </item>
         </ulist>
         <p>The items in the resulting sequence may be reordered in an arbitrary order. The
            resulting sequence is referred to below as the converted sequence. The function returns
            an item from the converted sequence rather than the input sequence. </p>
         <p>If the converted sequence is empty, the empty sequence is returned.</p>
         <p>All items in the converted sequence must be derived from a single base type for which
            the <code>le</code> operator is defined. In addition, the values in the sequence must
            have a total order. If date/time values do not have a timezone, they are considered to
            have the implicit timezone provided by the dynamic context for the purpose of
            comparison. Duration values must either all be <code>xs:yearMonthDuration</code> values
            or must all be <code>xs:dayTimeDuration</code> values.</p>
         <p>If the converted sequence contains the value <code>NaN</code>, the value
               <code>NaN</code> is returned
            <phrase diff="add" at="B">(as an <code>xs:float</code> or <code>xs:double</code> as appropriate)</phrase>.</p>
         <p>If the items in the converted sequence are of type <code>xs:string</code> or types
            derived by restriction from <code>xs:string</code>, then the determination of the item
            with the smallest value is made according to the collation that is used. If the type of
            the items in the converted sequence is not <code>xs:string</code> and
               <code>$collation</code> is specified, the collation is ignored.</p>
         <p>The collation used by this function is determined according to the rules in <specref
               ref="choosing-a-collation"/>.</p>
         <p>The function returns the result of the expression:</p>
         <eg xml:space="preserve">
   if (every $v in $c satisfies $c[1] le $v) 
   then $c[1] 
   else fn:min(fn:tail($c))</eg>
         <p>evaluated with <code>$collation</code> as the default collation if specified, and with
               <code>$c</code> as the converted sequence.</p>

      </fos:rules>
      <fos:errors>
         <p>A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains
            items of incompatible types, as described above.</p>
      </fos:errors>
      <fos:notes>
         <p>Because the rules allow the sequence to be reordered, if there are two or items that are
            "equal lowest", the specific item whose value is returned is <termref
               def="implementation-dependent">implementation-dependent</termref>. This can arise for example if two different strings
            compare equal under the selected collation, or if two different <code>xs:dateTime</code>
            values compare equal despite being in different timezones.</p>
         <p>If the converted sequence contains exactly one value then that value is returned.</p>
         <p>The default type when the <code>fn:min</code> function is applied to
               <code>xs:untypedAtomic</code> values is <code>xs:double</code>. This differs from the
            default type for operators such as <code>lt</code>, and for sorting in XQuery and XSLT,
            which is <code>xs:string</code>.</p>
         <p diff="add" at="B">The rules for the dynamic type of the result are stricter in version 3.1 of the specification than
            in earlier versions. For example, if all the values in the input sequence belong to types derived from
            <code>xs:integer</code>, version 3.0 required only that the result be an instance
            of the least common supertype of the types present in the input sequence; Version 3.1
            requires that the returned value retains its original type. This does not apply, however, where type promotion
            is needed to convert all the values to a common primitive type.</p>

      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:min((3,4,5))</fos:expression>
               <fos:result>3</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:min([3,4,5])</fos:expression>
               <fos:result>3</fos:result>
               <fos:postamble>Arrays are atomized</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:min((xs:integer(5), xs:float(5), xs:double(10)))</fos:expression>
               <fos:result>xs:double(5.0e0)</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p><code>fn:min((3,4,"Zero"))</code> raises a type error <errorref class="RG"
                  code="0006"/>. </p>
         </fos:example>
         <fos:example>
            <p><code>fn:min((xs:float(0.0E0), xs:float(-0.0E0)))</code> can return either positive
               or negative zero. The two items are equal, so it is <termref
                  def="implementation-dependent">implementation-dependent</termref> which is returned.</p>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:min((fn:current-date(), xs:date("1900-01-01")))</fos:expression>
               <fos:result>xs:date("1900-01-01")</fos:result>
               <fos:postamble>Assuming that the current date is set to a reasonable
                  value.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:min(("a", "b", "c"))</fos:expression>
               <fos:result>"a"</fos:result>
               <fos:postamble>Assuming a typical default collation.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="sum" prefix="fn">
      <fos:signatures>
         <fos:proto name="sum" return-type="xs:anyAtomicType">
            <fos:arg name="arg" type="xs:anyAtomicType*"/>
         </fos:proto>
         <fos:proto name="sum" return-type="xs:anyAtomicType?">
            <fos:arg name="arg" type="xs:anyAtomicType*"/>
            <fos:arg name="zero" type="xs:anyAtomicType?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a value obtained by adding together the values in <code>$arg</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>Any values of type <code>xs:untypedAtomic</code> in <code>$arg</code> are cast to
               <code>xs:double</code>. The items in the resulting sequence may be reordered in an
            arbitrary order. The resulting sequence is referred to below as the converted
            sequence.</p>
         <p>If the converted sequence is empty, then the single-argument form of the function
            returns the <code>xs:integer</code> value <code>0</code>; the two-argument form returns
            the value of the argument <code>$zero</code>.</p>
         <p>If the converted sequence contains the value <code>NaN</code>, <code>NaN</code> is
            returned.</p>
         <p>All items in <code>$arg</code> must be numeric or derived from a single base type. In
            addition, the type must support addition. Duration values must either all be
               <code>xs:yearMonthDuration</code> values or must all be
               <code>xs:dayTimeDuration</code> values. For numeric values, the numeric promotion
            rules defined in <specref ref="op.numeric"/> are used to promote all values to a single
            common type. The sum of a sequence of integers will therefore be an integer, while the
            sum of a numeric sequence that includes at least one <code>xs:double</code> will be an
               <code>xs:double</code>. </p>
         <p>The result of the function, using the second signature, is the result of the
            expression:</p>
         <eg xml:space="preserve">
if (fn:count($c) eq 0) then
    $zero
else if (fn:count($c) eq 1) then
    $c[1]
else
    $c[1] + fn:sum(subsequence($c, 2))</eg>
         <p>where <code>$c</code> is the converted sequence.</p>
         <p>The result of the function, using the first signature, is the result of the expression:
               <code>fn:sum($arg, 0)</code>.</p>

      </fos:rules>
      <fos:errors>
         <p>A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains
            items of incompatible types, as described above.</p>

      </fos:errors>
      <fos:notes>
         <p>The second argument allows an appropriate value to be defined to represent the sum of an
            empty sequence. For example, when summing a sequence of durations it would be
            appropriate to return a zero-length duration of the appropriate type. This argument is
            necessary because a system that does dynamic typing cannot distinguish "an empty
            sequence of integers", for example, from "an empty sequence of durations".</p>
         <p> If the converted sequence contains exactly one value then that value is returned.</p>
      </fos:notes>
      <fos:examples>
         <fos:variable name="d1"  id="v-sum-d1" select="xs:yearMonthDuration(&quot;P20Y&quot;)"/>
         <fos:variable name="d2"  id="v-sum-d2" select="xs:yearMonthDuration(&quot;P10M&quot;)"/>
         <fos:variable name="seq1"  id="v-sum-seq1" select="($d1, $d2)"/>
         <fos:variable name="seq3"  id="v-sum-seq3" select="(3, 4, 5)"/>
         <fos:example>
            <fos:test use="v-sum-d1 v-sum-d2">
               <fos:expression>fn:sum(($d1, $d2))</fos:expression>
               <fos:result>xs:yearMonthDuration("P20Y10M")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-sum-d1 v-sum-d2 v-sum-seq1">
               <fos:expression>fn:sum($seq1[. lt xs:yearMonthDuration('P3M')],
                  xs:yearMonthDuration('P0M'))</fos:expression>
               <fos:result>xs:yearMonthDuration("P0M")</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-sum-seq3">
               <fos:expression>fn:sum($seq3)</fos:expression>
               <fos:result>12</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:sum(())</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:sum((),())</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:sum((1 to 100)[. lt 0], 0) </fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p><code>fn:sum(($d1, 9E1))</code> raises a type error <errorref class="RG" code="0006"
               />. </p>
         </fos:example>
         <fos:example>
            <fos:test use="v-sum-d1 v-sum-d2">
               <fos:expression>fn:sum(($d1, $d2), "ein Augenblick")</fos:expression>
               <fos:result>xs:yearMonthDuration("P20Y10M")</fos:result>
               <fos:postamble>There is no requirement that the <code>$zero</code> value should be
                  the same type as the items in <code>$arg</code>, or even that it should belong to
                  a type that supports addition.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:sum([1, 2, 3])</fos:expression>
               <fos:result>6</fos:result>
               <fos:postamble>Atomizing an array returns the sequence obtained by atomizing its members.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:sum([[1, 2], [3, 4]])</fos:expression>
               <fos:result>10</fos:result>
               <fos:postamble>Atomizing an array returns the sequence obtained by atomizing its members.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <!--<fos:function name="to" prefix="op">
      <fos:signatures>
         <fos:proto name="to" return-type="xs:integer*">
            <fos:arg name="firstval" type="xs:integer"/>
            <fos:arg name="lastval" type="xs:integer"/>
         </fos:proto>
      </fos:signatures>
      <fos:opermap operator="to" types="xs:integer xs:integer">Defines the semantics of the "to"
         operator when applied to two integer arguments.</fos:opermap>
      <fos:summary>
         <p>Returns a sequence of consecutive integers in a given range.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the sequence containing every <code>xs:integer</code> whose value
            is between the value of <code>$firstval</code> (inclusive) and the value of
               <code>$lastval</code> (inclusive), in monotonic increasing order.</p>
         <p>If the value of the first operand is greater than the value of the second, the function
            returns the empty sequence.</p>
         <p>If the values of the two operands are equal, the function returns a sequence containing
            a single <code>xs:integer</code> equal to that value.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>1 to 3</fos:expression>
               <fos:result>(1, 2, 3)</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>3 to 1</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>5 to 5</fos:expression>
               <fos:result>5</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>-->
   <fos:function name="id" prefix="fn">
      <fos:signatures>
         <fos:proto name="id" return-type="element()*">
            <fos:arg name="arg" type="xs:string*"/>
         </fos:proto>
         <fos:proto name="id" return-type="element()*">
            <fos:arg name="arg" type="xs:string*"/>
            <fos:arg name="node" type="node()" default="." usage="navigation"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the sequence of element nodes that have an <code>ID</code> value matching the
            value of one or more of the <code>IDREF</code> values supplied in <code>$arg</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns a sequence, in document order with duplicates eliminated,
            containing every element node <code>E</code> that satisfies all the following
            conditions:</p>
         <olist>
            <item>
               <p>
                  <code>E</code> is in the target document. The target document is the document
                  containing <code>$node</code>, or the document containing the context item
                     (<code>.</code>) if the second argument is omitted. The behavior of the
                  function if <code>$node</code> is omitted is exactly the same as if the context
                  item had been passed as <code>$node</code>.</p>
            </item>
            <item>
               <p><code>E</code> has an <code>ID</code> value equal to one of the candidate
                     <code>IDREF</code> values, where:</p>
               <ulist>
                  <item>
                     <p> An element has an <code>ID</code> value equal to <code>V</code> if either
                        or both of the following conditions are true:</p>
                     <ulist>
                        <item>
                           <p>The <code>is-id</code> property (See <xspecref spec="DM31"
                                 ref="dm-is-id"/>.) of the element node is true, and the typed value
                              of the element node is equal to <code>V</code> under the rules of the
                                 <code>eq</code> operator using the Unicode codepoint collation
                                 (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p>
                        </item>
                        <item>
                           <p>The element has an attribute node whose <code>is-id</code> property
                              (See <xspecref spec="DM31" ref="dm-is-id"/>.) is true and whose typed
                              value is equal to <code>V</code> under the rules of the
                                 <code>eq</code> operator using the Unicode code point collation
                                 (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p>
                        </item>
                     </ulist>
                  </item>
                  <item>
                     <p> Each <code>xs:string</code> in <code>$arg</code> is parsed as if it were of
                        type <code>IDREFS</code>, that is, each <code>xs:string</code> in
                           <code>$arg</code> is treated as a whitespace-separated sequence of
                        tokens, each acting as an <code>IDREF</code>. These tokens are then included
                        in the list of candidate <code>IDREF</code>s. If any of the tokens is not a
                        lexically valid <code>IDREF</code> (that is, if it is not lexically an
                           <code>xs:NCName</code>), it is ignored. Formally, the candidate
                           <code>IDREF</code> values are the strings in the sequence given by the
                        expression:</p>
                     <eg xml:space="preserve">for $s in $arg return 
    fn:tokenize(fn:normalize-space($s), ' ')[. castable as xs:IDREF]</eg>

                  </item>
               </ulist>
            </item>
            <item>
               <p>If several elements have the same <code>ID</code> value, then <code>E</code> is
                  the one that is first in document order.</p>
            </item>
         </olist>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="DC" code="0001" type="dynamic"/> if
               <code>$node</code>, or the context item if the second argument is absent, is a node
            in a tree whose root is not a document node.</p>
         <p>The following errors may be raised when <code>$node</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>

      </fos:errors>
      <fos:notes>
         <p>The effect of this function is anomalous in respect of element nodes with the
               <code>is-id</code> property. For legacy reasons, this function returns the element
            that has the <code>is-id</code> property, whereas it would be more appropriate to return
            its parent, that being the element that is uniquely identified by the ID. A new function
               <code>fn:element-with-id</code> has been introduced with the desired
            behavior.</p>

         <p> If the data model is constructed from an Infoset, an attribute will have the
               <code>is-id</code> property if the corresponding attribute in the Infoset had an
            attribute type of <code>ID</code>: typically this means the attribute was declared as an
               <code>ID</code> in a DTD.</p>
         <!--Text replaced by erratum E13 change 1"-->
         <p> If the data model is constructed from a PSVI, an element or attribute will have the
               <code>is-id</code> property if its typed value is a single atomic value of type
               <code>xs:ID</code> or a type derived by restriction from <code>xs:ID</code>.</p>
         <!--End of text replaced by erratum E13-->
         <p> No error is raised in respect of a candidate <code>IDREF</code> value that does not
            match the <code>ID</code> of any element in the document. If no candidate
               <code>IDREF</code> value matches the <code>ID</code> value of any element, the
            function returns the empty sequence.</p>
         <p> It is not necessary that the supplied argument should have type <code>xs:IDREF</code>
            or <code>xs:IDREFS</code>, or that it should be derived from a node with the
               <code>is-idrefs</code> property.</p>
         <p> An element may have more than one <code>ID</code> value. This can occur with synthetic
            data models or with data models constructed from a PSVI where the element and one of its
            attributes are both typed as <code>xs:ID</code>.</p>
         <p> If the source document is well-formed but not valid, it is possible for two or more
            elements to have the same <code>ID</code> value. In this situation, the function will
            select the first such element.</p>
         <p> It is also possible in a well-formed but invalid document to have an element or
            attribute that has the <code>is-id</code> property but whose value does not conform to
            the lexical rules for the <code>xs:ID</code> type. Such a node will never be selected by
            this function.</p>
      </fos:notes>
      <fos:examples>
         <fos:variable name="emp"  id="v-id-emp" as="document-node()"><![CDATA[
        validate lax{    
          document{
            <employee xml:id="ID21256"
                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
                      xmlns:xs="http://www.w3.org/2001/XMLSchema">
               <empnr xsi:type="xs:ID">E21256</empnr>
               <first>John</first>
               <last>Brown</last>
            </employee>
          }
        }]]>
         </fos:variable>
         <fos:example>
            <fos:test xslt-version="3.0" use="v-id-emp">
               <fos:expression>$emp/id('ID21256')/name()</fos:expression>
               <fos:result>"employee"</fos:result>
               <fos:postamble>The <code>xml:id</code> attribute has the <code>is-id</code> property,
                  so the employee element is selected.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test xslt-version="3.0" use="v-id-emp">
               <fos:expression>$emp/id('E21256')/name()</fos:expression>
               <fos:result>"empnr"</fos:result>
               <fos:postamble>Assuming the <code>empnr</code> element is given the type
                     <code>xs:ID</code> as a result of schema validation, the element will have the
                     <code>is-id</code> property and is therefore selected. Note the difference from
                  the behavior of <code>fn:element-with-id</code>.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="element-with-id" prefix="fn">
      <fos:signatures>
         <fos:proto name="element-with-id" return-type="element()*">
            <fos:arg name="arg" type="xs:string*"/>
         </fos:proto>
         <fos:proto name="element-with-id" return-type="element()*">
            <fos:arg name="arg" type="xs:string*"/>
            <fos:arg name="node" type="node()" default="." usage="navigation"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p> Returns the sequence of element nodes that have an <code>ID</code> value matching the
            value of one or more of the <code>IDREF</code> values supplied in <code>$arg</code>.</p>
      </fos:summary>
      <fos:rules>

         <note>
            <p>The effect of this function is identical to <code>fn:id</code> in respect of
               elements that have an attribute with the <code>is-id</code> property. However, it
               behaves differently in respect of element nodes with the <code>is-id</code> property.
               Whereas the <code>fn:id</code> function, for legacy reasons, returns the element that has the
                  <code>is-id</code> property, this function returns the element identified by the ID,
               which is the parent of the element having the <code>is-id</code> property.</p>
         </note>
         <p>The function returns a sequence, in document order with duplicates eliminated,
            containing every element node <code>E</code> that satisfies all the following
            conditions:</p>
         <olist>
            <item>
               <p>
                  <code>E</code> is in the target document. The target document is the document
                  containing <code>$node</code>, or the document containing the context item
                     (<code>.</code>) if the second argument is omitted. The behavior of the
                  function if <code>$node</code> is omitted is exactly the same as if the context
                  item had been passed as <code>$node</code>.</p>
            </item>
            <item>
               <p><code>E</code> has an <code>ID</code> value equal to one of the candidate
                     <code>IDREF</code> values, where:</p>
               <ulist>
                  <item>
                     <p> An element has an <code>ID</code> value equal to <code>V</code> if either
                        or both of the following conditions are true:</p>
                     <ulist>
                        <item>
                           <p>The element has an child element node whose <code>is-id</code>
                              property (See <xspecref spec="DM31" ref="dm-is-id"/>.) is true and
                              whose typed value is equal to <code>V</code> under the rules of the
                                 <code>eq</code> operator using the Unicode code point collation
                                 (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p>
                        </item>
                        <item>
                           <p>The element has an attribute node whose <code>is-id</code> property
                              (See <xspecref spec="DM31" ref="dm-is-id"/>.) is true and whose typed
                              value is equal to <code>V</code> under the rules of the
                                 <code>eq</code> operator using the Unicode code point collation
                                 (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p>
                        </item>
                     </ulist>
                  </item>
                  <item>
                     <p>Each <code>xs:string</code> in <code>$arg</code> is parsed as if it were of
                        type <code>IDREFS</code>, that is, each <code>xs:string</code> in
                           <code>$arg</code> is treated as a whitespace-separated sequence of
                        tokens, each acting as an <code>IDREF</code>. These tokens are then included
                        in the list of candidate <code>IDREF</code>s. If any of the tokens is not a
                        lexically valid <code>IDREF</code> (that is, if it is not lexically an
                           <code>xs:NCName</code>), it is ignored. Formally, the candidate
                           <code>IDREF</code> values are the strings in the sequence given by the
                        expression:</p>
                     <eg xml:space="preserve">for $s in $arg return 
   fn:tokenize(fn:normalize-space($s), ' ')[. castable as xs:IDREF]</eg>
                  </item>
               </ulist>
            </item>
            <item>
               <p> If several elements have the same <code>ID</code> value, then <code>E</code> is
                  the one that is first in document order.</p>
            </item>
         </olist>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="DC" code="0001" type="dynamic"/> if
               <code>$node</code>, or the context item if the second argument is omitted, is a node
            in a tree whose root is not a document node.</p>
         <p>The following errors may be raised when <code>$node</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>

      </fos:errors>
      <fos:notes>
         <p>This function is equivalent to the <code>fn:id</code> function except when dealing with
            ID-valued element nodes. Whereas the <code>fn:id</code> function selects the element
            containing the identifier, this function selects its parent.</p>
         <p>If the data model is constructed from an Infoset, an attribute will have the
               <code>is-id</code> property if the corresponding attribute in the Infoset had an
            attribute type of <code>ID</code>: typically this means the attribute was declared as an
               <code>ID</code> in a DTD.</p>
         <!--Text replaced by erratum E13 change 1"-->
         <p> If the data model is constructed from a PSVI, an element or attribute will have the
               <code>is-id</code> property if its typed value is a single atomic value of type
               <code>xs:ID</code> or a type derived by restriction from <code>xs:ID</code>.</p>
         <!--End of text replaced by erratum E13-->
         <p> No error is raised in respect of a candidate <code>IDREF</code> value that does not
            match the <code>ID</code> of any element in the document. If no candidate
               <code>IDREF</code> value matches the <code>ID</code> value of any element, the
            function returns the empty sequence.</p>
         <p> It is not necessary that the supplied argument should have type <code>xs:IDREF</code>
            or <code>xs:IDREFS</code>, or that it should be derived from a node with the
               <code>is-idrefs</code> property.</p>
         <p> An element may have more than one <code>ID</code> value. This can occur with synthetic
            data models or with data models constructed from a PSVI where the element and one of its
            attributes are both typed as <code>xs:ID</code>.</p>
         <p> If the source document is well-formed but not valid, it is possible for two or more
            elements to have the same <code>ID</code> value. In this situation, the function will
            select the first such element.</p>
         <p> It is also possible in a well-formed but invalid document to have an element or
            attribute that has the <code>is-id</code> property but whose value does not conform to
            the lexical rules for the <code>xs:ID</code> type. Such a node will never be selected by
            this function.</p>
      </fos:notes>
      <fos:examples>
         <fos:variable name="emp" as="element()" id="v-element-with-id-emp"><![CDATA[
         validate lax{    
          document{
            <employee xml:id="ID21256"
                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
                      xmlns:xs="http://www.w3.org/2001/XMLSchema">
               <empnr xsi:type="xs:ID">E21256</empnr>
               <first>John</first>
               <last>Brown</last>
            </employee>
          }
        }]]>
         </fos:variable>
         <fos:example>
            <fos:test xslt-version="3.0" use="v-element-with-id-emp">
               <fos:expression>$emp/fn:element-with-id('ID21256')/name()</fos:expression>
               <fos:result>"employee"</fos:result>
               <fos:postamble>The <code>xml:id</code> attribute has the <code>is-id</code> property,
                  so the employee element is selected.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test xslt-version="3.0" use="v-element-with-id-emp">
               <fos:expression>$emp/fn:element-with-id('E21256')/name()</fos:expression>
               <fos:result>"employee"</fos:result>
               <fos:postamble>Assuming the <code>empnr</code> element is given the type
                     <code>xs:ID</code> as a result of schema validation, the element will have the
                     <code>is-id</code> property and is therefore its parent is selected. Note the
                  difference from the behavior of <code>fn:id</code>.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="idref" prefix="fn">
      <fos:signatures>
         <fos:proto name="idref" return-type="node()*">
            <fos:arg name="arg" type="xs:string*"/>
         </fos:proto>
         <fos:proto name="idref" return-type="node()*">
            <fos:arg name="arg" type="xs:string*"/>
            <fos:arg name="node" type="node()" default="." usage="navigation"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the sequence of element or attribute nodes with an <code>IDREF</code> value
            matching the value of one or more of the <code>ID</code> values supplied in
               <code>$arg</code>.</p>
      </fos:summary>
      <fos:rules>
         <p> The function returns a sequence, in document order with duplicates eliminated,
            containing every element or attribute node <code>$N</code> that satisfies all the
            following conditions:</p>
         <olist>
            <item>
               <p><code>$N</code> is in the target document. The target document is the document
                  containing <code>$node</code> or the document containing the context item
                     (<code>.</code>) if the second argument is omitted. The behavior of the
                  function if <code>$node</code> is omitted is exactly the same as if the context
                  item had been passed as <code>$node</code>.</p>
            </item>
            <item>
               <p><code>$N</code> has an <code>IDREF</code> value equal to one of the candidate
                     <code>ID</code> values, where:</p>
               <ulist>
                  <item>
                     <p>A node <code>$N</code> has an <code>IDREF</code> value equal to
                           <code>V</code> if both of the following conditions are true:</p>
                     <ulist>
                        <item>
                           <p>The <code>is-idrefs</code> property (see <xspecref spec="DM31"
                                 ref="dm-is-idrefs"/>) of <code>$N</code> is <code>true</code>.</p>
                        </item>
                        <item>
                           <p>The sequence <!--Text replaced by erratum E29 change 1"--></p>
                           <eg xml:space="preserve">fn:tokenize(fn:normalize-space(fn:string($N)), ' ')</eg>
                              <!--End of text replaced by erratum E29--> 
                           <p>contains a string that is
                              equal to <code>V</code> under the rules of the <code>eq</code>
                              operator using the Unicode code point collation
                                 (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p>
                        </item>
                     </ulist>
                  </item>
                  <item>
                     <p>Each <code>xs:string</code> in <code>$arg</code> is parsed as if it were of
                        lexically of type <code>xs:ID</code>. These <code>xs:string</code>s are then
                        included in the list of candidate <code>xs:ID</code>s. If any of the strings
                        in <code>$arg</code> is not a lexically valid <code>xs:ID</code> (that is,
                        if it is not lexically an <code>xs:NCName</code>), it is ignored. More
                        formally, the candidate <code>ID</code> values are the strings in the
                        sequence:</p>
                     <eg xml:space="preserve">$arg[. castable as xs:NCName]</eg>
                  </item>
               </ulist>
            </item>
         </olist>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="DC" code="0001" type="dynamic"/> if
               <code>$node</code>, or the context item if the second argument is omitted, is a node
            in a tree whose root is not a document node. </p>
         <p>The following errors may be raised when <code>$node</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>

      </fos:errors>
      <fos:notes>
         <p> An element or attribute typically acquires the <code>is-idrefs</code> property by being
            validated against the schema type <code>xs:IDREF</code> or <code>xs:IDREFS</code>, or
            (for attributes only) by being described as of type <code>IDREF</code> or
               <code>IDREFS</code> in a DTD.</p>
         <p diff="add" at="D">Because the function is sensitive to the way in which the data model
         is constructed, calls on this function are not always interoperable.</p>
         <p> No error is raised in respect of a candidate <code>ID</code> value that does not match
            the <code>IDREF</code> value of any element or attribute in the document. If no
            candidate <code>ID</code> value matches the <code>IDREF</code> value of any element or
            attribute, the function returns the empty sequence.</p>
         <p> It is possible for two or more nodes to have an <code>IDREF</code> value that matches a
            given candidate <code>ID</code> value. In this situation, the function will return all
            such nodes. However, each matching node will be returned at most once, regardless how
            many candidate <code>ID</code> values it matches.</p>
         <p> It is possible in a well-formed but invalid document to have a node whose
               <code>is-idrefs</code> property is true but that does not conform to the lexical
            rules for the <code>xs:IDREF</code> type. The effect of the above rules is that
            ill-formed candidate <code>ID</code> values and ill-formed <code>IDREF</code> values are
            ignored.</p>
         <p>If the data model is constructed from a PSVI, the typed value of a node that has the
               <code>is-idrefs</code> property will contain at least one atomic value of type
               <code>xs:IDREF</code> (or a type derived by restriction from <code>xs:IDREF</code>).
            It may also contain atomic values of other types. These atomic values are treated as
            candidate <code>ID</code> values <phrase diff="chg" at="D">if two conditions are met: their lexical form must be valid as an
               <code>xs:NCName</code>, and there must be at least one instance of <code>xs:IDREF</code>
            in the typed value of the node. If these conditions are not satisfied, such values are ignored.</phrase></p>

      </fos:notes>
      <fos:examples>
         <fos:variable name="emp" as="element()" id="v-idref-emp"><![CDATA[
      validate lax {  
        document {    
          <employees xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
                     xmlns:xs="http://www.w3.org/2001/XMLSchema">  
            <employee xml:id="ID21256">
               <empnr xsi:type="xs:ID">E21256</empnr>
               <first>Anil</first>
               <last>Singh</last>
               <deputy xsi:type="xs:IDREF">E30561</deputy>
            </employee>
            <employee xml:id="ID30561">
               <empnr xsi:type="xs:ID">E30561</empnr>
               <first>John</first>
               <last>Brown</last>
               <manager xsi:type="xs:IDREF">ID21256</manager>
            </employee>
          </employees>
        }
      }]]>
         </fos:variable>
         <fos:example>
            <fos:test xslt-version="3.0" use="v-idref-emp">
               <fos:expression>$emp/(element-with-id('ID21256')/@xml:id => fn:idref())/ancestor::employee/last => string()</fos:expression>
               <fos:result>"Brown"</fos:result>
               <fos:postamble>Assuming that <code>manager</code> has the is-idref property, the call on <code>fn:idref</code> selects
                  the <code>manager</code> element. If, instead, the <code>manager</code> had a <code>ref</code>
               attribute with the is-idref property, the call on <code>fn:idref</code> would select the attribute node.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test xslt-version="3.0" use="v-idref-emp">
               <fos:expression>$emp/(element-with-id('E30561')/empnr => fn:idref())/ancestor::employee/last => string()</fos:expression>
               <fos:result>"Singh"</fos:result>
               <fos:postamble>Assuming that <code>employee/deputy</code> has the is-idref property, the call on <code>fn:idref</code> selects
                  the <code>deputy</code> element.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="doc" prefix="fn">
      <fos:signatures>
         <fos:proto name="doc" return-type="document-node()?">
            <fos:arg name="uri" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="available-documents static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Retrieves a document using a URI supplied as an <code>xs:string</code>, and returns the
            corresponding document node.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$uri</code> is the empty sequence, the result is an empty sequence.</p>
         <p>If <code>$uri</code> is a relative URI reference, it is resolved relative to the value
            of the <term>static base URI</term> property from the static context. The resulting absolute URI is
            promoted to an <code>xs:string</code>.</p>
         <p>If the <term>available documents</term> described in <xspecref spec="XP31"
               ref="eval_context"/> provides a mapping from this string to a document node, the
            function returns that document node.</p>
         <p>The URI may include a fragment identifier.</p>
         <p>By default, this function is <termref def="deterministic">deterministic</termref>. Two
            calls on this function return the same document node if the same URI Reference (after
            resolution to an absolute URI Reference) is supplied to both calls. Thus, the following
            expression (if it does not raise an error) will always be true:</p>
         <eg xml:space="preserve">doc("foo.xml") is doc("foo.xml")</eg>
         <p>However, for performance reasons, implementations may provide a user option to evaluate
            the function without a guarantee of determinism. The manner in which any such option is
            provided is implementation-defined. If the user has not selected such an option, a call
            of the function must either return a deterministic result or must raise a dynamic error
               <errorref class="DC" code="0003"/>.</p>

         <note>
            <p>If <code>$uri</code> is read from a source document, it is generally appropriate to
               resolve it relative to the base URI property of the relevant node in the source
               document. This can be achieved by calling the <code>fn:resolve-uri</code> function,
               and passing the resulting absolute URI as an argument to the <code>fn:doc</code>
               function.</p>
         </note>
         <p>If two calls to this function supply different absolute URI References as arguments, the
            same document node may be returned if the implementation can determine that the two
            arguments refer to the same resource.</p>
         <p> By defining the semantics of this function in terms of a string-to-document-node
            mapping in the dynamic context, the specification is acknowledging that the results of
            this function are outside the purview of the language specification itself, and depend
            entirely on the run-time environment in which the expression is evaluated. This run-time
            environment includes not only an unpredictable collection of resources ("the web"), but
            configurable machinery for locating resources and turning their contents into document
            nodes within the XPath data model. Both the set of resources that are reachable, and the
            mechanisms by which those resources are parsed and validated, are <termref
               def="implementation-dependent">implementation-dependent</termref>.</p>
         <p> One possible processing model for this function is as follows. The resource identified
            by the URI Reference is retrieved. If the resource cannot be retrieved, a dynamic error
            is raised <errorref class="DC" code="0002"/>. The data resulting from the retrieval
            action is then parsed as an XML document and a tree is constructed in accordance with
            the <bibref ref="xpath-datamodel-30"/>. If the top-level media type is known and is
            "text", the content is parsed in the same way as if the media type were text/xml;
            otherwise, it is parsed in the same way as if the media type were application/xml. If
            the contents cannot be parsed successfully, a dynamic error is raised <errorref
               class="DC" code="0002"/>. Otherwise, the result of the function is the document node
            at the root of the resulting tree. This tree is then optionally validated against a
            schema.</p>
         <p>Various aspects of this processing are <termref def="implementation-defined">implementation-defined</termref>.
            Implementations may provide external configuration options that allow any aspect of the
            processing to be controlled by the user. In particular:</p>
         <ulist>
            <item>
               <p>The set of URI schemes that the implementation recognizes is
                  implementation-defined. Implementations may allow the mapping of URIs to resources
                  to be configured by the user, using mechanisms such as catalogs or user-written
                  URI handlers.</p>
            </item>
            <item>
               <p>The handling of non-XML media types is implementation-defined. Implementations may
                  allow instances of the data model to be constructed from non-XML resources, under
                  user control.</p>
            </item>
            <item>
               <p>It is <termref def="implementation-defined">implementation-defined</termref> whether DTD validation and/or schema
                  validation is applied to the source document.</p>
            </item>
            <item>
               <p>Implementations may provide user-defined error handling options that allow
                  processing to continue following an error in retrieving a resource, or in parsing
                  and validating its content. When errors have been handled in this way, the
                  function may return either an empty sequence, or a fallback document provided by
                  the error handler.</p>
            </item>
            <item>
               <p>Implementations may provide user options that relax the requirement for the
                  function to return deterministic results.</p>
            </item>
            <item>
               <p diff="add" at="E">The effect of a fragment identifier in the supplied URI 
                  is <termref def="implementation-defined">implementation-defined</termref>. One possible interpretation
               is to treat the fragment identifier as an ID attribute value, and to return a document
               node having the element with the selected ID value as its only child.</p>
            </item>
         </ulist>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error <rfc2119>may</rfc2119> be raised <errorref class="DC" code="0005"/> if
               <code>$uri</code> is not a valid URI <phrase diff="add" at="D">reference</phrase>.</p>
         <p diff="add" at="B">A dynamic error is raised <errorref class="DC" code="0002"/> if a relative URI reference
         is supplied, and the base-URI property in the static context is absent.</p>
         <p>A dynamic error is raised <errorref class="DC" code="0002"/> if the <term>available
               documents</term> provides no mapping for the absolutized URI.</p>
         <p>A dynamic error is raised <errorref class="DC" code="0002"/> if the resource cannot be
            retrieved or cannot be parsed successfully as XML.</p>
         <p>A dynamic error is raised <errorref class="DC" code="0003"/> if the implementation is
            not able to guarantee that the result of the function will be deterministic, and the
            user has not indicated that an unstable result is acceptable.</p>
      </fos:errors>
   </fos:function>
   <fos:function name="doc-available" prefix="fn">
      <fos:signatures>
         <fos:proto name="doc-available" return-type="xs:boolean">
            <fos:arg name="uri" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="available-documents static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>The function returns true if and only if the function call <code>fn:doc($uri)</code>
            would return a document node.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$uri</code> is an empty sequence, this function returns <code>false</code>.</p>
         <p>If a call on <code>fn:doc($uri)</code> would return a document node, this function
            returns <code>true</code>.</p>
         <p diff="del" at="E">A dynamic error is raised <errorref class="DC" code="0005"/> if <code>$uri</code> is not
            a valid URI according to the rules applied by the implementation of
            <code>fn:doc</code>.</p>
         <p>In all other cases this function returns <code>false</code>. <phrase diff="add" at="B">This
         includes the case where <phrase diff="add" at="E">an invalid URI is supplied, and also the case where </phrase>
            a valid relative URI reference is supplied, and cannot be resolved,
         for example because the static base URI is absent.</phrase></p>
         <p>If this function returns <code>true</code>, then calling <code>fn:doc($uri)</code>
            within the same <termref def="execution-scope"/> must return a document node. However,
            if nondeterministic processing has been selected for the <code>fn:doc</code> function,
            this guarantee is lost.</p>
      </fos:rules>
   </fos:function>
   <fos:function name="collection" prefix="fn">
      <fos:signatures>
         <fos:proto name="collection" return-type="item()*"/>
         <fos:proto name="collection" return-type="item()*">
            <fos:arg name="arg" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="available-collections static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a sequence of items identified by a
            collection URI; or a default collection if no URI is supplied.</p>
      </fos:summary>
      <fos:rules>
         <p>This function takes an <code>xs:string</code> as argument and returns a sequence of
            <phrase diff="chg" at="D">items</phrase> obtained by interpreting <code>$arg</code> as an <code>xs:anyURI</code> and
            resolving it according to the mapping specified in <term>available 
               collections</term> described in <xspecref spec="XP31"
               ref="id-xp-evaluation-context-components"/>.</p>
         <p>If <phrase diff="chg" at="D"><term>available collections</term></phrase> provides a mapping from this string to a
            sequence of items, the function returns that sequence. If <term>available 
               collections</term> maps the string to an empty sequence, then the function returns an
            empty sequence.</p>
         <p>If <code>$arg</code> is not specified, the function returns the sequence of <phrase diff="chg" at="D">items</phrase> in
            the default collection in the dynamic context. See <xspecref spec="XP31"
               ref="id-xp-evaluation-context-components"/>. </p>
         <p>If the value of <code>$arg</code> is a relative <code>xs:anyURI</code>, it is resolved
            against the value of the base-URI property from the static context. </p>
         <p>If <code>$arg</code> is the empty sequence, the function behaves as if it had been
            called without an argument. See above.</p>
         <p>By default, this function is <termref def="deterministic">deterministic</termref>. This
            means that repeated calls on the function with the same argument will return the same
            result. However, for performance reasons, implementations may provide a user option to
            evaluate the function without a guarantee of determinism. The manner in which any such
            option is provided is <termref def="implementation-defined">implementation-defined</termref>. If the user has not
            selected such an option, a call to this function must either return a deterministic
            result or must raise a dynamic error <errorref class="DC" code="0003"/>.</p>
         <p>There is no requirement that <phrase diff="chg" at="D">any nodes in the result</phrase> should be in document order, nor is
            there a requirement that the result should contain no duplicates.</p>


      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="DC" code="0002"/> if no URI is supplied and
            the value of the default collection is <xtermref ref="dt-absent" spec="DM31"
               >absent</xtermref>.</p>
         <p diff="add" at="B">A dynamic error is raised <errorref class="DC" code="0002"/> if a relative URI reference
            is supplied, and the base-URI property in the static context is absent.</p>
         <p>A dynamic error is raised <errorref class="DC" code="0002"/> if <term>available node
               collections</term> provides no mapping for the absolutized URI.</p>
         <p>A dynamic error <phrase diff="chg" at="E"><rfc2119>may</rfc2119> be</phrase> raised <errorref class="DC" code="0004"/> if <code>$arg</code> is not
            a valid <code>xs:anyURI</code>.</p>
      </fos:errors>
      <fos:notes>
         <p diff="chg" at="D">In earlier releases, the primary use for the <code>fn:collection</code> function
         was to retrieve a collection of XML documents, perhaps held as lexical XML in operating
         system filestore, or perhaps held in an XML database. In this release the concept has
         been generalised to allow other resources to be retrieved: for example JSON documents might
         be returned as arrays or maps, non-XML text files might be returned as strings, and binary
         files might be returned as instances of <code>xs:base64Binary</code>.</p>
         <p diff="chg" at="D">The abstract concept of a collection might be realized in different ways by different
            implementations, and the ways in which URIs map to collections can be equally variable. 
            Specifying resources using URIs is
            useful because URIs are dynamic, can be parameterized, and do not rely on an external
            environment.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="uri-collection" prefix="fn">
      <fos:signatures>
         <fos:proto name="uri-collection" return-type="xs:anyURI*"/>
         <fos:proto name="uri-collection" return-type="xs:anyURI*">
            <fos:arg name="arg" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="available-uri-collections static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a sequence of <code>xs:anyURI</code> values representing the URIs in a URI
            collection.</p>
      </fos:summary>
      <fos:rules>
         <p>The zero-argument form of the function returns the URIs in the <term>default URI
               collection</term> described in <xspecref spec="XP31"
               ref="id-xp-evaluation-context-components"/>.</p>
         <p>If the value of <code>$arg</code> is a relative <code>xs:anyURI</code>, it is resolved
            against the value of the base-URI property from the static context. </p>
         <p>If <code>$arg</code> is the empty sequence, the function behaves as if it had been
            called without an argument. See above.</p>
         <p>The single-argument form of the function returns the sequence of URIs corresponding to
            the supplied URI in the <term>available URI collections</term> described in
               <xspecref spec="XP31" ref="id-xp-evaluation-context-components"/>.</p>
         <p diff="add" at="D">By default, this function is <termref def="deterministic">deterministic</termref>. This
            means that repeated calls on the function with the same argument will return the same
            result. However, for performance reasons, implementations may provide a user option to
            evaluate the function without a guarantee of determinism. The manner in which any such
            option is provided is <termref def="implementation-defined">implementation-defined</termref>. If the user has not
            selected such an option, a call to this function must either return a deterministic
            result or must raise a dynamic error <errorref class="DC" code="0003"/>.</p>
         <p>There is no requirement that the URIs returned by this function should all be distinct,
            and no assumptions can be made about the order of URIs in the sequence, unless the
            implementation defines otherwise.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="DC" code="0002"/> if no URI is supplied (that
            is, if the function is called with no arguments, or with a single argument that
            evaluates to an empty sequence), and the value of the default resource collection is
               <xtermref ref="dt-absent" spec="DM31">absent</xtermref>.</p>
         <p diff="add" at="B">A dynamic error is raised <errorref class="DC" code="0002"/> if a relative URI reference
            is supplied, and the base-URI property in the static context is absent.</p>
         <p>A dynamic error is raised <errorref class="DC" code="0002"/> if <term>available resource
               collections</term> provides no mapping for the absolutized URI.</p>
         <p>A dynamic error <phrase diff="chg" at="E"><rfc2119>may</rfc2119> be</phrase> raised <errorref class="DC" code="0004"/> if <code>$arg</code> is not
            a valid <code>xs:anyURI</code>.</p>
      </fos:errors>
      <fos:notes>
         <p diff="chg" at="D">In some implementations, there might be a close relationship between <term>collections</term> (as retrieved
         by the <code>fn:collection</code> function), and <term>URI collections</term> (as retrieved by this function).
         For example, a collection might return XML documents, and the corresponding URI collection might return
         the URIs of those documents. However, this specification does not impose such a close relationship. For example, there
         may be collection URIs accepted by one of the two functions and not by the other; a collection might contain
         items that do not have any URI; or a URI collection might contain URIs that cannot be dereferenced to return any 
         resource.</p>
         
         <p>Thus, some implementations might ensure that calling <code>fn:uri-collection</code> and then
            applying <code>fn:doc</code> to each of the returned URIs delivers the same result as
            calling <code>fn:collection</code> with the same argument; however, this is not
            guaranteed.</p>
         
         <p>In the case where <code>fn:uri-collection</code> returns the URIs of resources that
            could also be retrieved directly using <code>fn:collection</code>, there are several reasons why it 
            might be appropriate to use this function in preference
            to the <code>fn:collection</code> function. For example:</p>

         <ulist>
            <item>
               <p>It allows different URIs for different kinds of resource to be dereferenced in
                  different ways: for
                  example, the returned URIs might be referenced using the
                     <code>fn:unparsed-text</code> function rather than the <code>fn:doc</code>
                  function.</p>
            </item>
            <item>
               <p>In XSLT 3.0 it allows the documents in a collection to be processed in streaming mode using the
                     <code>xsl:stream</code> instruction.</p>
            </item>
            <item>
               <p>It allows recovery from failures to read, parse, or validate individual documents,
                  by calling the <code>fn:doc</code> (or other dereferencing) function within the scope of try/catch.</p>
            </item>
            <item>
               <p>It allows selection of which documents to read based on their URI, for example
                  they can be filtered to select those whose URIs end in <code>.xml</code>, or those
                  that use the <code>https</code> scheme.</p>
            </item>
            <item>
               <p>An application might choose to limit the number of URIs processed in a single run,
                  for example it might process only the first 50 URIs in the collection; or it might
                  present the URIs to the user and allow the user to select which of them need to be
                  further processed.</p>
            </item>
            <item>
               <p>It allows the URIs to be modified before they are dereferenced, for example by
                  adding or removing query parameters, or by redirecting the request to a local
                  cache or to a mirror site.</p>
            </item>
         </ulist>

         <p>For some of these use cases, this assumes that the cost of calling
               <code>fn:collection</code> might be significant (for example, it might involving
            retrieving all the documents in the collection over the network and parsing them). This
            will not necessarily be true of all implementations.</p>

         

         


      </fos:notes>
   </fos:function>
   <fos:function name="unparsed-text" prefix="fn">
      <fos:signatures>
         <fos:proto name="unparsed-text" return-type="xs:string?">
            <fos:arg name="href" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="unparsed-text" return-type="xs:string?">
            <fos:arg name="href" type="xs:string?"/>
            <fos:arg name="encoding" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>The <code>fn:unparsed-text</code> function reads an external resource (for example, a
            file) and returns a string representation of the resource.</p>
      </fos:summary>
      <fos:rules>
         <p>The <code>$href</code> argument <rfc2119>must</rfc2119> be a string in the form of a URI
            reference, which <rfc2119>must</rfc2119> contain no fragment identifier, and
               <rfc2119>must</rfc2119> identify a resource for which a string representation is
            available. If the URI is a relative URI reference, then it is resolved relative to the
            <term>static base URI</term> property from the static context.</p>
         <p>The mapping of URIs to the string representation of a resource is the mapping defined in
            the <xtermref spec="XP31" ref="dt-available-text-resources">available text
               resources</xtermref> component of the dynamic context.</p>
         <p>If the value of the <code>$href</code> argument is an empty sequence, the function
            returns an empty sequence.</p>
         <p>The <code>$encoding</code> argument, if present, is the name of an encoding. The values
            for this attribute follow the same rules as for the <code>encoding</code> attribute in
            an XML declaration. The only values which every <termref def="implementation"
               >implementation</termref> is <rfc2119>required</rfc2119> to recognize are
               <code>utf-8</code> and <code>utf-16</code>.</p>
         <p>The encoding of the external resource is determined as follows:</p>
         <olist>
            <item>
               <p>external encoding information is used if available, otherwise</p>
            </item>
            <item>
               <p>if the media type of the resource is <code>text/xml</code> or
                     <code>application/xml</code> (see <bibref ref="rfc2376"/>), or if it matches
                  the conventions <code>text/*+xml</code> or <code>application/*+xml</code> (see
                     <bibref ref="rfc7303"/> and/or its successors), then the encoding is recognized
                  as specified in <bibref ref="xml"/>, otherwise</p>
            </item>
            <item>
               <p>the value of the <code>$encoding</code> argument is used if present, otherwise</p>
            </item>
            <item>
               <p>the processor <rfc2119>may</rfc2119> use <termref def="implementation-defined"
                     >implementation-defined</termref> heuristics to determine the likely encoding,
                  otherwise</p>
            </item>
            <item>
               <p>UTF-8 is assumed.</p>
            </item>
         </olist>
         <p>The result of the function is a string containing the string representation of the
            resource retrieved using the URI.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="UT" code="1170"/> if <code>$href</code>
            contains a fragment identifier, <phrase diff="add" at="B">or if it cannot be resolved
            to an absolute URI (for example, because the base-URI property in the static context is absent), 
            </phrase>or if it cannot be used to retrieve the string
            representation of a resource. </p>
         <p>A dynamic error is raised <errorref class="UT" code="1190"/> if the value of the
               <code>$encoding</code> argument is not a valid encoding name, if the <termref
               def="dt-processor">processor</termref> does not support the specified encoding, if
            the string representation of the retrieved resource contains octets that cannot be
            decoded into Unicode <termref def="character">characters</termref> using the specified
            encoding, or if the resulting characters are not permitted XML characters.</p>
         <p>A dynamic error is raised <errorref class="UT" code="1200"/> if <code>$encoding</code>
            is absent and the <termref def="dt-processor">processor</termref> cannot infer the
            encoding using external information and the encoding is not UTF-8.</p>
      </fos:errors>

      <fos:notes>
         <p>If it is appropriate to use a base URI other than the dynamic base URI (for example,
            when resolving a relative URI reference read from a source document) then it is
            advisable to resolve the relative URI reference using the <code>fn:resolve-uri</code>
            function before passing it to the <code>fn:unparsed-text</code> function.</p>
         <p>There is no essential relationship between the sets of URIs accepted by the two
            functions <code>fn:unparsed-text</code> and <code>fn:doc</code> (a URI accepted by one
            may or may not be accepted by the other), and if a URI is accepted by both there is no
            essential relationship between the results (different resource representations are
            permitted by the architecture of the web).</p>
         <p>There are no constraints on the MIME type of the resource.</p>


         <p>The fact that the resolution of URIs is defined by a mapping in the dynamic context
            means that in effect, various aspects of the behavior of this function are <termref
               def="implementation-defined">implementation-defined</termref>. Implementations may provide external configuration
            options that allow any aspect of the processing to be controlled by the user. In
            particular:</p>
         <ulist>
            <item>
               <p>The set of URI schemes that the implementation recognizes is
                  implementation-defined. Implementations may allow the mapping of URIs to resources
                  to be configured by the user, using mechanisms such as catalogs or user-written
                  URI handlers.</p>
            </item>
            <item>
               <p>The handling of media types is implementation-defined.</p>
            </item>

            <item>
               <p>Implementations may provide user-defined error handling options that allow
                  processing to continue following an error in retrieving a resource, or in reading
                  its content. When errors have been handled in this way, the function may return a
                  fallback document provided by the error handler.</p>
            </item>
            <item>
               <p>Implementations may provide user options that relax the requirement for the
                  function to return deterministic results.</p>
            </item>
         </ulist>

         <p>The rules for determining the encoding are chosen for consistency with <bibref
               ref="xinclude"/>. Files with an XML media type are treated specially because there
            are use cases for this function where the retrieved text is to be included as unparsed
            XML within a CDATA section of a containing document, and because processors are likely
            to be able to reuse the code that performs encoding detection for XML external
            entities.</p>
         <p>If the text file contains characters such as <code>&lt;</code> and <code>&amp;</code>,
            these will typically be output as <code>&amp;lt;</code> and <code>&amp;amp;</code> if
            the string is serialized as XML or HTML. If these characters actually represent markup
            (for example, if the text file contains HTML), then an XSLT stylesheet can attempt to
            write them as markup to the output file using the <code>disable-output-escaping</code>
            attribute of the <code>xsl:value-of</code> instruction. Note, however, that XSLT
            implementations are not required to support this feature.</p>
      </fos:notes>



      <!--
      <imp-def-feature>The set of encodings recognized by the
         <function>unparsed-text</function> function, other than <code>utf-8</code> and
         <code>utf-16</code>, is <termref def="implementation-defined"
            >implementation-defined</termref>.</imp-def-feature>
      
      <imp-def-feature>If no encoding is specified on a call to the
         <function>unparsed-text</function> function, the processor
         <rfc2119>may</rfc2119> use <termref def="implementation-defined"
            >implementation-defined</termref> heuristics to determine the likely
         encoding.</imp-def-feature>-->

      <fos:examples>
         <fos:example>
            <p>This XSLT example attempts to read a file containing 'boilerplate' HTML and copy it
               directly to the serialized output file:</p>
            <eg xml:space="preserve"><![CDATA[<xsl:output method="html"/>

<xsl:template match="/">
  <xsl:value-of select="unparsed-text('header.html', 'iso-8859-1')"
                disable-output-escaping="yes"/>
  <xsl:apply-templates/>
  <xsl:value-of select="unparsed-text('footer.html', 'iso-8859-1')"
                disable-output-escaping="yes"/>
</xsl:template>
]]></eg>
         </fos:example>
      </fos:examples>

   </fos:function>
   <fos:function name="unparsed-text-lines" prefix="fn">
      <fos:signatures>
         <fos:proto name="unparsed-text-lines" return-type="xs:string*">
            <fos:arg name="href" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="unparsed-text-lines" return-type="xs:string*">
            <fos:arg name="href" type="xs:string?"/>
            <fos:arg name="encoding" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>The <code>fn:unparsed-text-lines</code> function reads an external resource (for
            example, a file) and returns its contents as a sequence of strings, one for each line of
            text in the string representation of the resource.</p>
      </fos:summary>
      <fos:rules>
         <p>The <code>unparsed-text-lines</code> function reads an external resource (for example, a
            file) and returns its string representation as a sequence of strings, separated at
            newline boundaries. </p>
         <p>The result of the single-argument function is the same as the result of the expression
               <code>fn:tokenize(fn:unparsed-text($href), '\r\n|\r|\n')[not(position()=last() and
               .='')]</code>. The result of the two-argument function is the same as the result of
            the expression <code>fn:tokenize(fn:unparsed-text($href, $encoding),
               '\r\n|\r|\n')[not(position()=last() and .='')]</code>. </p>
         <p>The result is thus a sequence of strings containing the text of the resource retrieved
            using the URI, each string representing one line of text. Lines are separated by one of
            the sequences x0A, x0D, or x0Dx0A. The characters representing the newline are not
            included in the returned strings. If there are two adjacent newline sequences, a
            zero-length string will be returned to represent the empty line; but if the external
            resource ends with the sequence x0A, x0D, or x0Dx0A, the result will be as if this final
            line ending were not present.</p>
      </fos:rules>
      <fos:errors>
         <p>Error conditions are the same as for the <code>fn:unparsed-text</code> function.</p>

      </fos:errors>

      <fos:notes>
         <p>See the notes for <code>fn:unparsed-text</code>.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="unparsed-text-available" prefix="fn">
      <fos:signatures>
         <fos:proto name="unparsed-text-available" return-type="xs:boolean">
            <fos:arg name="href" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="unparsed-text-available" return-type="xs:boolean">
            <fos:arg name="href" type="xs:string?"/>
            <fos:arg name="encoding" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Because errors in evaluating the <code>fn:unparsed-text</code> function are
            non-recoverable, these two functions are provided to allow an application to determine
            whether a call with particular arguments would succeed.</p>
      </fos:summary>
      <fos:rules>
         <p>The <code>fn:unparsed-text-available</code> function determines whether a call
            on the <code>fn:unparsed-text</code> function with identical arguments would
            return a string.</p>
         <p>If the first argument is an empty sequence, the function returns false. </p>
         <p>In other cases, the function returns true if a call on
               <code>fn:unparsed-text</code> with the same arguments would succeed, and
            false if a call on <code>fn:unparsed-text</code> with the same arguments would
            fail with a non-recoverable dynamic error.</p>
         <p>The functions <code>fn:unparsed-text</code> and
               <code>fn:unparsed-text-available</code> have the same requirement for
               <termref def="deterministic">determinism</termref> as the functions
               <code>fn:doc</code> and <code>fn:doc-available</code>. This means that unless the
            user has explicitly stated a requirement for a reduced level of determinism, either of
            these functions if called twice with the same arguments during the course of a
            transformation <rfc2119>must</rfc2119> return the same results each time; moreover, the
            results of a call on <code>fn:unparsed-text-available</code>
            <rfc2119>must</rfc2119> be consistent with the results of a subsequent call on
               <code>unparsed-text</code> with the same arguments.</p>
      </fos:rules>
      <fos:notes>
         <p>This requires that the <code>fn:unparsed-text-available</code> function should
            actually attempt to read the resource identified by the URI, and check that it is
            correctly encoded and contains no characters that are invalid in XML. Implementations
            may avoid the cost of repeating these checks for example by caching the validated
            contents of the resource, to anticipate a subsequent call on the
               <code>fn:unparsed-text</code> or <code>fn:unparsed-text-lines</code>
            function. Alternatively, implementations may be able to rewrite an expression such as
               <code>if (unparsed-text-available(A)) then unparsed-text(A) else ...</code> to
            generate a single call internally.</p>
         <p>Since the function <code>fn:unparsed-text-lines</code> succeeds or fails under
            exactly the same circumstances as <code>fn:unparsed-text</code>, the
               <code>fn:unparsed-text-available</code> function may equally be used to test
            whether a call on <code>fn:unparsed-text-lines</code> would succeed.</p>

      </fos:notes>

   </fos:function>
   <fos:function name="environment-variable" prefix="fn">
      <fos:signatures>
         <fos:proto name="environment-variable" return-type="xs:string?">
            <fos:arg name="name" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="environment-variables">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the value of a system environment variable, if it exists.</p>
      </fos:summary>
      <fos:rules>
         <p>The set of available <xtermref spec="XP31" ref="dt-environment-variables">environment
               variables</xtermref> is a set of (name, value) pairs forming part of the dynamic
            context, in which the name is unique within the set of pairs. The name and value are
            arbitrary strings.</p>
         <p>If the <code>$name</code> argument matches the name of one of these pairs, the function
            returns the corresponding value.</p>
         <p>If there is no environment variable with a matching name, the function returns the empty
            sequence.</p>
         <p>The collation used for matching names is <termref def="implementation-defined">implementation-defined</termref>, but
            must be the same as the collation used to ensure that the names of all environment
            variables are unique.</p>
         <p>The function is <termref def="dt-deterministic">deterministic</termref>, which means
            that if it is called several times within the same <termref def="execution-scope"
               >execution scope</termref>, with the same arguments, it must return the same
            result.</p>
      </fos:rules>
      <fos:notes>
         <p>On many platforms, the term "environment variable" has a natural meaning in terms of
            facilities provided by the operating system. This interpretation of the concept does not
            exclude other interpretations, such as a mapping to a set of configuration parameters in
            a database system.</p>
         <p>Environment variable names are usually case sensitive. Names are usually of the form
               <code>(letter|_) (letter|_|digit)*</code>, but this varies by platform.</p>
         <p>On some platforms, there may sometimes be multiple environment variables with the same
            name; in this case, it is implementation-dependent as to which is returned; see for
            example <bibref ref="POSIX.1-2008"/> (Chapter 8, Environment Variables). Implementations
               <rfc2119>may</rfc2119> use prefixes or other naming conventions to disambiguate the
            names.</p>
         <p>The requirement to ensure that the function is deterministic means in practice that the
            implementation must make a snapshot of the environment variables at some time during
            execution, and return values obtained from this snapshot, rather than using live values
            that are subject to change at any time.</p>
         <p>Operating system environment variables may be associated with a particular process,
            while queries and stylesheets may execute across multiple processes (or multiple
            machines). In such circumstances implementations <rfc2119>may</rfc2119> choose to
            provide access to the environment variables associated with the process in which the
            query or stylesheet processing was initiated.</p>
         <p>Security advice: Queries from untrusted sources should not be permitted unrestricted
            access to environment variables. For example, the name of the account under which the
            query is running may be useful information to a would-be intruder. An implementation may
            therefore choose to restrict access to the environment, or may provide a facility to
            make <code>fn:environment-variable</code> always return the empty sequence.</p>

      </fos:notes>
   </fos:function>
   <fos:function name="available-environment-variables" prefix="fn">
      <fos:signatures>
         <fos:proto name="available-environment-variables" return-type="xs:string*"/>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="environment-variables">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a list of environment variable names that are suitable for passing to
               <code>fn:environment-variable</code>, as a (possibly empty) sequence of strings.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns a sequence of strings, being the names of the environment variables
            in the dynamic context in some <termref def="implementation-dependent"
               >implementation-dependent</termref> order.</p>
         <p>The function is <termref def="dt-deterministic">deterministic</termref>: that is, the
            set of available environment variables does not vary during evaluation.</p>
      </fos:rules>
      <fos:notes>
         <p>The function returns a list of strings, containing no duplicates.</p>
         <p>It is intended that the strings in this list should be suitable for passing to
               <code>fn:environment-variable</code>.</p>

         <p>See also the note on security under the definition of the
               <code>fn:environment-variable</code> function. If access to environment variables has
            been disabled, <code>fn:available-environment-variables</code> always returns the empty
            sequence.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="generate-id" prefix="fn">
      <fos:signatures>
         <fos:proto name="generate-id" return-type="xs:string"/>
         <fos:proto name="generate-id" return-type="xs:string">
            <fos:arg name="arg" type="node()?" usage="inspection" default="."/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="0">
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
      </fos:properties>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>This function returns a string that uniquely identifies a given node. </p>
      </fos:summary>
      <fos:rules>
         <p>If the argument is omitted, it defaults to the context item (<code>.</code>). The
            behavior of the function if the argument is omitted is exactly the same as if the
            context item had been passed as the argument.</p>
         <p>If the argument is the empty sequence, the result is the zero-length string.</p>
         <p>In other cases, the function returns a string that uniquely identifies a given node.
            <phrase diff="add" at="E">More formally, it is guaranteed that within a single
             <termref def="execution-scope">execution scope</termref>, 
               <code>fn:codepoint-equal(fn:generate-id($N), fn:generate-id($M))</code> returns true 
               if and only if <code>($M is $N)</code> returns true.</phrase></p>

         <p>The returned identifier <rfc2119>must</rfc2119> consist of ASCII alphanumeric characters
            and <rfc2119>must</rfc2119> start with an alphabetic character. Thus, the string is
            syntactically an XML name.</p>
         
      </fos:rules>
      <fos:errors>
         <p>The following errors may be raised when <code>$arg</code> is omitted:</p>
         <ul>
            <li>
               <p>If the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>,
                  dynamic error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p>
            </li>
            <li>
               <p>If the context item is not a node, type error <xerrorref spec="XP" class="TY"
                     code="0004" type="type"/>.</p>
            </li>
         </ul>

      </fos:errors>
      <fos:notes>
         <p>An implementation is free to generate an identifier in any convenient way provided that
            it always generates the same identifier for the same node and that different identifiers
            are always generated from different nodes. An implementation is under no obligation to
            generate the same identifiers each time a document is transformed or queried.</p>
         <p>There is no guarantee that a generated unique identifier will be distinct from any
            unique IDs specified in the source document.</p>
         <p>There is no inverse to this function; it is not directly possible to find the node with
            a given generated ID. Of course, it is possible to search a given sequence of nodes
            using an expression such as <code>$nodes[generate-id()=$id]</code>.</p>
         <p>It is advisable, but not required, for implementations to generate IDs that are distinct
            even when compared using a case-blind collation.</p>
         
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p>The primary use case for this function is to generate hyperlinks. For example, when
               generating HTML, an anchor for a given section <code>$sect</code> can be generated by
               writing (in either XSLT or XQuery):</p>
            <p>
               <code><![CDATA[<a name="{fn:generate-id($sect)}"/>]]></code>
            </p>
            <p>and a link to that section can then be produced with code such as:</p>
            <p>
               <code><![CDATA[see <a href="#{fn:generate-id($sect)}">here</a>]]></code>
            </p>
            <p>Note that anchors generated in this way will not necessarily be the same each time a
               document is republished.</p>
            
         </fos:example>
         <fos:example>
            <p>Since the keys in a map must be atomic values, it is possible to use generated IDs
               as surrogates for nodes when constructing a map. For example, in some implementations,
               testing whether a node <code>$N</code> is a member of a large node-set <code>$S</code>
               using the expression <code>fn:exists($N intersect $S)</code> may be expensive; there
               may then be performance benefits in creating a map:</p>
            <p>
               <code>let $SMap := map:merge($S!map{fn:generate-id(.) : .})</code>
            </p>
            <p>and then testing for membership of the node-set using:</p>
            <p>
               <code>map:contains($SMap, fn:generate-id($N))</code>
            </p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="parse-xml" prefix="fn">
      <fos:signatures>
         <fos:proto name="parse-xml" return-type="document-node(element(*))?">
            <fos:arg name="arg" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>nondeterministic</fos:property>
         <fos:property dependency="static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>This function takes as input an XML document represented as a string, and returns the
            document node at the root of an XDM tree representing the parsed document.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>The precise process used to construct the XDM instance is <termref
            def="implementation-defined">implementation-defined</termref>. In particular, it is implementation-defined whether
            DTD and/or schema validation is invoked, and it is implementation-defined whether an XML
            1.0 or XML 1.1 parser is used.</p>
         <p>The <term>static base URI</term> property from the static context of the <code>fn:parse-xml</code>
            function call is used both as the base URI used by the XML parser to resolve relative
            entity references within the document, and as the base URI of the document node that is
            returned.</p>
         <p>The document URI of the returned node is <termref def="absent">absent</termref>.</p>
         <p>The function is <emph>not</emph>
            <termref def="deterministic">deterministic</termref>: that is, if the function is called
            twice with the same arguments, it is <termref def="implementation-dependent"
               >implementation-dependent</termref> whether the same node is returned on both
            occasions.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="DC" code="0006"/> if the content of
               <code>$arg</code> is not a well-formed and namespace-well-formed XML document.</p>
         <p>A dynamic error is raised <errorref class="DC" code="0006"/> if DTD-based validation is
            carried out and the content of <code>$arg</code> is not valid against its DTD.</p>
      </fos:errors>
      <fos:notes>
         <p>Since the XML document is presented to the parser as a string, rather than as a sequence
            of octets, the encoding specified within the XML declaration has no meaning. If the XML
            parser accepts input only in the form of a sequence of octets, then the processor must
            ensure that the string is encoded as octets in a way that is consistent with rules used
            by the XML parser to detect the encoding.</p>
         <p>The primary use case for this function is to handle input documents that contain nested
            XML documents embedded within CDATA sections. Since the content of the CDATA section are
            exposed as text, the receiving query or stylesheet may pass this text to the
               <code>fn:parse-xml</code> function to create a tree representation of the nested
            document.</p>
         <p>Similarly, nested XML within comments is sometimes encountered, and lexical XML is
            sometimes returned by extension functions, for example, functions that access web
            services or read from databases.</p>
         <p>A use case arises in XSLT where there is a need to preprocess an input document before
            parsing. For example, an application might wish to edit the document to remove its
            DOCTYPE declaration. This can be done by reading the raw text using the
               <code>fn:unparsed-text</code> function, editing the resulting string, and then
            passing it to the <code>fn:parse-xml</code> function.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p>The expression <code>fn:parse-xml("&lt;alpha>abcd&lt;/alpha>")</code> returns a newly
               created document node, having an <code>alpha</code> element as its only child; the
                  <code>alpha</code> element in turn is the parent of a text node whose string value
               is <code>"abcd"</code>.</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="parse-xml-fragment" prefix="fn">
      <fos:signatures>
         <fos:proto name="parse-xml-fragment" return-type="document-node()?">
            <fos:arg name="arg" type="xs:string?"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>nondeterministic</fos:property>
         <fos:property dependency="static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>This function takes as input an XML external entity represented as a string, and returns
            the document node at the root of an XDM tree representing the parsed document
            fragment.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p>
         <p>The input must be a namespace-well-formed external general parsed entity. More
            specifically, it must be a string conforming to the production rule <xnt spec="xml"
               ref="NT-extParsedEnt">extParsedEnt</xnt> in <bibref ref="xml"/>, it must contain
            no entity references other than references to predefined entities, and it must satisfy
            all the rules of <bibref ref="xml-names"/> for namespace-well-formed documents with
            the exception that the rule requiring it to be a well-formed document is replaced by the
            rule requiring it to be a well-formed external general parsed entity.</p>
         <p>The string is parsed to form a sequence of nodes which become children of the new
            document node, in the same way as the content of any element is converted into a
            sequence of children for the resulting element node.</p>
         <p>Schema validation is <emph>not</emph> invoked, which means that the nodes in the
            returned document will all be untyped.</p>
         <p>The precise process used to construct the XDM instance is <termref
            def="implementation-defined">implementation-defined</termref>. In particular, it is implementation-defined whether
            an XML 1.0 or XML 1.1 parser is used.</p>
         <p>The <term>static base URI</term> from the static context of the <code>fn:parse-xml-fragment</code>
            function call is used as the base URI of the document node that is returned.</p>
         <p>The document URI of the returned node is <termref def="absent">absent</termref>.</p>
         <p>The function is <emph>not</emph>
            <termref def="deterministic">deterministic</termref>: that is, if the function is called
            twice with the same arguments, it is <termref def="implementation-dependent"
               >implementation-dependent</termref> whether the same node is returned on both
            occasions.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="DC" code="0006"/> if the content of
               <code>$arg</code> is not a well-formed external general parsed entity, if it contains
            entity references other than references to predefined entities, or if a document that
            incorporates this well-formed parsed entity would not be namespace-well-formed.</p>
      </fos:errors>
      <fos:notes>
         <p>See also the notes for the <code>fn:parse-xml</code> function.</p>
         <p>The main differences between <code>fn:parse-xml</code> and
               <code>fn:parse-xml-fragment</code> are that for <code>fn:parse-xml</code>, the
            children of the resulting document node must contain exactly one element node and no
            text nodes, wheras for <code>fn:parse-xml-fragment</code>, the resulting document node
            can have any number (including zero) of element and text nodes among its children. An
            additional difference is that the <emph>text declaration</emph> at the start of an
            external entity has slightly different syntax from the <emph>XML declaration</emph> at
            the start of a well-formed document.</p>
         <p>Note that all whitespace outside the <emph>text declaration</emph> is significant,
            including whitespace that precedes the first element node.</p>
         <p>One use case for this function is to handle XML fragments stored in databases, which
            frequently allow zero-or-more top level element nodes. Another use case is to parse the
            contents of a <code>CDATA</code> section embedded within another XML document.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p>The expression
                  <code>fn:parse-xml-fragment("&lt;alpha>abcd&lt;/alpha>&lt;beta>abcd&lt;/beta>")</code>
               returns a newly created document node, having two elements named <code>alpha</code>
               and <code>beta</code> as its children; each of these elements in turn is the parent
               of a text node.</p>
            <p>The expression <code>fn:parse-xml-fragment("He was &lt;i>so&lt;/i> kind")</code>
               returns a newly created document node having three children: a text node whose string
               value is <code>"He was "</code>, an element node named <code>i</code> having a child
               text node with string value <code>"so"</code>, and a text node whose string value is
                  <code>" kind"</code>.</p>
            <p>The expression <code>fn:parse-xml-fragment("")</code> returns a document node having
               no children.</p>
            <p>The expression <code>fn:parse-xml-fragment(" ")</code> returns a document node whose
               children comprise a single text node whose string value is a single space.</p>
            <p>The expression <code>fn:parse-xml-fragment('&lt;?xml version="1.0" encoding="utf8"
                  standalone="yes"?>&lt;a/>')</code> results in a dynamic error <errorref class="DC"
                  code="0006"/> because the "standalone" keyword is not permitted in the text
               declaration that appears at the start of an external general parsed entity. (Thus, it
               is not the case that any input accepted by the <code>fn:parse-xml</code> function
               will also be accepted by <code>fn:parse-xml-fragment</code>.)</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="serialize" prefix="fn">
      <fos:signatures>
         <fos:proto name="serialize" return-type="xs:string">
            <fos:arg name="arg" type="item()*" usage="absorption"/>
         </fos:proto>
         <fos:proto name="serialize" return-type="xs:string">
            <fos:arg name="arg" type="item()*" usage="absorption"/>
            <fos:arg name="params" type="item()?" usage="absorption"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>This function serializes the supplied input sequence <code>$arg</code> as described in
               <bibref ref="xslt-xquery-serialization-31"/>, returning the serialized representation
            of the sequence as a string.</p>
      </fos:summary>
      <fos:rules>
         <p>The value of the first argument <code>$arg</code> acts as the input sequence to the serialization process,
            which starts with sequence normalization.</p>
         
         <p>The second argument <code>$params</code>, if present, provides serialization parameters. These may be supplied in either 
         of two forms:</p>
         
         <olist>
            <item><p>As an <code>output:serialization-parameters</code>
               element, having the format described in <xspecref spec="SER31"
                  ref="serparams-in-xdm-instance"/>. In this case the type of the supplied
               argument must match the required type <code>element(output:serialization-parameters)</code>.</p></item>
            <item><p diff="add" at="D">As a map. In this case the type of the supplied argument must match the required type <code>map(*)</code></p></item>
         </olist>

         <p>The single-argument version of this function has the same effect as the two-argument
            version called with <code>$params</code> set to an empty sequence. This in turn is the
            same as the effect of passing an <code>output:serialization-parameters</code> element
            with no child elements.</p>
         
         <p>The final stage of serialization, that is, encoding, is skipped. If the serializer does
            not allow this phase to be skipped, then the sequence of octets returned by the
            serializer is decoded into a string by reversing the character encoding performed in the
            final stage.</p>
         
         <p>If the second argument is omitted, or is supplied in the form of an <code>output:serialization-parameters</code>
         element, then the values of any serialization parameters that are not explicitly specified is <termref def="implementation-defined">implementation-defined</termref>,
         and may depend on the context.</p>
         
         <p diff="add" at="D">If the second argument is supplied as a map, then the <termref def="option-parameter-conventions">option parameter conventions</termref>
         apply. In this case:</p>
         
         <olist diff="add" at="D">
            <item><p>Each entry in the map defines one serialization parameter.</p></item>
            <item><p>The key of the entry is an <code>xs:string</code> value in the cases of parameter names defined in these specifications, or an
            <code>xs:QName</code> (with non-absent namespace) in the case of implementation-defined serialization parameters.</p></item>
            <item><p>The required type of each parameter, and its default value, are defined by the following table. The default
            value is used when the map contains no entry for the parameter in question, and also when an entry is present, with the
            empty sequence as its value. The table also indicates how the value of the map entry is to be interpreted in cases
            where further explanation is needed.</p></item>
         </olist>
            <!--<item><p>The value part of the entry has a required type defined by the following rules, which are organized according to the type
               defined for the parameter in the schema for serialization parameters:</p>
               <olist>
                  <item><p>Where the type is <code>yes-no-type</code>, then an <code>xs:boolean</code> value
                  where true represents "yes" and false represents "no".</p></item>
                  <item><p>Where the type is <code>yes-no-omit-type</code>, then an optional <code>xs:boolean</code> value
                     where true represents "yes", false represents "no", and the empty sequence represents "omit".</p></item>
                  <item><p>For any other type derived from <code>xs:string</code>, an instance of <code>xs:string</code> that is
                  castable to the required type.</p></item>
                  <item><p>For the union type <code>method-type</code>, an instance of either <code>xs:string</code> or <code>xs:QName</code>
                  as appropriate.</p></item>
                  <item><p>For <code>decimal-param-type</code>, an instance of <code>xs:decimal</code>.</p></item>
                  <item><p>For <code>QNames-type</code>, either a sequence or an array of <code>xs:QName</code> values.</p></item>
                  <item><p>For the <code>use-character-maps</code> parameter, a map, whose keys are the characters to be mapped (as <code>xs:string</code> instances), and whose
                     corresponding values are the strings to be substituted for these characters. The <termref def="option-parameter-conventions">option parameter conventions</termref>
                  apply recursively to this nested map.</p></item>
               </olist>
               <note><p>If the supplied value is of the wrong type for the particular parameter, for example if the value of <code>indent</code>
                  is a string rather than a boolean, then as defined by the <termref def="option-parameter-conventions">option parameter conventions</termref>,
                  a type error <xerrorref spec="XP" class="TY" code="0004"/> is raised. 
                  If the value is of the correct type, but does not satisfy the rules for that
                  parameter defined in <bibref ref="xslt-xquery-serialization-31"/>, then a dynamic error 
                  <xerrorref spec="SER31" class="PM" code="0016"/> is raised.
               </p></note>
            </item>
            <item><p>If no entry is present in the map for a particular serialization parameter name, then that parameter takes a default value as defined in the
            following table:</p>-->
         <table class="no-code-break data">
            <thead>
                     <tr>
                        <th>Parameter</th>
                        <th>Required type</th>
                        <th>Interpretation</th>
                        <th>Default Value</th>
                     </tr>
                  </thead>
                  <tbody>
                     <tr>
                        <td><code>allow-duplicate-names</code></td>
                        <td><code>xs:boolean?</code></td>
                        <td><code>true()</code> means "yes", <code>false()</code> means "no"</td>
                        <td><code>no</code></td>
                     </tr>
                     <tr>
                        <td><code>byte-order-mark</code></td>
                        <td><code>xs:boolean?</code></td>
                        <td><code>true()</code> means "yes", <code>false()</code> means "no"</td>
                        <td><code>no</code></td>
                     </tr>
                     <tr>
                        <td><code>cdata-section-elements</code></td>
                        <td><code>xs:QName*</code></td>
                        <td></td>
                        <td><code>()</code></td>
                     </tr>
                     <tr>
                        <td><code>doctype-public</code></td>
                        <td><code>xs:string?</code></td>
                        <td>Zero-length string and <code>()</code> both represent "absent"</td>
                        <td>absent</td>
                     </tr>
                     <tr>
                        <td><code>doctype-system</code></td>
                        <td><code>xs:string?</code></td>
                        <td>Zero-length string and <code>()</code> both represent "absent"</td>
                        <td>absent</td>
                     </tr>
                     <tr>
                        <td><code>encoding</code></td>
                        <td><code>xs:string?</code></td>
                        <td></td>
                        <td><code>utf-8</code></td>
                     </tr>
                     <tr>
                        <td><code>escape-uri-attributes</code></td>
                        <td><code>xs:boolean?</code></td>
                        <td><code>true()</code> means "yes", <code>false()</code> means "no"</td>
                        <td><code>yes</code></td>
                     </tr>
                     <tr>
                        <td><code>html-version</code></td>
                        <td><code>xs:decimal?</code></td>
                        <td></td>
                        <td><code>5</code></td>
                     </tr>
                     <tr>
                        <td><code>include-content-type</code></td>
                        <td><code>xs:boolean?</code></td>
                        <td><code>true()</code> means "yes", <code>false()</code> means "no"</td>
                        <td><code>yes</code></td>
                     </tr>
                     <tr>
                        <td><code>indent</code></td>
                        <td><code>xs:boolean?</code></td>
                        <td><code>true()</code> means "yes", <code>false()</code> means "no"</td>
                        <td><code>no</code></td>
                     </tr>
                     <tr>
                        <td><code>item-separator</code></td>
                        <td><code>xs:string?</code></td>
                        <td></td>
                        <td>absent</td>
                     </tr>
                     <tr>
                        <td><code>json-node-output-method</code></td>
                        <td><code>union(xs:string, xs:QName)?</code></td>
                        <td>See Notes 1, 2</td>
                        <td><code>xml</code></td>
                     </tr>
                     <tr>
                        <td><code>media-type</code></td>
                        <td><code>xs:string?</code></td>
                        <td></td>
                        <td>(a media type suitable for the chosen <code>method</code>)</td>
                     </tr>
                     <tr>
                        <td><code>method</code></td>
                        <td><code>union(xs:string, xs:QName)?</code></td>
                        <td>See Notes 1, 2</td>
                        <td><code>xml</code></td>
                     </tr>
                     <tr>
                        <td><code>normalization-form</code></td>
                        <td><code>xs:string?</code></td>
                        <td></td>
                        <td><code>none</code></td>
                     </tr>
                     <tr>
                        <td><code>omit-xml-declaration</code></td>
                        <td><code>xs:boolean?</code></td>
                        <td><code>true()</code> means "yes", <code>false()</code> means "no"</td>
                        <td><code>yes</code></td>
                     </tr>
                     <tr>
                        <td><code>standalone</code></td>
                        <td><code>xs:boolean?</code></td>
                        <td><code>true()</code> means "yes", <code>false()</code> means "no", <code>()</code> means "omit"</td>
                        <td><code>omit</code></td>
                     </tr>
                     <tr>
                        <td><code>suppress-indentation</code></td>
                        <td><code>xs:QName*</code></td>
                        <td></td>
                        <td><code>()</code></td>
                     </tr>
                     <tr>
                        <td><code>undeclare-prefixes</code></td>
                        <td><code>xs:boolean?</code></td>
                        <td><code>true()</code> means "yes", <code>false()</code> means "no"</td>
                        <td><code>no</code></td>
                     </tr>
                     <tr>
                        <td><code>use-character-maps</code></td>
                        <td><code>map(xs:string, xs:string)?</code></td>
                        <td>See Note 3</td>
                        <td><code>map{}</code></td>
                     </tr>
                     <tr>
                        <td><code>version</code></td>
                        <td><code>xs:string?</code></td>
                        <td></td>
                        <td><code>1.0</code></td>
                     </tr>
                  </tbody>
            </table>
         
         <p>Notes to the table:</p>
         
         <olist>
            <item><p>The notation <code>union(A, B)</code> is used to represent a union type whose member types are <code>A</code>
            and <code>B</code>.</p></item>
            <item><p>If an <code>xs:QName</code> is supplied <phrase diff="add" at="E">for the <code>method</code> or <code>json-node-output-method</code> 
               options,</phrase> then it must have a non-absent namespace URI. This
            means that system-defined serialization methods such as <code>xml</code> and <code>json</code>
            are defined as strings, not as <code>xs:QName</code> values.</p></item>
            <item><p><phrase diff="add" at="E">For the <code>use-character-maps</code> option</phrase>, the value is a map, whose keys 
               are the characters to be mapped (as <code>xs:string</code> instances),
            and whose corresponding values are the strings to be substituted for these characters. 
            <phrase diff="del" at="E">The <termref def="option-parameter-conventions">option parameter conventions</termref>
               apply recursively to this nested map.</phrase></p></item>
         </olist>
         
      </fos:rules>
      <fos:errors>
         <p>A type error <xerrorref spec="XP" class="TY" code="0004"/> occurs if the second argument
            is present and does not match either of the types <code>element(output:serialization-parameters)?</code>
         or <code>map(*)</code>.</p>
         <note><p>This is defined as a type error so that it can be enforced via the function signature by implementations
         that generalize the type system in a suitable way.</p></note>
         <p>If the host language makes serialization an optional feature and the implementation does
            not support serialization, then a dynamic error <errorref class="DC" code="0010"/> is
            raised.</p>
         <p>The serialization process will raise an error if <code>$arg</code> is an attribute or
            namespace node.</p>
         <p>When the second argument is supplied as a map, 
            and the supplied value is of the wrong type for the particular parameter, for example if the value of <code>indent</code>
         is a string rather than a boolean, then as defined by the <termref def="option-parameter-conventions">option parameter conventions</termref>,
         a type error <xerrorref spec="XP" class="TY" code="0004"/> is raised. 
         If the value is of the correct type, but does not satisfy the rules for that
         parameter defined in <bibref ref="xslt-xquery-serialization-31"/>, then a dynamic error 
         <xerrorref spec="SER31" class="PM" code="0016"/> is raised. (For example, this occurs if the map supplied to
         <code>use-character-maps</code> includes a key that is a string whose length is not one (1)).</p>
         <p>If any serialization error occurs, including the detection of an invalid value for a
            serialization parameter as described above, this results in the <code>fn:serialize</code> call failing with
            a dynamic error.</p>
      </fos:errors>
      <fos:notes>
         <p>One use case for this function arises when there is a need to construct an XML document
            containing nested XML documents within a CDATA section (or on occasions within a
            comment). See <code>fn:parse-xml</code> for further details.</p>
         <p>Another use case arises when there is a need to call an extension function that expects
            a lexical XML document as input.</p>
         <p>There are also use cases where the application wants to post-process the output of a
            query or transformation, for example by adding an internal DTD subset, or by inserting
            proprietary markup delimiters such as the <code>&lt;% ... %&gt;</code> used by some
            templating languages.</p>
         <p diff="add" at="D">The ability to specify the serialization parameters in an <code>output:serialization-parameters</code>
         element provides backwards compatibility with the 3.0 version of this specification; the ability to
         use a map takes advantage of new features in the 3.1 version. The default parameter values are
         implementation-defined when an <code>output:serialization-parameters</code>
            element is used (or when the argument is omitted), but are fixed by this specification in the
         case where a map (including an empty map) is supplied for the argument.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p>Given the variables:</p>
         </fos:example>
         <fos:variable name="params" as="element()" id="v-serialize-params"><![CDATA[
<output:serialization-parameters 
        xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
  <output:omit-xml-declaration value="yes"/>
</output:serialization-parameters>]]>
         </fos:variable>
         <fos:variable name="data" as="element()" id="v-serialize-data"><![CDATA[
<a b="3"/>]]>
         </fos:variable>
         <fos:example>
            <p>The following call might produce the output shown:</p>
         </fos:example>
         <fos:example>
            <fos:test use="v-serialize-data v-serialize-params">
               <fos:expression><![CDATA[fn:serialize($data, $params)]]></fos:expression>
               <fos:result><![CDATA['<a b="3"/>']]></fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>The following call would also produce the output shown (though the second argument could equally well be supplied
               as an empty map (<code>map{}</code>), since both parameters are given their default values):</p>
         </fos:example>
         <fos:example>
            <fos:test use="v-serialize-data">
               <fos:expression><![CDATA[fn:serialize($data, map{"method":"xml", "omit-xml-declaration":true()})]]></fos:expression>
               <fos:result><![CDATA['<a b="3"/>']]></fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="position" prefix="fn">
      <fos:signatures>
         <fos:proto name="position" return-type="xs:integer"/>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
         <fos:property>special-streaming-rules</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the context position from the dynamic context.</p>
      </fos:summary>
      <fos:rules>
         <p>Returns the context position from the dynamic context. (See <xspecref spec="XP31"
               ref="id-xp-evaluation-context-components"/>.)</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <xerrorref spec="XP" class="DY" code="0002" type="type"/> if
            the context item is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>.</p>
      </fos:errors>
   </fos:function>
   <fos:function name="last" prefix="fn">
      <fos:signatures>
         <fos:proto name="last" return-type="xs:integer"/>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
         <fos:property>special-streaming-rules</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the context size from the dynamic context.</p>
      </fos:summary>
      <fos:rules>
         <p>Returns the context size from the dynamic context. (See <xspecref spec="XP31"
               ref="id-xp-evaluation-context-components"/>.)</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <xerrorref spec="XP" class="DY" code="0002" type="type"/> if
            the context <phrase diff="chg" at="D">size</phrase> is <xtermref ref="dt-absent" spec="DM31">absent</xtermref>.</p>
      </fos:errors>
      <fos:notes>
         <p diff="add" at="D">Under most circumstances, the context size is absent only if the context item is absent. However, XSLT 3.0 with
         streaming defines situations in which the context item and context position are known, but the context size is unknown.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>(1 to 20)[fn:last() - 1]</fos:expression>
               <fos:result>19</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="current-dateTime" prefix="fn">
      <fos:signatures>
         <fos:proto name="current-dateTime" return-type="xs:dateTimeStamp"/>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the current date and time (with timezone).</p>
      </fos:summary>
      <fos:rules>
         <p>Returns the current dateTime (with timezone) from the dynamic context. (See <xspecref
               spec="XP31" ref="id-xp-evaluation-context-components"/>.) This is an
               <code>xs:dateTime</code> that is current at some time during the evaluation of a
            query or transformation in which <code>fn:current-dateTime</code> is executed.</p>
         <p>This function is <termref def="dt-deterministic"/>. The precise instant during the query
            or transformation represented by the value of <code>fn:current-dateTime()</code> is
            <termref def="implementation-dependent">implementation-dependent</termref>.</p>
         <p>If the implementation supports data types from XSD 1.1 then the returned value will be
            an instance of <code>xs:dateTimeStamp</code>. Otherwise, the only guarantees are that it
            will be an instance of <code>xs:dateTime</code> and will have a timezone component.</p>
      </fos:rules>
      <fos:notes>
         <p>The returned <code>xs:dateTime</code> will always have an associated timezone, which
            will always be the same as the implicit timezone in the dynamic context</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p><code>fn:current-dateTime()</code> returns an <code>xs:dateTimeStamp</code>
               corresponding to the current date and time. For example, a call of
                  <code>fn:current-dateTime()</code> might return
                  <code>2004-05-12T18:17:15.125Z</code> corresponding to the current time on May 12,
               2004 in timezone <code>Z</code>. </p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="current-date" prefix="fn">
      <fos:signatures>
         <fos:proto name="current-date" return-type="xs:date"/>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the current date.</p>
      </fos:summary>
      <fos:rules>
         <p>Returns <code>xs:date(fn:current-dateTime())</code>. This is an <code>xs:date</code>
            (with timezone) that is current at some time during the evaluation of a query or
            transformation in which <code>fn:current-date</code> is executed.</p>
         <p>This function is <termref def="dt-deterministic"/>. The precise instant during the query
            or transformation represented by the value of <code>fn:current-date</code> is <termref
               def="implementation-dependent">implementation-dependent</termref>.</p>
      </fos:rules>
      <fos:notes>
         <p>The returned date will always have an associated timezone, which will always be the same
            as the implicit timezone in the dynamic context</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p><code>fn:current-date()</code> returns an <code>xs:date</code> corresponding to the
               current date. For example, a call of <code>fn:current-date()</code> might return
                  <code>2004-05-12+01:00</code>. </p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="current-time" prefix="fn">
      <fos:signatures>
         <fos:proto name="current-time" return-type="xs:time"/>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the current time.</p>
      </fos:summary>
      <fos:rules>
         <p>Returns <code>xs:time(fn:current-dateTime())</code>. This is an <code>xs:time</code>
            (with timezone) that is current at some time during the evaluation of a query or
            transformation in which <code>fn:current-time</code> is executed.</p>
         <p>This function is <termref def="dt-deterministic"/>. The precise instant during the query
            or transformation represented by the value of <code>fn:current-time()</code> is <termref
               def="implementation-dependent">implementation-dependent</termref>.</p>
      </fos:rules>
      <fos:notes>
         <p>The returned time will always have an associated timezone, which will always be the same
            as the implicit timezone in the dynamic context</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p><code>fn:current-time()</code> returns an <code>xs:time</code> corresponding to the
               current time. For example, a call of <code>fn:current-time()</code> might return
                  <code>23:17:00.000-05:00</code>. </p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="implicit-timezone" prefix="fn">
      <fos:signatures>
         <fos:proto name="implicit-timezone" return-type="xs:dayTimeDuration"/>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="implicit-timezone">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the value of the implicit timezone property from the dynamic context. </p>
      </fos:summary>
      <fos:rules>
         <p>Returns the value of the implicit timezone property from the dynamic context. Components
            of the dynamic context are described in <xspecref spec="XP31"
               ref="id-xp-evaluation-context-components"/>.</p>
      </fos:rules>
   </fos:function>
   <fos:function name="default-collation" prefix="fn">
      <fos:signatures>
         <fos:proto name="default-collation" return-type="xs:string"/>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the value of the default collation property from the static context. </p>
      </fos:summary>
      <fos:rules>
         <p>Returns the value of the default collation property from the static context. Components
            of the static context are described in <xspecref spec="XP31"
               ref="id-xp-static-context-components"/>.</p>
      </fos:rules>
      <fos:notes>
         <p>The default collation property can never be absent. If it is not explicitly defined, a
            system defined default can be invoked. If this is not provided, the Unicode codepoint
            collation (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>) is
            used. </p>
      </fos:notes>
   </fos:function>
   <fos:function name="default-language" prefix="fn">
      <fos:signatures>
         <fos:proto name="default-language" return-type="xs:language"/>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="default-language">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the value of the default language property from the dynamic context. </p>
      </fos:summary>
      <fos:rules>
         <p>Returns the value of the default language property from the dynamic context. Components
            of the dynamic context are described in <xspecref spec="XP31"
               ref="eval_context"/>.</p>
      </fos:rules>
      <fos:notes>
         <p>The default language property can never be absent. The functions <code>fn:format-integer</code>,
         <code>fn:format-date</code>, <code>fn:format-time</code>, and <code>fn:format-dateTime</code>
         are defined to use the default language if no explicit language is supplied. The default language
         may play a role in selection of a default collation, but this is not a requirement.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="static-base-uri" prefix="fn">
      <fos:signatures>
         <fos:proto name="static-base-uri" return-type="xs:anyURI?"/>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>This function returns the value of the <term>static base URI</term> property from the static
            context.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the value of the <term>static base URI</term> property from the static context.
            If the property is absent, the empty sequence is returned.</p>
         <p>Components of the static context are described in <xspecref spec="XP31"
               ref="static_context"/> .</p>
      </fos:rules>
      <fos:notes>
         <p>XQuery 3.0 and XSLT 3.0 give an implementation freedom to use different base URIs during
            the static analysis phase and the dynamic evaluation phase, that is, for compile-time
            and run-time resources respectively. This is appropriate when the implementation allows
            the output of static analysis (a "compiled" query or stylesheet) to be deployed for execution
            to a different location from the one where static analysis took place. In this situation, the
               <code>fn:static-base-uri</code> function should return a URI suitable for locating
            resources needed during dynamic evaluation.</p>
      </fos:notes>
   </fos:function>
   <fos:function name="function-lookup" prefix="fn">
      <fos:signatures>
         <fos:proto name="function-lookup" return-type="function(*)?">
            <fos:arg name="name" type="xs:QName"/>
            <fos:arg name="arity" type="xs:integer"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-dependent</fos:property>
         <fos:property>higher-order</fos:property>
         <fos:property>special-streaming-rules</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the function having a given name and arity, if there is one.</p>
      </fos:summary>
      <fos:rules>
         <p>A call to <code>fn:function-lookup</code> returns the function obtained by looking up
            the expanded QName supplied as <code>$name</code> and the arity supplied as
               <code>$arity</code> in the named functions component of the dynamic context
            (specifically, the dynamic context of the call to <code>fn:function-lookup</code>).</p>

         <p>Furthermore, if that function has an implementation-dependent implementation (see note
            below), then the implementation of the function returned by
               <code>fn:function-lookup</code> is associated with the static and dynamic context of
            the call to <code>fn:function-lookup</code>.</p>

         <note>
            <p>The above rule deliberately uses the same wording as the corresponding rule for Named
               Function References. The term "a function [with] an implementation-dependent
               implementation" essentially means a function whose implementation is provided by the
               language processor rather than by the stylesheet or query author. This rule is
               therefore relevant to built-in functions and vendor-supplied extension functions
               whose result depends on the context of the function call.</p>
         </note>



         <p>Otherwise (if no known function can be identified by name and arity), an empty sequence
            is returned.</p>

         <p>If the arguments to <code>fn:function-lookup</code> identify a function that is present
            in the static context of the function call, the function will always return the same
            function that a static reference to this function would bind to. If there is no such
            function in the static context, then the results depend on what is present in the
            dynamic context, which is <termref def="implementation-defined"
               >implementation-defined</termref>.</p>



      </fos:rules>

      <fos:notes>
         <p>This function can be useful where there is a need to make a dynamic decision on which of
            several statically-known functions to call. It can thus be used as a substitute for
            polymorphism, in the case where the application has been designed so several functions
            implement the same interface.</p>
         <p>The function can also be useful in cases where a query or stylesheet module is written
            to work with alternative versions of a library module. In such cases the author of the
            main module might wish to test whether an imported library module contains or does not
            contain a particular function, and to call a function in that module only if it is
            available in the version that was imported. A static call would cause a static error if
            the function is not available, whereas getting the function using
               <code>fn:function-lookup</code> allows the caller to take fallback action in this
            situation. </p>
         <p>If the function that is retrieved by <code>fn:function-lookup</code> is <termref
               def="dt-context-dependent">context-dependent</termref>, that is, if it has
            dependencies on the static or dynamic context of its caller, the context that applies is
            the static and/or dynamic context of the call to the <code>fn:function-lookup</code>
            function itself. The context thus effectively forms part of the closure of the returned
            function. In practice this applies only where the target of
               <code>fn:function-lookup</code> is a built-in function, because user-defined
            functions never depend on the static or dynamic context of the function call. The rule
            applies recursively, since <code>fn:function-lookup</code> is itself a context-dependent
            built-in function. </p>
         <p>These specifications do not define any circumstances in which the dynamic context will
            contain functions that are not present in the static context, but neither do they rule
            this out. For example an API <rfc2119>may</rfc2119> provide the ability to add functions
            to the dynamic context. Equally, these specifications do not define any mechanism for
            creating context-dependent functions other than the built-in context-dependent
            functions, but neither do they rule out the existence of such functions. </p>
         <p>The mere fact that a function exists and has a name does not of itself mean that the
         function is present in the dynamic context. For example, functions obtained through
         use of the <code>fn:load-xquery-module</code> function are not added to the dynamic context.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:function-lookup(xs:QName('fn:substring'), 2)('abcd',
                  2)</fos:expression>
               <fos:result>'bcd'</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>

            <p>The expression <code>(fn:function-lookup(xs:QName('xs:dateTimeStamp'), 1),
                  xs:dateTime#1)[1] ('2011-11-11T11:11:11Z')</code> returns an
                  <code>xs:dateTime</code> value set to the specified date, time, and timezone; if
               the implementation supports XSD 1.1 then the result will be an instance of the
               derived type <code>xs:dateTimeStamp</code>. The query is written to ensure that no
               failure occurs when the implementation does not recognize the type
                  <code>xs:dateTimeStamp</code>.</p>


         </fos:example>
         <fos:example>
            <p>The expression <code>let $f := fn:function-lookup(xs:QName('zip:binary-entry'), 2)
                  return if (exists($f)) then $f($href, $entry) else ()</code> returns the result of
               calling <code>zip:binary-entry($href, $entry)</code> if the function is available, or
               an empty sequence otherwise.</p>
         </fos:example>


      </fos:examples>
   </fos:function>
   <fos:function name="function-name" prefix="fn">
      <fos:signatures>
         <fos:proto name="function-name" return-type="xs:QName?">
            <fos:arg name="func" type="function(*)"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the name of the function identified by a function item.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$func</code> refers to a named function, <code>fn:function-name($func)</code>
            returns the name of that function.</p>
         <p>Otherwise (<code>$func</code> refers to an anonymous function),
               <code>fn:function-name($func)</code> returns an empty sequence.</p>
         <p>The prefix part of the returned QName is <termref def="implementation-dependent">implementation-dependent</termref>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:function-name(fn:substring#2)</fos:expression>
               <fos:result>fn:QName("http://www.w3.org/2005/xpath-functions",
                  "fn:substring")</fos:result>
               <fos:postamble>The namespace prefix of the returned QName is not
                  predictable.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:function-name(function($node){count($node/*)})</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>

      </fos:examples>
   </fos:function>
   <fos:function name="function-arity" prefix="fn">
      <fos:signatures>
         <fos:proto name="function-arity" return-type="xs:integer">
            <fos:arg name="func" type="function(*)"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the arity of the function identified by a function item.</p>
      </fos:summary>
      <fos:rules>
         <p>The <code>fn:function-arity</code> function returns the arity (number of arguments) of
            the function identified by <code>$func</code>.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:function-arity(fn:substring#2)</fos:expression>
               <fos:result>2</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:function-arity(function($node){name($node)})</fos:expression>
               <fos:result>1</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>let $initial := fn:substring(?, 1, 1) return
                  fn:function-arity($initial)</fos:expression>
               <fos:result>1</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="for-each" prefix="fn">
      <fos:signatures>
         <fos:proto name="for-each" return-type="item()*">
            <fos:arg name="seq" type="item()*" usage="navigation"/>
            <fos:arg name="action" type="function(item()) as item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Applies the function item <var>$action</var> to every item from the sequence <var>$seq</var>
            in turn, returning the concatenation of the resulting sequences in order.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the function is equivalent to the following implementation in XQuery:</p>
         <eg><![CDATA[
declare function fn:for-each($seq, $action) {
  if (fn:empty($seq))
  then ()
  else ($action(fn:head($seq)), fn:for-each(fn:tail($seq), $action))
};]]></eg>
         <p>or its equivalent in XSLT:</p>
         <eg><![CDATA[
<xsl:function name="fn:for-each">
  <xsl:param name="seq"/>
  <xsl:param name="action"/>
  <xsl:if test="fn:exists($seq)">
    <xsl:sequence select="$action(fn:head($seq)), fn:for-each(fn:tail($seq), $action)"/>
  </xsl:if>
</xsl:function>]]>
         </eg>
      </fos:rules>
      <fos:notes>
         <p>The function call <code>fn:for-each($SEQ, $F)</code> is equivalent to the expression
               <code>for $i in $SEQ return $F($i)</code>, assuming that ordering mode is
               <code>ordered</code>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:for-each(1 to 5, function($a) { $a * $a })</fos:expression>
               <fos:result>(1, 4, 9, 16, 25)</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:for-each(("john", "jane"),
                  fn:string-to-codepoints#1)</fos:expression>
               <fos:result>(106, 111, 104, 110, 106, 97, 110, 101)</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:for-each(("23", "29"), xs:int#1)</fos:expression>
               <fos:result>(23, 29)</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="filter" prefix="fn">
      <fos:signatures>
         <fos:proto name="filter" return-type="item()*">
            <fos:arg name="seq" type="item()*" usage="navigation"/>
            <fos:arg name="f" type="function(item()) as xs:boolean" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns those items from the sequence <var>$seq</var> for which the supplied function
               <var>$f</var> returns true.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the function is equivalent to the following implementation in XQuery:</p>
         <eg><![CDATA[
declare function fn:filter(
        $seq as item()*,
        $f as function(item()) as xs:boolean)
        as item()* {
  if (fn:empty($seq))
  then ()
  else ( fn:head($seq)[$f(.) eq fn:true()], 
         fn:filter(fn:tail($seq), $f)
       )
};]]></eg>
         <p>or its equivalent in XSLT:</p>
         <eg><![CDATA[
<xsl:function name="fn:filter" as="item()*">
  <xsl:param name="seq" as="item()*"/>
  <xsl:param name="f" as="function(item()) as xs:boolean"/>
  <xsl:if test="fn:exists($seq)">
    <xsl:sequence select="fn:head($seq)[$f(.) eq fn:true()], fn:filter(fn:tail($seq), $f)"/>
  </xsl:if>
</xsl:function>]]>
         </eg>
      </fos:rules>
      <fos:errors>
         <p>As a consequence of the function signature and the function calling rules, a type error
            occurs if the supplied function <var>$f</var> returns anything other than a single
               <code>xs:boolean</code> item; there is no conversion to an effective boolean
            value.</p>
      </fos:errors>
      <fos:notes>
         <p>The function call <code>fn:filter($SEQ, $F)</code> has a very similar effect to the
            expression <code>$SEQ[$F(.)]</code>. There are some differences, however. In the case of
               <code>fn:filter</code>, the function <code>$F</code> is required to return a boolean;
            there is no special treatment for numeric predicate values, and no conversion to an
            effective boolean value. Also, with a filter expression <code>$SEQ[$F(.)]</code>, the
            focus within the predicate is different from that outside; this means that the use of a
            context-sensitive function such as <code>fn:lang#1</code> will give different results in
            the two cases.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:filter(1 to 10, function($a) {$a mod 2 = 0})</fos:expression>
               <fos:result>(2, 4, 6, 8, 10)</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:filter((), fn:lang("en", ?))</fos:expression>
               <fos:result>()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="fold-left" prefix="fn">
      <fos:signatures>
         <fos:proto name="fold-left" return-type="item()*">
            <fos:arg name="seq" type="item()*" usage="navigation"/>
            <fos:arg name="zero" type="item()*"/>
            <fos:arg name="f" type="function(item()*, item()) as item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Processes the supplied sequence from left to right, applying the supplied function
            repeatedly to each item in turn, together with an accumulated result value.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the function is equivalent to the following implementation in XQuery:</p>
         <eg><![CDATA[
declare function fn:fold-left(
        $seq as item()*,
        $zero as item()*,
        $f as function(item()*, item()) as item()*) 
        as item()* {
  if (fn:empty($seq))
  then $zero
  else fn:fold-left(fn:tail($seq), $f($zero, fn:head($seq)), $f)
};]]></eg>
         <p>or its equivalent in XSLT:</p>
         <eg><![CDATA[
<xsl:function name="fn:fold-left" as="item()*">
  <xsl:param name="seq" as="item()*"/>
  <xsl:param name="zero" as="item()*"/>
  <xsl:param name="f" as="function(item()*, item()) as item()*"/>
  <xsl:choose>
    <xsl:when test="fn:empty($seq)">
      <xsl:sequence select="$zero"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="fn:fold-left(fn:tail($seq), $f($zero, fn:head($seq)), $f)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>]]>
         </eg>
      </fos:rules>
      <fos:errors>
         <p>As a consequence of the function signature and the function calling rules, a type error
            occurs if the supplied function <var>$f</var> cannot be applied to two arguments, where
            the first argument is either the value of <var>$zero</var> or the result of a previous
            application of <var>$f</var>, and the second 
            <phrase diff="chg" at="B-bug26173">is any single item from the sequence <var>$seq</var></phrase>.</p>
      </fos:errors>
      <fos:notes>
         <p>This operation is often referred to in the functional programming literature as
            "folding" or "reducing" a sequence. It takes a function that operates on a pair of
            values, and applies it repeatedly, with an accumulated result as the first argument, and
            the next item in the sequence as the second argument. The accumulated result is
            initially set to the value of the <var>$zero</var> argument, which is conventionally a
            value (such as zero in the case of addition, one in the case of multiplication, or a
            zero-length string in the case of string concatenation) that causes the function to
            return the value of the other argument unchanged.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:fold-left(1 to 5, 0, function($a, $b) { $a + $b
                  })</fos:expression>
               <fos:result>15</fos:result>
               <fos:postamble>This returns the sum of the items in the sequence</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:fold-left((2,3,5,7), 1, function($a, $b) { $a * $b
                  })</fos:expression>
               <fos:result>210</fos:result>
               <fos:postamble>This returns the product of the items in the sequence</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:fold-left((true(), false(), false()), false(), function($a, $b) {
                  $a or $b })</fos:expression>
               <fos:result>true()</fos:result>
               <fos:postamble>This returns true if any item in the sequence has an effective boolean
                  value of true</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:fold-left((true(), false(), false()), false(), function($a, $b) {
                  $a and $b })</fos:expression>
               <fos:result>false()</fos:result>
               <fos:postamble>This returns true only if every item in the sequence has an effective
                  boolean value of true</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:fold-left(1 to 5, (), function($a, $b) {($b,
                  $a)})</fos:expression>
               <fos:result>(5,4,3,2,1)</fos:result>
               <fos:postamble>This reverses the order of the items in a sequence</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:fold-left(1 to 5, "", fn:concat(?, ".", ?))</fos:expression>
               <fos:result>".1.2.3.4.5"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:fold-left(1 to 5, "$zero", fn:concat("$f(", ?, ", ", ?, ")"))</fos:expression>
               <fos:result>"$f($f($f($f($f($zero, 1), 2), 3), 4), 5)"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:fold-left(1 to 5, map{}, function($map, $n) {map:put($map, $n, $n*2)})</fos:expression>
               <fos:result>map{1:2, 2:4, 3:6, 4:8, 5:10}</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="fold-right" prefix="fn">
      <fos:signatures>
         <fos:proto name="fold-right" return-type="item()*">
            <fos:arg name="seq" type="item()*" usage="navigation"/>
            <fos:arg name="zero" type="item()*"/>
            <fos:arg name="f" type="function(item(), item()*) as item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
         <fos:property>special-streaming-rules</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Processes the supplied sequence from right to left, applying the supplied function
            repeatedly to each item in turn, together with an accumulated result value.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the function is equivalent to the following implementation in XQuery:</p>
         <eg><![CDATA[
declare function fn:fold-right(
        $seq as item()*, 
        $zero as item()*, 
        $f as function(item(), item()*) as item()*) 
        as item()* {
  if (fn:empty($seq))
  then $zero
  else $f(fn:head($seq), fn:fold-right(fn:tail($seq), $zero, $f))
};]]></eg>
         <p>or its equivalent in XSLT:</p>
         <eg><![CDATA[
<xsl:function name="fn:fold-right" as="item()*">
  <xsl:param name="seq" as="item()*"/>
  <xsl:param name="zero" as="item()*"/>
  <xsl:param name="f" as="function(item(), item()*) as item()*"/>
  <xsl:choose>
    <xsl:when test="fn:empty($seq)">
      <xsl:sequence select="$zero"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="$f(fn:head($seq), fn:fold-right(fn:tail($seq), $zero, $f))"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>]]>
         </eg>
      </fos:rules>
      <fos:errors>
         <p>As a consequence of the function signature and the function calling rules, a type error
            occurs if the supplied function <var>$f</var> cannot be applied to two arguments, where
            the first argument is any item in the sequence <var>$seq</var>, and the second is either
            the value of <var>$zero</var> or the result of a previous application of
            <var>$f</var>.</p>

      </fos:errors>
      <fos:notes>
         <p>This operation is often referred to in the functional programming literature as
            "folding" or "reducing" a sequence. It takes a function that operates on a pair of
            values, and applies it repeatedly, with the next item in the sequence as the first
            argument, and the result of processing the remainder of the sequence as the second
            argument. The accumulated result is initially set to the value of the <var>$zero</var>
            argument, which is conventionally a value (such as zero in the case of addition, one in
            the case of multiplication, or a zero-length string in the case of string concatenation)
            that causes the function to return the value of the other argument unchanged.</p>
         <p>In cases where the function performs an associative operation on its two arguments (such
            as addition or multiplication), <code>fn:fold-right</code> produces the same result as
               <code>fn:fold-left</code>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:fold-right(1 to 5, 0, function($a, $b) { $a + $b
                  })</fos:expression>
               <fos:result>15</fos:result>
               <fos:postamble>This returns the sum of the items in the sequence</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:fold-right(1 to 5, "", fn:concat(?, ".", ?))</fos:expression>
               <fos:result>"1.2.3.4.5."</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>fn:fold-right(1 to 5, "$zero", concat("$f(", ?, ", ", ?,
                  ")"))</fos:expression>
               <fos:result>"$f(1, $f(2, $f(3, $f(4, $f(5, $zero)))))"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="for-each-pair" prefix="fn">
      <fos:signatures>
         <fos:proto name="for-each-pair" return-type="item()*">
            <fos:arg name="seq1" type="item()*" usage="navigation"/>
            <fos:arg name="seq2" type="item()*" usage="navigation"/>
            <fos:arg name="action" type="function(item(), item()) as item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Applies the function item <var>$action</var> to successive pairs of items taken one from
               <var>$seq1</var> and one from <var>$seq2</var>, returning the concatenation of the
            resulting sequences in order.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the function is equivalent to the following implementation in XQuery:</p>
         <eg><![CDATA[
declare function fn:for-each-pair($seq1, $seq2, $action)
{
   if(fn:exists($seq1) and fn:exists($seq2)) 
   then (
     $action(fn:head($seq1), fn:head($seq2)),
     fn:for-each-pair(fn:tail($seq1), fn:tail($seq2), $action)
   )
   else ()
};]]></eg>
         <p>or its equivalent in XSLT:</p>
         <eg><![CDATA[
<xsl:function name="fn:for-each-pair">
  <xsl:param name="seq1"/>
  <xsl:param name="seq2"/>
  <xsl:param name="action"/>
  <xsl:if test="fn:exists($seq1) and fn:exists($seq2)">
    <xsl:sequence select="$action(fn:head($seq1), fn:head($seq2))"/>
    <xsl:sequence select="fn:for-each-pair(fn:tail($seq1), fn:tail($seq2), $action)"/>
  </xsl:if>
</xsl:function>]]>
         </eg>
      </fos:rules>
      <fos:notes>
         <p>If one sequence is longer than the other, excess items in the longer sequence are ignored.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:for-each-pair(("a", "b", "c"), ("x", "y", "z"),
                  concat#2)</fos:expression>
               <fos:result>("ax", "by", "cz")</fos:result>
            </fos:test>
         </fos:example>
         <!--<fos:example>
            <fos:test>
               <fos:expression><![CDATA[fn:for-each-pair(function($a, $b){<e a="{$a}" b="{$b}"/>}, (1 to 3), ("x", "y", "z"))]]></fos:expression>
               <fos:result as="element()*"><![CDATA[(<e a="1" b="x"/>, <e a="2" b="y"/>, <e a="3" b="z"/>)]]></fos:result>
               <fos:postamble>This example uses XQuery syntax</fos:postamble>
            </fos:test>
         </fos:example>-->
         <fos:example>
            <fos:test>
               <fos:expression>fn:for-each-pair(1 to 5, 1 to 5, function($a, $b){10*$a + $b})</fos:expression>
               <fos:result>(11, 22, 33, 44, 55)</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test>
               <fos:expression>let $s := 1 to 8 return fn:for-each-pair($s, tail($s), function($a, $b){$a*$b})</fos:expression>
               <fos:result>(2, 6, 12, 20, 30, 42, 56)</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="sort" prefix="fn" diff="chg" at="E">
      <fos:signatures>
         <fos:proto name="sort" return-type="item()*">
            <fos:arg name="input" type="item()*" usage="navigation"/>
         </fos:proto>
         <fos:proto name="sort" return-type="item()*">
            <fos:arg name="input" type="item()*" usage="navigation"/>
            <fos:arg name="collation" type="xs:string?" usage="absorption"/>
         </fos:proto>
         <fos:proto name="sort" return-type="item()*">
            <fos:arg name="input" type="item()*" usage="navigation"/>
            <fos:arg name="collation" type="xs:string?" usage="absorption"/>
            <fos:arg name="key" type="function(item()) as xs:anyAtomicType*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="3">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      
      
      <fos:summary>
         <p>Sorts a supplied sequence, based on the value of a sort key supplied as a function.</p>
      </fos:summary>
      <fos:rules>
         <p>Calling the single-argument version of the function is equivalent to calling the two-argument form
         with <code>default-collation()</code> as the second argument: that is, it sorts a sequence of items according
         to the typed value of the items, using the default collation to compare strings.</p>
         
         <p>Calling the two-argument version of the function is equivalent to calling the three-argument form
            with <code>fn:data#1</code> as the third argument: that is, it sorts a sequence of items according
            to the typed value of the items, using a specified collation to compare strings.</p>
         
         <p>In the case of both <code>fn:sort#2</code> and <code>fn:sort#3</code>, supplying an empty
         sequence as the second argument is equivalent to supplying <code>fn:default-collation()</code>. For more
         information on collations see <specref ref="choosing-a-collation"/>.</p>
         
         <p>The result of the function is obtained as follows:</p>
         <ulist>
            <item><p>For each item in the sequence <code>$input</code>, the function supplied as <code>$key</code> 
               is evaluated with that item as its argument. 
               The resulting values are the sort keys of the items in the input sequence.
            </p></item>
            <item><p>The result sequence contains the same items as the input sequence <code>$input</code>, but generally in a different order.</p></item>
            <item><p>Let <var>$C</var> be the selected collation, or the default collation where applicable.</p></item>
            <item><p>The order of items in the result is such that, given two items <code>$A</code> and <code>$B</code>:</p>
            <ulist>
               <item><p>If <code>(fn:deep-equal($key($A), $key($B), $C)</code>, then the relative order of <code>$A</code> and <code>$B</code> 
                  in the output is the same as their relative order in the input (that is, the sort is stable)
               </p></item>
               <item><p>Otherwise, if <code>(deep-less-than($key($A), $key($B), $C)</code>, then <code>$A</code> precedes <code>$B</code> in the output. 
                  The function <code>deep-less-than</code> is defined as the boolean result of the expression:
               </p>
                  <eg diff="chg" at="D"><code>if (fn:empty($A)) 
     then fn:exists($B)
else if (fn:deep-equal($A[1], $B[1], $C)) 
     then deep-less-than(fn:tail($A), fn:tail($B), $C)
else if ($A[1] ne $A[1] (:that is, $A[1] is NaN:)) 
     then fn:true()
else if (is-string($A[1]) and is-string($B[1]) 
     then fn:compare($A[1], $B[1], $C) lt 0
else $A[1] lt $B[1]</code></eg>
                  
                  
                  
                  <p>where the function <code>is-string($X)</code> returns true if and only if <code>$X</code> is an instance of 
                     <code>xs:string</code>, <code>xs:anyURI</code>, or <code>xs:untypedAtomic</code>.</p>
                  
                  
                  <p>This ordering of sequences is referred to by mathematicians as "lexicographic ordering".
                  </p>
               </item>
         </ulist>
            </item>
         </ulist>
      </fos:rules>
      <fos:errors>
         <p>If the set of computed sort keys contains values that are not comparable using the <code>lt</code> operator then the sort 
            operation will fail with a type error (<xerrorref spec="XP" class="TY" code="0004"/>).
         </p>
      </fos:errors>
      <fos:notes>
         <p>XSLT and XQuery both provide native sorting capability, but previous releases of XPath provided no sorting functionality
         for use in standalone environments.</p>
         <p>In addition there are cases where this function may be more flexible than the built-in sorting capability for XQuery or XSLT,
         for example when the sort key or collation is chosen dynamically, or when the sort key is a sequence of items rather than a single
         item.</p>
         <p>The results are compatible with the results of XSLT sorting (using <code>xsl:sort</code>) in the case where the sort key evaluates to a sequence of
         length zero or one, given the options <code>stable="yes"</code> and <code>order="ascending"</code>.</p>
         <p>The results are compatible with the results of XQuery sorting (using the <code>order by</code> clause) in the case where the sort key evaluates to a sequence of
            length zero or one, given the options <code>stable</code>, <code>ascending</code>, and <code>empty least</code>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:sort((1, 4, 6, 5, 3))</fos:expression>
               <fos:result>(1, 3, 4, 5, 6)</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>fn:sort((1, -2, 5, 10, -10, 10, 8), (), fn:abs#1)</fos:expression>
               <fos:result>(1, -2, 5, 8, 10, -10, 10)</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>To sort a set of strings <code>$in</code> using Swedish collation:</p>
            <eg>
let $SWEDISH := "http://www.w3.org/2013/collation/UCA?lang=se"
return fn:sort($in, $SWEDISH)
            </eg>
         </fos:example>
         <fos:example>
            <p>To sort a sequence of employees by last name as the major sort key and first name as the minor sort key,
               using the default collation:
            </p>
            <eg>fn:sort($employees, (), function($emp) {$emp/name ! (last, first)})</eg>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="apply" prefix="fn" diff="add" at="C">
      <fos:signatures>
         <fos:proto name="apply" return-type="item()*">
            <fos:arg name="function" type="function(*)"/>
            <fos:arg name="array" type="array(*)" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Makes a dynamic call on a function with an argument list supplied in the form of an array.</p>
      </fos:summary>
      <fos:rules>
         <p>The result of the function is obtained by invoking the supplied function <code>$function</code> with arguments
         taken from the members of the supplied array <code>$array</code>. The first argument of the function call is the first
         member of <code>$array</code>, the second argument is the second member of <code>$array</code>, and so on.</p>
         <p>The arity of the supplied function <code>$function</code> must be the same as the size of the array <code>$array</code>.</p>
         <p>The effect of calling <code>fn:apply($f, [$a, $b, $c, ...])</code> is the same as the effect of the dynamic function call 
            <code>$f($a, $b, $c, ....)</code>. For example, the function conversion rules are applied to the supplied arguments
            in the usual way.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised if the arity of the function <code>$function</code> is not the same as the size of the
            array <code>$array</code> (<errorref spec="FO" class="AP" code="0001"/>).
         </p>
      </fos:errors>
      <fos:notes>
         <p>The function is useful where the arity of a function item is not known statically.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>fn:apply(fn:concat#3, ["a", "b", "c"])</fos:expression>
               <fos:result>"abc"</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>The expression <code>fn:apply($f, array:subarray(["a", "b", "c", "d", "e", "f"], 1, fn:function-arity($f)))</code> 
               calls the supplied function <code>$f</code> supplying the number of arguments required by its arity.</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="same-key" prefix="op">
      <fos:signatures>
         <fos:proto name="same-key" return-type="xs:boolean">
            <fos:arg name="k1" type="xs:anyAtomicType"/>
            <fos:arg name="k2" type="xs:anyAtomicType"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Determines whether two atomic values can coexist as separate keys within a map.</p>
      </fos:summary>
      <fos:rules>
         <p>The internal function <code>op:same-key</code> (which is not available at the user level) is used to assess whether two atomic
            values are considered to be duplicates when used as keys in a map. A map cannot
         contain two separate entries whose keys are <term>the same</term> as defined by this function. 
         The function is also used when matching keys in functions such as <code>map:get</code>
         and <code>map:remove</code>.</p>
         
         <p>The function returns true if and only if one of the following conditions is true:</p>
         
         <olist>
            <item><p>All of the following conditions are true:</p>
               <olist>
                  <item><p><code>$k1</code> is an instance of <code>xs:string</code>, <code>xs:anyURI</code>, or <code>xs:untypedAtomic</code></p></item>
                  <item><p><code>$k2</code> is an instance of <code>xs:string</code>, <code>xs:anyURI</code>, or <code>xs:untypedAtomic</code></p></item>
                  <item><p><code>fn:codepoint-equal($k1, $k2)</code></p></item>
               </olist>
               <note><p>Strings are compared without any dependency on collations.</p></note>
            </item>
            <item><p>All of the following conditions are true:</p>
               <olist>
                  <item><p><code>$k1</code> is an instance of <code>xs:decimal</code>, <code>xs:double</code>, or <code>xs:float</code></p></item>
                  <item><p><code>$k2</code> is an instance of <code>xs:decimal</code>, <code>xs:double</code>, or <code>xs:float</code></p></item>
                  <item><p>One of the following conditions is true:</p>
                     <olist>
                        <item><p>Both <code>$k1</code> and <code>$k2</code> are <code>NaN</code></p>
                        <note><p><code>xs:double('NaN')</code> is the same key as <code>xs:float('NaN')</code></p></note></item>
                        <item><p>Both <code>$k1</code> and <code>$k2</code> are positive infinity</p>
                           <note><p><code>xs:double('INF')</code> is the same key as <code>xs:float('INF')</code></p></note></item>
                        <item><p>Both <code>$k1</code> and <code>$k2</code> are negative infinity</p>
                           <note><p><code>xs:double('-INF')</code> is the same key as <code>xs:float('-INF')</code></p></note></item>
                        <item><p><code>$k1</code> and <code>$k2</code> when converted to decimal numbers with no rounding or loss of precision
                           are mathematically equal.</p>
                           <note><p>Every instance of <code>xs:double</code>, <code>xs:float</code>, and <code>xs:decimal</code> can be represented
                              exactly as a decimal number provided enough digits are available both before and after the decimal point. Unlike the <code>eq</code>
                              relation, which converts both operands to <code>xs:double</code> values, possibly losing precision in the process, this
                              comparison is transitive.</p></note>
                           <note><p>Positive and negative zero are the same key.</p></note>
                        </item>
                     </olist>
                  </item>                
               </olist>
               
            </item>
            <item><p>All of the following conditions are true:</p>
               <olist>
                  <item><p><code>$k1</code> is an instance of <code>xs:date</code>, <code>xs:time</code>, <code>xs:dateTime</code>,
                     <code>xs:gYear</code>, <code>xs:gYearMonth</code>, <code>xs:gMonth</code>, <code>xs:gMonthDay</code>, or <code>xs:gDay</code></p></item>
                  <item><p><code>$k2</code> is an instance of <code>xs:date</code>, <code>xs:time</code>, <code>xs:dateTime</code>,
                     <code>xs:gYear</code>, <code>xs:gYearMonth</code>, <code>xs:gMonth</code>, <code>xs:gMonthDay</code>, or <code>xs:gDay</code></p></item>
                  <item><p>One of the following conditions is true:</p>
                        <olist>
                           <item><p>Both <code>$k1</code> and <code>$k2</code> have a timezone</p></item>
                           <item><p>Neither <code>$k1</code> nor <code>$k2</code> has a timezone</p></item>
                        </olist>
                  </item>
                  <item><p><code>fn:deep-equal($k1, $k2)</code></p>
                  <note><p>The use of <code>deep-equal</code> rather than <code>eq</code> ensures that comparing values of different
                  types yields <code>false</code> rather than an error.</p></note></item>
                  
               </olist>
               <note><p>Unlike the <code>eq</code> operator, this comparison has no dependency on the implicit timezone, which means that
                  the question of whether or not a map contains duplicate keys is not dependent on this aspect of the dynamic context.</p></note>
            </item>
            <item>
               <p>All of the following conditions are true:</p>
               <olist>
                  <item><p><code>$k1</code> is an instance of <code>xs:boolean</code>, <code>xs:hexBinary</code>, <code>xs:base64Binary</code>,
                     <code>xs:duration</code>, <code>xs:QName</code>, or <code>xs:NOTATION</code></p></item>
                  <item><p><code>$k2</code> is an instance of <code>xs:boolean</code>, <code>xs:hexBinary</code>, <code>xs:base64Binary</code>,
                     <code>xs:duration</code>, <code>xs:QName</code>, or <code>xs:NOTATION</code></p></item>
                  <item><p><code>fn:deep-equal($k1, $k2)</code></p>
                     <note><p>The use of <code>deep-equal</code> rather than <code>eq</code> ensures that comparing values of different
                        types yields <code>false</code> rather than an error.</p></note></item>
               </olist>
            </item>
         </olist>
         
      </fos:rules>
      
      <fos:notes>
         <p>The rules for comparing keys in a map are chosen to ensure that the comparison is:</p>
         <ulist>
            <item><p><term>Context-free</term>: there is no dependency on the static or dynamic context</p></item>
            <item><p><term>Error-free</term>: any two atomic values can be compared, and the result is either true or false, never an error</p></item>
            <item><p><term>Transitive</term>: if <var>A</var> is the same key as <var>B</var>, and <var>B</var> is the same key as <var>C</var>, 
               then <var>A</var> is the same key as <var>C</var>.</p></item>
         </ulist>
         <p>As always, any algorithm that delivers the right result is acceptable. For example, when testing whether an <code>xs:double</code>
         value <var>D</var> is the same key as an <code>xs:decimal</code> value that has <var>N</var> significant digits, it is not
         necessary to know all the digits in the decimal expansion of <var>D</var> to establish the result: computing the first <var>N+1</var> 
            significant digits (or indeed, simply knowing that there are more than <var>N</var> significant digits) is sufficient.</p>
      </fos:notes>
      
   </fos:function>

 <fos:function name="merge" prefix="map" diff="chg" at="E">
      <fos:signatures>
         <fos:proto name="merge" return-type="map(*)">
            <fos:arg name="maps" type="map(*)*" usage="inspection"/>
         </fos:proto>
         <fos:proto name="merge" return-type="map(*)">
            <fos:arg name="maps" type="map(*)*" usage="inspection"/>
            <fos:arg name="options" type="map(*)" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a map that combines the entries from a number of existing maps.</p>
      </fos:summary>
      <fos:rules>
         <p>The function <code>map:merge</code> <phrase diff="chg" at="C">returns a map</phrase> that
            is formed by combining the contents of the maps supplied in the <code>$maps</code>
            argument.</p>


         <p>Informally, the supplied maps are combined as follows:</p>

         <olist>
            <item>
               <p>There is one entry in the returned map for each distinct key present in the union
                  of the input maps, where two keys are distinct if they are not the <phrase
                     diff="chg" at="N"><termref def="dt-same-key">same key</termref></phrase>.</p>
            </item>
            <item>
               <p diff="chg" at="E">If there are duplicate keys, that is, if two or more maps contain entries having the
                  <termref def="dt-same-key">same key</termref>, then the way this is handled is
                  controlled by the second (<code>$options</code>) argument.</p>
            </item>
         </olist>

         
         <p>The definitive specification is as follows.</p>
         
         <olist>
            <item><p>The effect of calling the single-argument function is the same as the effect of
            calling the two-argument function with an empty map as the value of <code>$options</code>.</p></item>
            <item><p>The <code>$options</code> argument can be used to control the way in which duplicate keys are handled.
               The <termref def="dt-option-parameter-conventions">option parameter conventions</termref> apply.
            </p></item>
            <item><p>The entries that may appear in the <code>$options</code> map are as follows:</p>
               
               <fos:options>
                  <fos:option key="duplicates">
                     <fos:meaning>Determines the policy for handling duplicate keys: specifically, the action to be
                        taken if two maps in the input sequence <code>$maps</code> contain entries with key values
                        <var>K1</var> and <var>K2</var> where <var>K1</var> and <var>K2</var> are the 
                        <termref def="same-key">same key</termref>.
                     </fos:meaning>
                     <fos:type>xs:string</fos:type>
                     <fos:default>use-first</fos:default>
                     <fos:values>
                        <fos:value value="reject">
                           An error is raised <errorref class="JS" code="0003"/> if duplicate keys are encountered.
                        </fos:value>
                        <fos:value value="use-first">
                           If duplicate keys are present, all but the first of a set of duplicates are ignored, 
                           where the ordering is based on the order of maps in the <code>$maps</code> argument.
                        </fos:value>
                        <fos:value value="use-last">
                           If duplicate keys are present, all but the last of a set of duplicates are ignored, 
                           where the ordering is based on the order of maps in the <code>$maps</code> argument.
                        </fos:value>
                        <fos:value value="use-any">
                           If duplicate keys are present, all but one of a set of duplicates are ignored, 
                           and it is <termref def="implementation-dependent">implementation-dependent</termref>
                           which one is retained. 
                        </fos:value>
                        <fos:value value="combine">
                           If duplicate keys are present, the result map includes an entry for the key whose 
                           associated value is the sequence-concatenation of all the values associated with the key, 
                           retaining order based on the order of maps in the <code>$maps</code> argument.
                           The key value in the result map that corresponds to such a set of duplicates must
                           be the <termref def="same-key">same key</termref> as each of the duplicates, but it is
                           otherwise unconstrained: for example if the duplicate keys are <code>xs:byte(1)</code>
                           and <code>xs:short(1)</code>, the key in the result could legitimately be <code>xs:long(1)</code>.
                        </fos:value>
                     </fos:values>
                  </fos:option>
               </fos:options>
               
               <!--<table border="1" cellpadding="1" summary="options for the map:merge function">
                  <thead>
                     <tr>
                        <th>Key</th>
                        <th>Value</th>
                        <th>Meaning</th>
                     </tr>
                  </thead>
                  <tbody>
                     
                     
                     <tr>
                        <td rowspan="6">
                           <code>duplicates</code>
                        </td>
                        <td colspan="2">Determines the policy for handling duplicate keys: specifically, the action to be
                           taken if two maps in the input sequence <code>$maps</code> contain entries with key values
                           <var>K1</var> and <var>K2</var> where <var>K1</var> and <var>K2</var> are the <termref def="same-key">same key</termref>.
                           The required type is <code>xs:string</code>. The default value is <code>use-first</code>.</td>
                     </tr>
                     <tr>
                        <td>
                           <code>reject</code>
                        </td>
                        <td>An error is raised <errorref class="JS" code="0003"/> if duplicate keys are encountered.</td>
                     </tr>
                     <tr>
                        <td>
                           <code>use-first</code>
                        </td>
                        <td>If duplicate keys are present, all but the first of a set of duplicates are ignored, 
                           where the ordering is based on the order of maps in the <code>$maps</code> argument.</td>
                     </tr>
                     <tr>
                        <td>
                           <code>use-last</code>
                        </td>
                        <td>If duplicate keys are present, all but the last of a set of duplicates are ignored, 
                           where the ordering is based on the order of maps in the <code>$maps</code> argument.</td>
                     </tr>
                     <tr>
                        <td>
                           <code>combine</code>
                        </td>
                        <td>If duplicate keys are present, the result map includes an entry for the key whose 
                           associated value is the sequence-concatenation of all the values associated with the key, 
                           retaining order based on the order of maps in the <code>$maps</code> argument.
                           The key value in the result map that corresponds to such a set of duplicates must
                           be the <termref def="same-key">same key</termref> as each of the duplicates, but it is
                           otherwise unconstrained: for example if the duplicate keys are <code>xs:byte(1)</code>
                           and <code>xs:short(1)</code>, the key in the result could legitimately be <code>xs:long(1)</code>.
                        </td>
                     </tr>
                     <tr>
                        <td>
                           <code>use-any</code>
                        </td>
                        <td>If duplicate keys are present, all but one of a set of duplicates are ignored, 
                           and it is <termref def="implementation-dependent">implementation-dependent</termref>
                           which one is retained. 
                        </td>
                     </tr>
                     
                     
                   
                     
                  </tbody>
               </table>-->
            </item>
         </olist>
         <p>The result of the function call <code>map:merge($MAPS, $OPTIONS)</code>
         is defined to be consistent with the result of the expression:</p>
         
         <eg><![CDATA[
let $FOJS0003 := QName("http://www.w3.org/2005/xqt-errors", "FOJS0003"),

$duplicates-handler := map {
  "use-first":   function($a, $b) {$a},
  "use-last":    function($a, $b) {$b},
  "combine":     function($a, $b) {$a, $b},
  "reject":      function($a, $b) {fn:error($FOJS0003)},
  "use-any": function($a, $b) {fn:random-number-generator()?permute(($a, $b))[1]}
},

$combine-maps := function($A as map(*), $B as map(*), $deduplicator as function(*)) {
    fn:fold-left(map:keys($B), $A, function($z, $k){ 
        if (map:contains($z, $k))
        then map:put($z, $k, $deduplicator($z($k), $B($k)))
        else map:put($z, $k, $B($k))
    })
}
return fn:fold-left($MAPS, map{}, 
    $combine-maps(?, ?, $duplicates-handler(($OPTIONS?duplicates, "use-first")[1]))
            
            ]]></eg>
         
         <note>
            <p>By way of explanation, <code>$combine-maps</code> is a function that combines
            two maps by iterating over the keys of the second map, adding each key and its corresponding
            value to the first map as it proceeds. The second call of <code>fn:fold-left</code>
            in the <code>return</code> clause then iterates over the maps supplied in the call
            to <code>map:merge</code>, accumulating a single map that absorbs successive maps
            in the input sequence by calling <code>$combine-maps</code>.</p>
         
       
        <p>This algorithm processes the supplied maps in a defined order, but processes the keys within
         each map in implementation-dependent order.</p>
         
         <p>The use of <code>fn:random-number-generator</code> represents one possible conformant
         implementation for <code>"duplicates":"use-any"</code>, but it is not the only conformant
         implementation and is not intended to be a realistic implementation. The purpose of this
         option is to allow the implementation to use whatever strategy is most efficient; for example,
         if the input maps are processed in parallel, then specifying <code>"duplicates":"use-any"</code>
         means that the implementation does not need to keep track of the original order of the sequence of input
         maps.</p>
            
         </note>

         
      </fos:rules>
    <fos:errors>
       <p>An error is raised <errorref spec="FO" class="JS" code="0003"/> if the value of 
          <code>$options</code> indicates that duplicates are to be rejected, and a duplicate key is encountered.</p>
       <p>An error is raised <errorref spec="FO" class="JS" code="0005"/> if the value of 
          <code>$options</code> includes an entry whose key is defined 
          in this specification, and whose value is not a permitted value for that key.</p>
    </fos:errors>
      
      <fos:notes>
         <p diff="add" at="R-bug24726">If the input is an empty sequence, the result is an empty map.</p>
         <p diff="add" at="R-bug24726">If the input is a sequence of length one, the result map is 
            <phrase diff="chg" at="C">indistinguishable from the supplied map</phrase>.</p>
         <p>There is no requirement that the supplied input maps should have the same or compatible
            types. The type of a map (for example <code>map(xs:integer, xs:string)</code>) is
            descriptive of the entries it currently contains, but is not a constraint on how the map
            may be combined with other maps.</p>
      </fos:notes>
      <fos:examples>
         <fos:variable name="week"  id="v-map-merge-week"
            select="map{0:&quot;Sonntag&quot;, 1:&quot;Montag&quot;, 2:&quot;Dienstag&quot;,&#xa;     3:&quot;Mittwoch&quot;, 4:&quot;Donnerstag&quot;, 5:&quot;Freitag&quot;, 6:&quot;Samstag&quot;}"/>
         <fos:example>
            <fos:test>
               <fos:expression>map:merge(())</fos:expression>
               <fos:result>map{}</fos:result>
               <fos:postamble>Returns an empty map</fos:postamble>
            </fos:test>
            <fos:test>
               <fos:expression>map:merge((map:entry(0, "no"), map:entry(1, "yes")))</fos:expression>
               <fos:result>map{0:"no", 1:"yes"}</fos:result>
               <fos:postamble>Returns a map with two entries</fos:postamble>
            </fos:test>
            <fos:test use="v-map-merge-week">
               <fos:expression>map:merge(($week, map{7:"Unbekannt"}))</fos:expression>
               <fos:result>map{0:"Sonntag", 1:"Montag", 2:"Dienstag", 3:"Mittwoch", 4:"Donnerstag",
                  5:"Freitag", 6:"Samstag", 7:"Unbekannt"}</fos:result>
               <fos:postamble>The value of the existing map is unchanged; the <phrase diff="chg" at="C">returned map 
                  contains</phrase> all the entries from <code>$week</code>, supplemented with an additional
                  entry.</fos:postamble>
            </fos:test>
            <fos:test use="v-map-merge-week">
               <fos:expression>map:merge(($week, map{6:"Sonnabend"}), map{"duplicates":"use-last"})</fos:expression>
               <fos:result>map{0:"Sonntag", 1:"Montag", 2:"Dienstag", 3:"Mittwoch", 4:"Donnerstag",
                  5:"Freitag", 6:"Sonnabend"}</fos:result>
               <fos:postamble>The value of the existing map is unchanged; the returned map
                  contains all the entries from <code>$week</code>, with one entry replaced by a
                  new entry. Both input maps contain an entry with the key <code>6</code>; the
                  one used in the result is the one that comes last in the input
                  sequence.</fos:postamble>
            </fos:test>
            <fos:test use="v-map-merge-week">
               <fos:expression>map:merge(($week, map{6:"Sonnabend"}), map{"duplicates":"use-first"})</fos:expression>
               <fos:result>map{0:"Sonntag", 1:"Montag", 2:"Dienstag", 3:"Mittwoch", 4:"Donnerstag",
                  5:"Freitag", 6:"Samstag"}</fos:result>
               <fos:postamble>The value of the existing map is unchanged; the returned map
                  contains all the entries from <code>$week</code>, with one entry replaced by a
                  new entry. Both input maps contain an entry with the key <code>6</code>; the
                  one used in the result is the one that comes first in the input
                  sequence.</fos:postamble>
            </fos:test>
            <fos:test use="v-map-merge-week">
               <fos:expression>map:merge(($week, map{6:"Sonnabend"}), map{"duplicates":"combine"})</fos:expression>
               <fos:result>map{0:"Sonntag", 1:"Montag", 2:"Dienstag", 3:"Mittwoch", 4:"Donnerstag",
                  5:"Freitag", 6:("Samstag", "Sonnabend")}</fos:result>
               <fos:postamble>The value of the existing map is unchanged; the returned map
                  contains all the entries from <code>$week</code>, with one entry replaced by a
                  new entry. Both input maps contain an entry with the key <code>6</code>; the
                  entry that appears in the result is the sequence-concatenation of the entries
                  in the input maps, retaining order.</fos:postamble>
            </fos:test>

         </fos:example>
      </fos:examples>
   </fos:function>

   <fos:function name="keys" prefix="map">
      <fos:signatures>
         <fos:proto name="keys" return-type="xs:anyAtomicType*">
            <fos:arg name="map" type="map(*)" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>nondeterministic-wrt-ordering</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a sequence containing all the keys present in a map</p>
      </fos:summary>
      <fos:rules>
         <p>The function <code>map:keys</code> takes any <termref def="dt-map">map</termref>
            as its <code>$map</code> argument and returns the keys that are present in the map as
            a sequence of atomic values, in <termref def="dt-implementation-dependent"
               >implementation-dependent</termref> order.</p>
         <p diff="add" at="D">The function is <term>non-deterministic with respect to ordering</term>
            (see <specref ref="properties-of-functions"/>). This means that two calls with the same argument
            are not guaranteed to produce the results in the same order.</p>
      </fos:rules>
      <fos:notes>
         <p diff="add" at="P">The number of items in the result will be the same as the number of
            entries in the map, and the result sequence will contain no duplicate values.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>map:keys(map{1:"yes", 2:"no"})</fos:expression>
               <fos:result allow-permutation="true">(1,2)</fos:result>
               <fos:postamble>The result is in <termref def="dt-implementation-dependent"
                     >implementation-dependent</termref> order.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>

   <fos:function name="contains" prefix="map" diff="add" at="MAP">
      <fos:signatures>
         <fos:proto name="contains" return-type="xs:boolean">
            <fos:arg name="map" type="map(*)" usage="inspection"/>
            <fos:arg name="key" type="xs:anyAtomicType"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Tests whether a supplied map contains an entry for a given key</p>
      </fos:summary>
      <fos:rules>
         <p>The function <code>map:contains</code> returns true if the <termref def="dt-map"
               >map</termref> supplied as <code>$map</code> contains an entry with <phrase
               diff="chg" at="N">the <termref def="dt-same-key">same key</termref> as</phrase> the
            supplied value of <code>$key</code>; otherwise it returns false.</p>

        

      </fos:rules>
      

      <fos:examples>
         <fos:variable name="week"  id="v-map-contains-week"
            select="map{0:&quot;Sonntag&quot;, 1:&quot;Montag&quot;, 2:&quot;Dienstag&quot;,&#xa;     3:&quot;Mittwoch&quot;, 4:&quot;Donnerstag&quot;, 5:&quot;Freitag&quot;, 6:&quot;Samstag&quot;}"/>
         <fos:example>
            <fos:test use="v-map-contains-week">
               <fos:expression>map:contains($week, 2)</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
            <fos:test use="v-map-contains-week">
               <fos:expression>map:contains($week, 9)</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>map:contains(map{}, "xyz")</fos:expression>
               <fos:result>false()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>map:contains(map{"xyz":23}, "xyz")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>map:contains(map{"abc":23, "xyz":()}, "xyz")</fos:expression>
               <fos:result>true()</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="get" prefix="map" diff="add" at="MAP">
      <fos:signatures>
         <fos:proto name="get" return-type="item()*">
            <fos:arg name="map" type="map(*)" usage="inspection"/>
            <fos:arg name="key" type="xs:anyAtomicType"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the value associated with a supplied key in a given map.</p>
      </fos:summary>
      <fos:rules>
         <p>The function <code>map:get</code> attempts to find an entry within the <termref
               def="dt-map">map</termref> supplied as <code>$map</code> that has <phrase diff="chg"
               at="N">the <termref def="dt-same-key">same key</termref> as</phrase> the supplied
            value of <code>$key</code>. If there is such an entry, it returns the associated value;
            otherwise it returns an empty sequence.</p>

      </fos:rules>
      <fos:notes>
         <p>A return value of <code>()</code> from <code>map:get</code> could indicate that
            the key is present in the map with an associated value of <code>()</code>, or it could
            indicate that the key is not present in the map. The two cases can be distinguished by
            calling <code>map:contains</code>.</p>

         <p>Invoking the <termref def="dt-map">map</termref> as a function item has the same effect
            as calling <code>get</code>: that is, when <code>$map</code> is a map, the expression
               <code>$map($K)</code> is equivalent to <code>map:get($map, $K)</code>. Similarly, the
            expression <code>map:get(map:get(map:get($map, 'employee'), 'name'), 'first')</code> can
            be written as <code>$map('employee')('name')('first')</code>. </p>
         
      </fos:notes>
      <fos:examples>
         <fos:variable name="week"  id="v-map-get-week"
            select="map{0:&quot;Sonntag&quot;, 1:&quot;Montag&quot;, 2:&quot;Dienstag&quot;,&#xa;     3:&quot;Mittwoch&quot;, 4:&quot;Donnerstag&quot;, 5:&quot;Freitag&quot;, 6:&quot;Samstag&quot;}"/>
         <fos:example>
            <fos:test use="v-map-get-week">
               <fos:expression>map:get($week, 4)</fos:expression>
               <fos:result>"Donnerstag"</fos:result>
            </fos:test>
            <fos:test use="v-map-get-week">
               <fos:expression>map:get($week, 9)</fos:expression>
               <fos:result>()</fos:result>
               <fos:postamble>When the key is not present, the function returns an empty
                  sequence.</fos:postamble>
            </fos:test>
            <fos:test>
               <fos:expression>map:get(map:entry(7,()), 7)</fos:expression>
               <fos:result>()</fos:result>
               <fos:postamble>An empty sequence as the result can also signify that the key is
                  present and the associated value is an empty sequence.</fos:postamble>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="find" prefix="map" diff="add" at="MAP">
      <fos:signatures>
         <fos:proto name="find" return-type="array(*)">
            <fos:arg name="input" type="item()*" usage="inspection"/>
            <fos:arg name="key" type="xs:anyAtomicType"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Searches the supplied input sequence and any contained maps and arrays for a map entry with the supplied key,
            and returns the corresponding values.</p>
      </fos:summary>
      <fos:rules>
         <p>The function <code>map:find</code> searches the sequence supplied as <code>$input</code>
         looking for map entries whose key is the <termref def="dt-same-key">same key</termref>
         as <code>$key</code>. The associated value in any such map entry (each being in general a sequence)
         is returned as a member of the result array.</p>
         
         <p>The search processes the <code>$input</code> sequence using the following recursively-defined rules 
            (any equivalent algorithm may be used provided it delivers
            the same result, respecting those rules that constrain the order of the result):</p>
         
         <olist>
            <item><p>To process a sequence, process each of its items in order.</p></item>
            <item><p>To process an item that is an array, process each of the array's members in order 
               (each member is, in general, a sequence).</p></item>
            <item><p>To process an item that is a map, then for each key-value entry (<var>K</var>, <var>V</var>)
               in the map (in <termref def="dt-implementation-dependent">implementation-dependent</termref> order)
               perform both of the following steps, in order:</p>
            <olist>
               <item><p>If <var>K</var> is the <termref def="dt-same-key">same key</termref> as <code>$key</code>, 
                  then add <var>V</var> as a new member to the end of the result array.</p></item>
               <item><p>Process <var>V</var> (which is, in general, a sequence).</p></item>
            </olist></item>
            <item><p>To process an item that is neither a map nor an array, do nothing. (Such items are ignored).</p></item>
         </olist>
         
      </fos:rules>
      <fos:notes>
         <p>If <code>$input</code> is an empty sequence, map, or array, or if the requested <code>$key</code> is not found,
            the result will be a zero-length array.</p>
   
      </fos:notes>
      <fos:examples>
         <fos:variable name="responses"  id="v-map-find-responses"
            select="[map{0:'no', 1:'yes'}, map{0:'non', 1:'oui'}, &#xa;                  map{0:'nein', 1:('ja', 'doch')}]"/>
         <fos:example>
            <fos:test use="v-map-find-responses">
               <fos:expression>map:find($responses, 0)</fos:expression>
               <fos:result>['no', 'non', 'nein']</fos:result>
            </fos:test>
            <fos:test use="v-map-find-responses">
               <fos:expression>map:find($responses, 1)</fos:expression>
               <fos:result>['yes', 'oui', ('ja', 'doch')]</fos:result>
            </fos:test>
            <fos:test use="v-map-find-responses">
               <fos:expression>map:find($responses, 2)</fos:expression>
               <fos:result>[]</fos:result>
            </fos:test>
 
         </fos:example>
         <fos:variable name="inventory" id="v-map-find-inventory"
            select='map{"name":"car", "id":"QZ123", &#xa;      "parts": [map{"name":"engine", "id":"YW678", "parts":[]}]}'/>
         <fos:example>
            <fos:test use="v-map-find-inventory">
               <fos:expression>map:find($inventory, "parts")</fos:expression>
               <fos:result>[[map{"name":"engine", "id":"YW678", "parts":[]}], []]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="put" prefix="map" diff="add" at="R-bug24726">
      <fos:signatures>
         <fos:proto name="put" return-type="map(*)">
            <fos:arg name="map" type="map(*)" usage="inspection"/>
            <fos:arg name="key" type="xs:anyAtomicType"/>
            <fos:arg name="value" type="item()*" usage="navigation"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns a map containing all the contents of the supplied map, but with an additional entry, which replaces
         any existing entry for the same key.</p>
      </fos:summary>
      <fos:rules>
         <p>The function <code>map:put</code> returns <phrase diff="chg" at="C">a <termref def="dt-map"
            >map</termref> that</phrase> contains all entries from the supplied <code>$map</code>,
            with the exception of any entry whose key is the <termref def="dt-same-key">same key</termref> as <code>$key</code>, together with a new
         entry whose key is <code>$key</code> and whose associated value is <code>$value</code>.</p>
         
         <p>The effect of the function call <code>map:put($MAP, $KEY, $VALUE)</code> is equivalent
         to the result of the following steps:</p>
         
         <olist>
            <item>
               <p><code>let $MAP2 := map:remove($MAP, $KEY)</code></p>
               <p>This returns a map in which all entries with the same key as <code>$KEY</code> have been removed.</p>
            </item>
            <item>
               <p>Construct and return a map containing:</p>
               <olist>
                  <item><p>All the entries (key/value pairs) in <code>$MAP2</code>, and</p></item>
                  <item><p>The entry <code>map:entry($KEY, $VALUE)</code></p></item>
               </olist>
            </item>
         </olist>
       
      </fos:rules>
      
      <fos:notes>
         <p>There is no requirement that the type of <code>$key</code> and <code>$value</code> be consistent with the types
         of any existing keys and values in the supplied map.</p>
         
      </fos:notes>

      <fos:examples>
         <fos:variable name="week"  id="v-map-put-week"
            select="map{0:&quot;Sonntag&quot;, 1:&quot;Montag&quot;, 2:&quot;Dienstag&quot;,&#xa;       3:&quot;Mittwoch&quot;, 4:&quot;Donnerstag&quot;, 5:&quot;Freitag&quot;, 6:&quot;Samstag&quot;}"/>
         <fos:example>
            <fos:test use="v-map-put-week">
               <fos:expression>map:put($week, 6, "Sonnabend")</fos:expression>
               <fos:result>map{0:"Sonntag", 1:"Montag", 2:"Dienstag", 3:"Mittwoch", 4:"Donnerstag",
                  5:"Freitag", 6:"Sonnabend"}</fos:result>
            </fos:test>
            <fos:test use="v-map-put-week">
               <fos:expression>map:put($week, -1, "Unbekannt")</fos:expression>
               <fos:result>map{0:"Sonntag", 1:"Montag", 2:"Dienstag", 3:"Mittwoch", 4:"Donnerstag",
                  5:"Freitag", 6:"Samstag", -1:"Unbekannt"}</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="entry" prefix="map" diff="add" at="MAP">
      <fos:signatures>
         <fos:proto name="entry" return-type="map(*)">
            <fos:arg name="key" type="xs:anyAtomicType"/>
            <fos:arg name="value" type="item()*" usage="navigation"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p><phrase diff="chg" at="C">Returns</phrase> a map that contains a single entry (a key-value pair).</p>
      </fos:summary>
      <fos:rules>
         <p>The function <code>map:entry</code> returns a <termref def="dt-map"
               >map</termref> which <phrase diff="del" at="P">normally</phrase> contains a single
            entry. <phrase diff="del" at="N">The collation of the new map is the default collation
               from the static context. </phrase>The key of the entry in the new map is
               <code>$key</code>, and its associated value is <code>$value</code>.</p>

         <p diff="del" at="N">If the supplied key is the <code>xs:float</code> or
               <code>xs:double</code> value <code>NaN</code>, the supplied <code>$map</code> is
            empty (that is, it contains no entries).</p>

         <p diff="del" at="N">If the supplied key is <code>xs:untypedAtomic</code>, it is converted
            to <code>xs:string</code>.</p>
      </fos:rules>
      <fos:notes>
         <p>The function call <code>map:entry(K, V)</code> produces the same result as the
         expression <code>map{K : V}</code>.</p>
         <p>The function <code>map:entry</code> is intended primarily for use in conjunction with
            the function <code>map:merge</code>. For example, a map containing seven entries may be
            constructed like this:</p>

         <eg><![CDATA[
map:merge((
   map:entry("Su", "Sunday"),
   map:entry("Mo", "Monday"),
   map:entry("Tu", "Tuesday"),
   map:entry("We", "Wednesday"),
   map:entry("Th", "Thursday"),
   map:entry("Fr", "Friday"),
   map:entry("Sa", "Saturday")
   ))]]></eg>
         <p>The <code>map:merge</code> function can be used to construct
            a map with a variable number of entries, for example:</p>
         <eg><![CDATA[
map:merge(for $b in //book return map:entry($b/isbn, $b))]]></eg>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>map:entry("M", "Monday")</fos:expression>
               <fos:result>map{"M":"Monday"}</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="remove" prefix="map" diff="add" at="MAP">
      <fos:signatures>
         <fos:proto name="remove" return-type="map(*)">
            <fos:arg name="map" type="map(*)" usage="inspection"/>
            <fos:arg name="keys" type="xs:anyAtomicType*"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p diff="chg" at="C">Returns a map containing all the entries from a supplied map, except <phrase diff="chg" at="E">those having a specified key</phrase>.</p>
      </fos:summary>
      <fos:rules>
         <p>The function <code>map:remove</code> returns a <termref def="dt-map"
               >map</termref> containing all the entries in <code>$map</code> except for any entry whose key is 
            the <termref def="dt-same-key">same key</termref> as <phrase diff="chg" at="E">an item in</phrase> <code>$keys</code>.</p>
         <p>No failure occurs <phrase diff="chg" at="E">if an item in <code>$keys</code> does not correspond to any entry in <code>$map</code>;
            that key value is simply ignored</phrase>.</p>
         <p>The effect of the function call <code>map:remove($MAP, $KEY)</code> can be described more formally as the result of the expression below:</p>
         
         <eg><![CDATA[
map:merge (
    map:for-each (
       $MAP, function($k, $v) { 
               if (some $key in $KEY satisfies (op:same-key($k, $key)) 
               then () 
               else map:entry($k, $v)
             } ) ) ]]></eg>
      </fos:rules>
      
      <fos:examples>
         <fos:variable name="week"  id="v-map-remove-week"
            select="map{0:&quot;Sonntag&quot;, 1:&quot;Montag&quot;, 2:&quot;Dienstag&quot;,&#xa;       3:&quot;Mittwoch&quot;, 4:&quot;Donnerstag&quot;, 5:&quot;Freitag&quot;, 6:&quot;Samstag&quot;}"/>
         <fos:example>
            <fos:test use="v-map-remove-week">
               <fos:expression>map:remove($week, 4)</fos:expression>
               <fos:result>map{0:"Sonntag", 1:"Montag", 2:"Dienstag", 3:"Mittwoch", 5:"Freitag",
                  6:"Samstag"}</fos:result>
            </fos:test>
            <fos:test use="v-map-remove-week">
               <fos:expression>map:remove($week, 23)</fos:expression>
               <fos:result>map{0:"Sonntag", 1:"Montag", 2:"Dienstag", 3:"Mittwoch", 4:"Donnerstag",
                  5:"Freitag", 6:"Samstag"}</fos:result>
            </fos:test>
            <fos:test use="v-map-remove-week">
               <fos:expression>map:remove($week, (0, 6 to 7))</fos:expression>
               <fos:result>map{1:"Montag", 2:"Dienstag", 3:"Mittwoch", 4:"Donnerstag", 5:"Freitag"}</fos:result>
            </fos:test>        
            <fos:test use="v-map-remove-week">
               <fos:expression>map:remove($week, ())</fos:expression>
               <fos:result>map{0:"Sonntag", 1:"Montag", 2:"Dienstag", 3:"Mittwoch", 4:"Donnerstag", 5:"Freitag",
                  6:"Samstag"}</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="for-each" prefix="map" diff="chg" at="B">
      <fos:signatures>
         <fos:proto name="for-each" return-type="item()*">
            <fos:arg name="map" type="map(*)" usage="inspection"/>
            <fos:arg name="action" type="function(xs:anyAtomicType, item()*) as item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>nondeterministic-wrt-ordering</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Applies a supplied function to every entry in a map, returning the concatenation of the
            results.</p>
      </fos:summary>
      <fos:rules>
         <p>The function <code>map:for-each</code> takes any <termref def="dt-map"
               >map</termref> as its <code>$map</code> argument and applies the supplied function
            to each entry in the map, in <termref def="dt-implementation-dependent"
               >implementation-dependent</termref> order; the result is the sequence obtained by
            concatenating the results of these function calls.</p>
         <p diff="add" at="D">The function is <term>non-deterministic with respect to ordering</term>
            (see <specref ref="properties-of-functions"/>). This means that two calls with the same arguments
            are not guaranteed to process the map entries in the same order.</p>
         <p>The function supplied as <code>$action</code> takes two arguments. It is called
            supplying the key of the map entry as the first argument, and the associated value as
            the second argument.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>map:for-each(map{1:"yes", 2:"no"}, function($k,
                  $v){$k})</fos:expression>
               <fos:result allow-permutation="true">(1,2)</fos:result>
               <fos:postamble>This function call is equivalent to calling <code>map:keys</code>. The
                  result is in implementation-dependent order.</fos:postamble>
            </fos:test>
            <fos:test>
               <fos:expression>distinct-values(map:for-each(map{1:"yes", 2:"no"}, function($k,
                  $v){$v}))</fos:expression>
               <fos:result allow-permutation="true">("yes", "no")</fos:result>
               <fos:postamble>This function call returns the distinct values present in the map, in
                  implementation-dependent order.</fos:postamble>
            </fos:test>
            <fos:test>
               <fos:expression>map:merge(map:for-each(map{"a":1, "b":2}, function($k,
                  $v){map:entry($k, $v+1)}))</fos:expression>
               <fos:result>map{"a":2, "b":3}</fos:result>
               <fos:postamble>This function call returns a map with the same keys as the input map,
                  with the value of each entry increased by one.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>

               <p>This XQuery example converts the entries in a map to attributes on a newly constructed
                  element node:</p>
               
               <eg><![CDATA[
let $dimensions := map{'height': 3, 'width': 4, 'depth': 5};
return
  <box>{
     map:for-each($dimensions, function ($k, $v) { attribute {$k} {$v} })
  }</box>]]></eg>

               <p>The result is the element <code>&lt;box height="3" width="4"
                  depth="5"/></code>.</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   <fos:function name="size" prefix="map" diff="add" at="MAP">
      <fos:signatures>
         <fos:proto name="size" return-type="xs:integer">
            <fos:arg name="map" type="map(*)" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the number of entries in the supplied map.</p>
      </fos:summary>
      <fos:rules>
         <p>The function <code>map:size</code> takes any <termref def="dt-map">map</termref>
            as its <code>$map</code> argument and returns the number of entries that are present
            in the map.</p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>map:size(map{})</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>map:size(map{"true":1, "false":0})</fos:expression>
               <fos:result>2</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>



   <fos:function name="collation-key" prefix="fn" diff="add" at="A">
      <fos:signatures>
         <fos:proto name="collation-key" return-type="xs:base64Binary">
            <fos:arg name="key" type="xs:string"/>
         </fos:proto>
         <fos:proto name="collation-key" return-type="xs:base64Binary">
            <fos:arg name="key" type="xs:string"/>
            <fos:arg name="collation" type="xs:string"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p diff="chg" at="B-bug25446">Given a string value and a collation, generates an internal value called a collation key, with the property that
            the matching and ordering of collation keys reflects the matching and ordering of strings under the specified collation.</p>
      </fos:summary>
      <fos:rules>
         <p>Calling the one-argument version of this function is equivalent to calling the
            two-argument version supplying the default collation as the second argument.</p>
         <p>The function returns an <phrase diff="add" at="B-bug25446"><termref def="implementation-dependent">implementation-dependent</termref></phrase> 
            value with the property that,
            for any two strings <code>$K1</code> and <code>$K2</code>:</p>
            <ulist>
               <item><p><code>collation-key($K1, $C) eq collation-key($K2, $C)</code> if and only if
                  <code>compare($K1, $K2, $C) eq 0</code></p></item>
               <item diff="add" at="B-bug25446"><p><code>collation-key($K1, $C) lt collation-key($K2, $C)</code> if and only if
                  <code>compare($K1, $K2, $C) lt 0</code></p></item>
            </ulist>
            
         <p diff="add" at="E">The collation used by this function is determined according to the rules in <specref
            ref="choosing-a-collation"/>. Collation keys are defined as <code>xs:base64Binary</code> values
            to ensure unambiguous and context-free comparison semantics.</p>
         <p>An implementation is free to generate a collation key in any convenient way provided
            that it always generates the same collation key for two strings that are equal under the
            collation, and different collation keys for strings that are not equal. This holds only
            within a single <termref ref="execution-scope">execution scope</termref>;
            an implementation is under no obligation to generate the same collation keys during a
            subsequent unrelated query or transformation.</p>
         <p>It is possible to define collations that do not have the ability to generate collation
            keys. Supplying such a collation will cause the function to fail. The ability to
            generate collation keys is an <termref def="implementation-defined">implementation-defined</termref> property of the
            collation.</p>
      </fos:rules>
      <fos:errors>
         <p>An error is raised <errorref class="CH" code="0004"/> if the specified
            collation does not support the generation of collation keys. </p>
      </fos:errors>
      <fos:notes>
         <p>The function is provided primarily for use with maps. If a map is required where
            codepoint equality is inappropriate for comparing keys, then a common technique is to
            normalize the key so that equality matching becomes feasible. There are many ways
            keys can be normalized, for example by use of functions such as
               <code>fn:upper-case</code>, <code>fn:lower-case</code>,
               <code>fn:normalize-space</code>, or <code>fn:normalize-unicode</code>, but this
            function provides a way of normalizing them according to the rules of a specified
            collation. For example, if the collation ignores accents, then the function will
            generate the same collation key for two input strings that differ only in their use of
            accents.</p>
         <p diff="add" at="E">The result of the function is defined to be an <code>xs:base64Binary</code> value. Binary values
         are chosen because they have unambiguous and context-free comparison semantics, because the value space
         is unbounded, and because the ordering rules are such that between any two values in the ordered value space, an
         arbitrary number of further values can be interpolated. The choice between <code>xs:base64Binary</code>
            and <code>xs:hexBinary</code> is arbitrary; the only operation that behaves differently between the two binary
            data types is conversion to/from a string, and this operation is not one that is normally required for
            effective use of collation keys.
         </p>
         <p>For collations based on the Unicode Collation Algorithm, an algorithm for computing
            collation keys is provided in <bibref ref="UNICODE-TR10"/>. Implementations are
               <rfc2119>not required</rfc2119> to use this algorithm.</p>
         <p diff="del" at="B-bug25446">This specification does not mandate that collation keys should retain ordering. This is
            partly because the primary use case is for maps, where only equality comparisons are
            required, and partly to allow the use of binary data types (which are currently
            unordered types) for the result. The specification may be revised in a future release to
            specify that ordering is preserved.</p>
         <p diff="add" at="B-bug25446">The fact that collation keys are ordered can be exploited in XQuery, whose <code>order by</code>
         clause does not allow the collation to be selected dynamically. This restriction can be circumvented
         by rewriting the clause <code>order by $e/@key collation "URI"</code> as <code>order by fn:collation-key($e/@key, $collation)</code>,
         where <code>$collation</code> allows the collation to be chosen dynamically.</p>
         <p diff="add" at="B-bug25446">Note that <code>xs:base64Binary</code> becomes an ordered type
         in XPath 3.1, making binary collation keys possible.</p>

      </fos:notes>
      <fos:examples>
         <fos:variable name="C" id="v-collation-key-C" select="'http://www.w3.org/2013/collation/UCA?strength=primary'"/>
         <fos:example>
            <fos:test use="v-collation-key-C">
               <fos:expression>map:merge((map{collation-key("A", $C):1}, map{collation-key("a",
                  $C):2}), map{"duplicates":"use-last"})(collation-key("A", $C))</fos:expression>
               <fos:result>2</fos:result>
               <fos:postamble>Given that the keys of the two entries are equal under the rules of
                  the chosen collation, only one of the entries can appear in the result; the one
                  that is chosen is the one from the last map in the input sequence.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <fos:test use="v-collation-key-C">
               <fos:expression>let $M := map{collation-key("A", $C):1, collation-key("B", $C):2}
                  return $M(collation-key("a", $C))</fos:expression>
               <fos:result>1</fos:result>
               <fos:postamble>The strings "A" and "a" have the same collation key under this
                  collation.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>As the above examples illustrate, it is important that when the
                  <code>collation-key</code> function is used to add entries to a map, then it must
               also be used when retrieving entries from the map. This process can be made less
               error-prone by encapsulating the map within a function: <code>function($k)
                  {$M(collation-key($k, $collation)}</code>.</p>
         </fos:example>
      </fos:examples>
   </fos:function>
   
     <fos:function name="json-to-xml" prefix="fn">
      <fos:signatures>
         <fos:proto name="json-to-xml" return-type="document-node()?">
            <fos:arg name="json-text" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="json-to-xml" return-type="document-node()?">
            <fos:arg name="json-text" type="xs:string?"/>
            <fos:arg name="options" type="map(*)" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>nondeterministic</fos:property>
         <fos:property dependency="static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Parses a string supplied in the form of a JSON text, returning the results in the form
            of an XML <phrase diff="chg" at="P">document node</phrase>.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the one-argument form of this function is the same as calling the
            two-argument form with an empty map as the value of the <code>$options</code>
            argument.</p>

         <p>The first argument is a JSON-text as defined in <bibref ref="rfc7159"/>, in the form of a string. The function
            parses this string to return an XDM node.</p>
         
         <p>If <code>$json-text</code> is an empty sequence, the function returns the empty sequence.</p>

         <p diff="chg" at="D">The <code>$options</code> argument can be used to control the way in which the parsing
            takes place. The <termref def="option-parameter-conventions">option parameter conventions</termref> apply.</p>

         <p>The entries that may appear in the <code>$options</code> map are as follows:</p>
         
         <fos:options>
            <fos:option key="liberal">
               <fos:meaning>Determines whether deviations from the syntax of RFC7159 are permitted.</fos:meaning>
               <fos:type>xs:boolean</fos:type>
               <fos:default>false</fos:default>
               <fos:values>
                  <fos:value value="false">
                     The input <rfc2119>must</rfc2119> consist of <phrase diff="add" at="D">an optional byte order mark (which is ignored) followed by</phrase> a string
                     that conforms to the grammar of <code>JSON-text</code> in <bibref ref="rfc7159"/>. An error <rfc2119>must</rfc2119> be raised
                     (see below) if the input does not conform to the grammar.
                  </fos:value>
                  <fos:value value="true">
                     The input <rfc2119>may</rfc2119> contain deviations from the grammar of <bibref ref="rfc7159"/>,
                     which are handled in an <termref def="implementation-defined">implementation-defined</termref> way. (Note: some popular
                     extensions include allowing quotes on keys to be omitted, allowing a comma
                     to appear after the last item in an array, allowing leading zeroes in numbers, and allowing control characters such as
                     tab and newline to be present in unescaped form.) Since the extensions accepted
                     are implementation-defined, an error <rfc2119>may</rfc2119> be raised
                     (see below) if the input does not conform to the grammar.
                  </fos:value>
               </fos:values>
            </fos:option>
            <fos:option key="duplicates">
               <fos:meaning>Determines the policy for handling duplicate keys in a JSON object.
                  To determine whether keys are duplicates, they are compared using the Unicode codepoint collation, after expanding escape
                  sequences, unless the <phrase diff="chg" at="D"><code>escape</code> option is set to <code>true</code></phrase>, in which
                  case keys are compared in escaped form. 
               </fos:meaning>
               <fos:type>xs:string</fos:type>
               <fos:default>If <code>validate</code> is <code>true</code> then <code>reject</code>, otherwise <code>retain</code>.</fos:default>
               <fos:values>
                  <fos:value value="reject">
                     An error is raised <errorref class="JS" code="0003"/> if duplicate keys are encountered.
                  </fos:value>
                  <fos:value value="use-first">
                     If duplicate keys are present in a JSON object, all but the first of a set of duplicates are ignored.
                  </fos:value>
                  <fos:value value="retain">
                     If duplicate keys are present in a JSON object, the XML result of the function will also contain duplicates (making
                     it invalid against the schema). This value is therefore incompatible with the option <code>validate=true</code> 
                     <errorref class="JS" code="0005"/>
                  </fos:value>
               </fos:values>
            </fos:option>
            
            <fos:option key="validate">
               <fos:meaning>Determines whether the generated XML tree is schema-validated.</fos:meaning>
               <fos:type>xs:boolean</fos:type>
               <fos:default><termref def="dt-implementation-defined">Implementation-defined</termref>.</fos:default>
               <fos:values>
                  <fos:value value="true">
                     Indicates that the resulting XDM instance must be typed; that is, the element
                     and attribute nodes must carry the type annotations that result from validation
                     against the schema given at <specref ref="schema-for-json"/>, or against an
                     <termref def="dt-implementation-defined">implementation-defined</termref> schema 
                     if the <code>liberal</code> option has the value <code>true</code>.
                  </fos:value>
                  <fos:value value="false">
                     Indicates that the resulting XDM instance must be untyped.
                  </fos:value>
               </fos:values>
            </fos:option>
            
            <fos:option key="escape">
               <fos:meaning>Determines whether special characters are represented in the XDM output 
                  in backslash-escaped form. </fos:meaning>
               <fos:type>xs:boolean</fos:type>
               <fos:default>false</fos:default>
               <fos:values>
                  <fos:value value="false">
                     All characters in the input that are valid
                     in the version of XML supported by the implementation, whether or not they are represented 
                     in the input by means of an escape sequence, are represented as unescaped characters in the result. Any
                     characters or codepoints that are not valid XML characters 
                     (for example, unpaired surrogates) <phrase diff="add" at="D">are passed to the <code>fallback</code> function
                        as described below; in the absence of a fallback function, they are replaced by
                        the Unicode <code>REPLACEMENT CHARACTER</code> (<code>xFFFD</code>)</phrase>.
                     The attributes <code>escaped</code> and <code>escaped-key</code> will not be present in the XDM output.
                  </fos:value>
                  <fos:value value="true">
                     JSON escape sequences are used in the result to represent special characters in the JSON input, as defined below, 
                     whether or not they were represented using JSON escape sequences in the input.
                     The characters that are considered "special" for this purpose are:
                     <ulist>
                        <item><p>all codepoints in the range <code>x00</code> to <code>x1F</code> 
                           or <code>x7F</code> to <code>x9F</code>;</p></item>
                        <item><p>all codepoints that do not represent characters that are valid in the version of XML supported by the processor,
                           including codepoints representing unpaired surrogates;</p></item>
                        <item><p>the backslash character itself (<code>x5C</code>).</p></item>
                     </ulist>
                     
                     Such characters are represented using a two-character
                     escape sequence where available (for example, <code>\t</code>), or a six-character escape sequence otherwise
                     (for example <code>\uDEAD</code>). Characters other than these will not be escaped in the result,
                     even if they were escaped in the input. In the result:
                     
                     <ulist>
                        <item><p>Any <code>string</code> element whose string value contains a
                           backslash character must have the attribute value <code>escaped="true"</code>.</p></item>
                        <item><p>Any element that contains a <code>key</code> attribute whose string value
                           contains a backslash character must have the attribute
                           <code>escaped-key="true"</code>.</p></item>
                        <item><p>The values of the <code>escaped</code> and
                           <code>escaped-key</code> attributes are immaterial when there is no backslash
                           present, and it is never necessary to include either attribute when its value
                           is <code>false</code>.</p></item>
                     </ulist>
                  </fos:value>
               </fos:values>
            </fos:option>
            
            <fos:option key="fallback">
               <fos:meaning>
                  Provides a function which is called when the input contains an escape sequence 
                  that represents a character that is not valid in the version of XML
                  supported by the implementation. 
                  
                  It is an error to supply the <code>fallback</code> option if the <code>escape</code> option is present
                  with the value <code>true</code>.
               </fos:meaning>
               <fos:type>function(xs:string) as xs:string</fos:type>
               <fos:default>The default is effectively the function <code>function($s){"&amp;#xFFFD;"}</code>: that is,
                  a function that replaces the escape sequence with the Unicode <code>REPLACEMENT CHARACTER</code>.</fos:default>
               <fos:values>
                  <fos:value value="User-supplied function">
                     The function is called when the JSON input contains an escape sequence that is valid according to the JSON 
                     grammar, but which does not represent a character that is valid in the version of XML supported
                     by the processor. In the case of surrogates, the function is called once for any six-character escape sequence
                     that is not properly paired with another surrogate. The string supplied 
                     as the argument will always be a two- or six- character escape
                     sequence, starting with a backslash, that conforms to the rules in the JSON grammar (as extended by the
                     implementation if <code>liberal:true()</code> is specified): for example
                     <code>\b</code> or <code>\uFFFF</code> or <code>\uDEAD</code>. The function is <emph>not</emph>
                     called for an escape sequence that is invalid against the grammar (for example <code>\x0A</code>). 
                     The function returns a string
                     which is inserted into the result in place of the invalid character. The
                     function also has the option of raising a dynamic error by calling <code>fn:error</code>.
                  </fos:value>
               </fos:values>
            </fos:option>
         </fos:options>

         <p>The various structures that can occur in JSON are transformed recursively to XDM values
            according to the rules given in <specref ref="json-to-xml-mapping"/>.</p>

         <p>The function returns a document node, whose only child
               is the element node representing the outermost construct in the JSON
            text.</p>

         <p>The function is <termref ref="dt-nondeterministic"
               >non-deterministic with respect to node identity</termref>: that is, if the function is called twice with the same
            arguments, it is <termref def="implementation-dependent"
               >implementation-dependent</termref> whether the same node is returned on both
            occasions.</p>

         <p>The base URI of the returned document node is taken from the static base URI of the
            function call.</p>
         
         <p>The choice of namespace prefix (or absence of a prefix) in the names of constructed
         nodes is <termref def="implementation-dependant">implementation-dependant</termref>.</p>
         
         <p>The XDM tree returned by the function does not contain any
         unnecessary (albeit valid) nodes such as whitespace text nodes, comments, or processing instructions.
         It does not include any whitespace in the value of <code>number</code> or <code>boolean</code> 
            element nodes, <phrase diff="add" at="D">or in the value of <code>escaped</code> or <code>escaped-key</code>
         attribute nodes.</phrase></p>
         
         
         <p diff="add" at="D">If the result is typed, every element named <code>string</code> will have an attribute named 
            <code>escaped</code> whose value is either <code>true</code> or <code>false</code>, and every element having 
            an attribute named <code>key</code> will also have an attribute named <code>escaped-key</code> whose value is either 
            <code>true</code> or <code>false</code>.
         </p>
         <p diff="add" at="D">If the result is untyped, the attributes <code>escaped</code> and <code>escaped-key</code> will 
            either be present with the value <code>true</code>, or will be absent. They will never be present with the value <code>false</code>.</p>
         
      </fos:rules>
      <fos:errors>
         
         <p>An error is raised <errorref spec="FO" class="JS" code="0001"/> if the value of
            <code>$input</code> does not conform to the JSON grammar as defined
            by <bibref ref="rfc7159"/>, unless the option <code>"liberal":true()</code> is present and
            the processor chooses to accept the deviation. </p>
         
         <p>An error is raised <errorref spec="FO" class="JS" code="0004"/> if the value of
            the <code>validate</code> option is <code>true</code> and the processor does not support
            schema validation or typed data.</p>
         
         <p>An error is raised <errorref spec="FO" class="JS" code="0005"/> if the value of
            <code>$options</code> includes an entry whose key is defined in this specification,
               and whose value is not a permitted value for that key.</p>


      </fos:errors>
      <fos:notes>
         <p>To read a JSON file, this function can be used in conjunction with the
               <code>fn:unparsed-text</code> function.</p>
         <p>Many JSON implementations allow commas to be used after the last item in an object or
            array, although the specification does not permit it. The option
               <code>spec="liberal"</code> is provided to allow such deviations from the
            specification to be accepted. Some JSON implementations also allow constructors such as
               <code>new Date("2000-12-13")</code> to appear as values: specifying
               <code>spec="liberal"</code> allows such extensions to be accepted, but does not
            guarantee it. If such extensions are accepted, the resulting value is
            implementation-defined, and will not necessarily conform to the schema at <specref
               ref="schema-for-json"/>.</p>
         <p>If the input starts with a byte order mark, this function ignores it. The byte order mark may have been added
            to the data stream in order to facilitate decoding of an octet stream to a character string, but since this function
            takes a character string as input, the byte order mark serves no useful purpose.</p>
         <p>The possibility of the input containing characters that are not valid in XML (for example, unpaired surrogates)
         arises only when such characters are expressed using JSON escape sequences. The is because the input to the function
         is an instance of <code>xs:string</code>, which by definition can only contain characters that are valid in XML.</p>
         
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>json-to-xml('{"x": 1, "y": [3,4,5]}')</fos:expression>
               <fos:result normalize-space="true" ignore-prefixes="true"><![CDATA[
<map xmlns="http://www.w3.org/2005/xpath-functions">
  <number key="x">1</number>
  <array key="y">
   <number>3</number>
   <number>4</number>
   <number>5</number>
  </array>
</map>]]></fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>json-to-xml('"abcd"', map{'liberal': false()})</fos:expression>
               <fos:result ignore-prefixes="true"><![CDATA[<string xmlns="http://www.w3.org/2005/xpath-functions">abcd</string>]]></fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>json-to-xml('{"x": "\\", "y": "\u0025"}')</fos:expression>
               <fos:result normalize-space="true" ignore-prefixes="true"><![CDATA[
<map xmlns="http://www.w3.org/2005/xpath-functions">
  <string key="x">\</string>
  <string key="y">%</string>
</map>]]></fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>json-to-xml('{"x": "\\", "y": "\u0025"}', map{'escape':
                  true()})</fos:expression>
               <fos:result normalize-space="true" ignore-prefixes="true"><![CDATA[
<map xmlns="http://www.w3.org/2005/xpath-functions">
  <string escaped="true" key="x">\\</string>
  <string key="y">%</string>
</map>]]></fos:result>
               <fos:postamble>But see the detailed rules for alternative values of the <code>escaped</code> attribute
                  on the second <code>string</code> element.</fos:postamble>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>The following example illustrates use of the <code>fallback</code> function to
               handle characters that are invalid in XML.</p>
            <eg diff="add" at="D"><![CDATA[
 let 
   $jsonstr := unparsed-text('http://example.com/endpoint'),
   $options := map {
     'liberal': true(),
     'fallback': function($char as xs:string) as xs:string {
       let 
         $c0chars := map {
           '\u0000':'[NUL]',
           '\u0001':'[SOH]',
           '\u0002':'[STX]',
           ...
           '\u001E':'[RS]',
           '\u001F':'[US]'
         },
         $replacement := $c0chars($char)
      return 
        if (exists($replacement))
        then $replacement
        else error(xs:QName('err:invalid-char'), 
          'Error: ' || $char || ' is not a C0 control character.')
     }
   }
 return json-to-xml($jsonstr, $options)]]></eg>
         </fos:example>
      </fos:examples>
   </fos:function>
   
<fos:function name="xml-to-json" prefix="fn" diff="add" at="D">
      <fos:signatures>
         <fos:proto name="xml-to-json" return-type="xs:string?">
            <fos:arg name="input" type="node()?" usage="absorption"/>
         </fos:proto>
         <fos:proto name="xml-to-json" return-type="xs:string?">
            <fos:arg name="input" type="node()?" usage="absorption"/>
            <fos:arg name="options" type="map(*)" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Converts an XML tree, whose format corresponds to the XML representation of JSON defined
            in this specification, into a string conforming to the JSON grammar.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the one-argument form of this function is the same as calling the
            two-argument form with an empty map as the value of the <code>$options</code>
            argument.</p>

         <p>The first argument <code>$input</code> is a node; the subtree rooted at this node will typically be
            the XML representation of a JSON document as defined in <specref ref="json-to-xml-mapping"/>.</p>
         
         <p>If <code>$input</code> is the empty sequence, the function returns the empty sequence.</p>

         <p diff="chg" at="D">The <code>$options</code> argument can be used to control the way in which the conversion
            takes place. The <termref def="option-parameter-conventions">option parameter conventions</termref> apply.</p>

         <p>The entries that may appear in the <code>$options</code> map are as follows:</p>
         
         <fos:options>
            <fos:option key="indent">
               <fos:meaning>Determines whether additional whitespace should be added to the output to improve readability.</fos:meaning>
               <fos:type>xs:boolean</fos:type>
               <fos:default>false</fos:default>
               <fos:values>
                  <fos:value value="false">
                     The processor must not insert any insignificant whitespace between JSON tokens.
                  </fos:value>
                  <fos:value value="true">
                     The processor <rfc2119>may</rfc2119> insert whitespace between JSON tokens in order to improve readability.
                     The specification imposes no constraints on how this is done.
                  </fos:value>
               </fos:values>
            </fos:option>
         </fos:options>

         <!--<table border="1" cellpadding="1" summary="options for the xml-to-json function">
            <thead>
               <tr>
                  <th>Key</th>
                  <th>Value</th>
                  <th>Meaning</th>
               </tr>
            </thead>
            <tbody>
               <tr>
                  <td rowspan="3">
                     <code>indent</code>
                  </td>
                  <td colspan="2">Determines whether additional whitespace should be added to the output to improve readability. 
                     The required type is <code>xs:boolean</code>.</td>
               </tr>
               <tr>
                  <td>
                     <code>false</code> (default)
                  </td>
                  <td>The processor must not insert any insignificant whitespace between JSON tokens.</td>
               </tr>
               <tr>
                  <td>
                     <code>true</code>
                  </td>
                  <td>The processor <rfc2119>may</rfc2119> insert whitespace between JSON tokens in order to improve readability.
                  The specification imposes no constraints on how this is done.</td>
               </tr>
               

            </tbody>
         </table>-->
         
         <p>The node supplied as <code>$input</code> must be one of the following: <errorref spec="FO" class="JS" code="0006"/></p>
         
         <olist diff="chg" at="E">
            <item><p>An element node whose name matches the name of a global element declaration in the schema given in 
               <specref ref="schema-for-json"/> ("the schema") and that is valid as defined below:</p>
               <olist>
                  <item><p>If the type annotation of the element matches the type of the relevant element declaration 
                     in the schema (indicating that the element has been validated against the schema), then the element 
                     is considered valid.
                  </p></item>
                  <item><p>Otherwise, the processor <rfc2119>may</rfc2119> attempt to validate the element against
                     the schema, in which case it is treated as valid if and only if the outcome of validation is
                     <term>valid</term>.
                  </p></item>
                  <item><p>Otherwise (if the processor does not attempt validation using the schema), 
                     the processor <rfc2119>must</rfc2119> ensure that the content of the element, 
                     after stripping all attributes (at any depth) in namespaces other than 
                     <code>http://www.w3.org/2005/xpath-functions</code>, is such that validation 
                     against the schema would have an outcome of <term>valid</term>.
                  </p>
                     <note><p>The process described here is not precisely equivalent to schema validation. 
                        For example, schema validation will fail if there is an invalid <code>xsi:type</code> 
                        or <code>xsi:nil</code> attribute, whereas this process will ignore such attributes.
                     </p></note></item>
               </olist>
            
            </item>
            
            <item><p>An element node <var>E</var> having a <code>key</code> attribute and/or an <code>escaped-key</code> attribute 
               provided that <var>E</var> would satisfy one of the above
            conditions if the <code>key</code> and/or <code>escaped-key</code> attributes were removed.</p>
            
            </item>
            
            <item><p>A document node having exactly one element child and no text node children, 
               where the element child satisfies one of the conditions above.</p></item>
         </olist>
         
  
         
         <p diff="add" at="E"><!--bug 29588-->Furthermore, <code>$input</code> must satisfy the following constraint
            (which cannot be conveniently expressed in the schema). Every element <var>M</var> that is a descendant-or-self of 
            <code>$input</code> and has local name <code>map</code> and namespace URI <code>http://www.w3.org/2005/xpath-functions</code>
            must satisfy the following rule: there must not be two distinct children of <var>M</var> (say <var>C/1</var> and <var>C/2</var>) 
            such that the normalized key of <var>C/1</var> is equal to the normalized key of <var>C/2</var>. The normalized key 
            of an element <var>C</var> is as follows:</p>
         
         <ulist diff="add" at="E">
            <item><p>If <var>C</var> has the attribute value <code>escaped-key="true"</code>, then the value of the 
               <code>key</code> attribute of <var>C</var>, with all JSON escape sequences replaced by the corresponding Unicode characters 
               according to the JSON escaping rules.
            </p></item>
            <item><p>Otherwise (the <code>escaped-key</code> attribute of <var>C</var> is absent or set to false), 
               the value of the <code>key</code> attribute of <var>C</var>.</p></item>
         </ulist>
         
         <p>Nodes in the input tree are handled by applying the following rules, recursively. In these rules the term
            "an element named <var>N</var>" means "an element node whose local name is <var>N</var> and whose namespace URI is 
            <code>http://www.w3.org/2005/xpath-functions</code>".</p>
         
         <olist>
            <item><p>A document node having a single element node child is processed by processing that child.</p></item>
            <item><p>An element named <code>null</code> results in the output <code>null</code>.</p></item>
            <item><p>An element <code>$E</code> named <code>boolean</code> results in the output <code>true</code> or <code>false</code>
            depending on the result of <phrase diff="chg" at="D"><code>xs:boolean(fn:string($E))</code></phrase>.</p></item>
            <item><p>An element <code>$E</code> named <code>number</code> results in the output of the string 
               <phrase diff="chg" at="D">result of <code>xs:string(xs:double(fn:string($E)))</code></phrase>
            </p>
            </item>
            <item><p>An element named <code>string</code> results in the output of the string value of the element, enclosed in
            quotation marks, with any special characters in the string escaped as described below.</p></item>
            <item><p>An element named <code>array</code> results in the output of the children of the <code>array</code> element, 
               each processed by applying these rules recursively: the items in the resulting list are enclosed between square brackets, 
               and separated by commas.</p></item>
            <item><p>An element named <code>map</code> results in the output of a sequence of map entries corresponding to 
               the children of the <code>map</code> element, enclosed between curly braces and separated by commas. 
               Each entry comprises the value of the <code>key</code> attribute of the child element, enclosed in quotation marks 
               and escaped as described below, followed by a colon, followed by the result of processing the child element 
               by applying these rules recursively.</p>
            </item>
            <item><p>Comments, processing instructions, and whitespace text node children of <code>map</code> and <code>array</code>
               are ignored.</p></item>
            
         </olist>
         
         <p>Strings are escaped as follows:</p>
         
         <olist>
            <item><p>If the attribute <code>escaped="true"</code> is present for a string value, or <code>escaped-key="true"</code> for a key value, then:</p>
         
            <olist>
               <item><p>any valid JSON escape sequence present in the string is copied unchanged to the output;</p></item>
         
               <item><p>any invalid JSON escape sequence results in a dynamic error <errorref spec="FO" class="JS" code="0007"/>;</p></item>
         
               <item><p>any unescaped occurrence of quotation mark, backspace, form-feed, newline, carriage return, tab, <phrase diff="add" at="E">or solidus</phrase> is replaced by
                  <code>\"</code>, <code>\b</code>, <code>\f</code>, <code>\n</code>, <code>\r</code>, <code>\t</code>, <phrase diff="add" at="E">or <code>\/</code></phrase> respectively; </p></item>
         
               <item><p>any other codepoint in the range 1-31 or 127-159 is replaced by an escape in the form \uHHHH where HHHH 
                  is the upper-case hexadecimal representation of the codepoint value.</p></item>
            </olist>
         </item>
         <item><p>Otherwise (that is, in the absence of the attribute <code>escaped="true"</code> for a string value, 
            or <code>escaped-key="true"</code> for a key value):</p>
         
            <olist>
            <item><p>any occurrence of backslash is replaced by <code>\\</code></p></item>
         
            <item><p>any occurrence of quotation mark, backspace, form-feed, newline, carriage return, or tab is 
               replaced by <code>\"</code>, <code>\b</code>, <code>\f</code>, <code>\n</code>, <code>\r</code>, or <code>\t</code> respectively; </p></item>
         
            <item><p>any other codepoint in the range 1-31 or 127-159 is replaced by an escape in 
            the form <code>\uHHHH</code> where <code>HHHH</code> is the upper-case hexadecimal representation of the codepoint value.</p></item>
         </olist>
         </item>
         </olist>

      </fos:rules>
      <fos:errors>
         
         <p>A dynamic error is raised <errorref spec="FO" class="JS" code="0005"/> if the value of
            <code>$options</code> includes an entry whose key is defined in this specification, 
            and whose value is not a permitted value for that key.</p>
         
         <p>A dynamic error is raised <errorref spec="FO" class="JS" code="0006"/> if the value of
            <code>$input</code> is not a document or element node or is not valid according to the schema for the XML representation of
            JSON<phrase diff="add" at="E">, or if a <code>map</code> element has two children whose normalized key values are the same.</phrase></p>
         
         <p>A dynamic error is raised <errorref spec="FO" class="JS" code="0007"/> if the value of
            <code>$input</code> includes a string labeled with <code>escaped="true"</code>, or
            a key labeled with <code>escaped-key="true"</code>, where the content of the string or key
            contains an invalid JSON escape sequence: specifically, where it contains a backslash (<code>\</code>) that is not followed by one
            of the characters <code>"</code>, <code>\</code>, <code>/</code>, <code>b</code>, <code>f</code>, <code>n</code>, 
            <code>r</code>, <code>t</code>, or <code>u</code>, or where it contains the characters <code>\u</code>
            not followed by four hexadecimal digits (that is <code>[0-9A-Fa-f]{4}</code>).
        </p>

      </fos:errors>
   <fos:notes>
      <p>The rule requiring schema validity has a number of consequences, including the following:</p>
      <olist>
         <item><p>The input cannot contain no-namespace attributes, or attributes in the namespace <code>http://www.w3.org/2005/xpath-functions</code>,
            except where explicitly allowed by the schema. Attributes in other namespaces, however, are ignored.</p></item>
         <item><p>Nodes that do not affect schema validity, such as comments, processing instructions, namespace nodes, and whitespace text node
            children of <code>map</code> and <code>array</code>, are ignored.</p></item>
         <item><p>Numeric values are restricted to those that are valid in JSON: 
            the schema disallows positive and negative infinity and NaN.</p></item>
         <item><p>Duplicate key values are not permitted. <phrase diff="add" at="E">Most cases of duplicate keys are prevented by the rules in the schema; 
            additional cases (where the keys are equal only after expanding JSON escape sequences) are prevented by the prose rules 
            of this function. For example, the key values <code>\n</code> and <code>\u000A</code> are treated as duplicates even though
            the rules in the schema do not treat them as such.</phrase></p></item>
      </olist>
      <p>The rule allowing the top-level element to have a <code>key</code> attribute (which is ignored)
         allows any element in the output of the <code>fn:json-to-xml</code> function
         to be processed: for example, it is possible to take a JSON document, convert it to XML, select
         a subtree based on the value of a <code>key</code> attribute, and then convert this subtree
         back to JSON, perhaps after a transformation. The rule means that an element with the appropriate name will be 
            accepted if it has been validated against one of the 
            types <code>mapWithinMapType</code>, <code>arrayWithinMapType</code>, <code>stringWithinMapType</code>, 
            <code>numberWithinMapType</code>, <code>booleanWithinMapType</code>, or <code>nullWithinMapType</code>.</p>
   </fos:notes>
   <fos:examples>
      <fos:example>
         <p>The input <code><![CDATA[<array xmlns="http://www.w3.org/2005/xpath-functions"><number>1</number><string>is</string><boolean>1</boolean></array>]]></code>
         produces the result <code>[1,"is",true]</code>.</p>
      </fos:example>
      <fos:example>
         <p>The input <code><![CDATA[<map xmlns="http://www.w3.org/2005/xpath-functions"><number key="Sunday">1</number><number key="Monday">2</number></map>]]></code>
            produces the result <code>{"Sunday":1,"Monday":2}</code>.</p>
      </fos:example>
   </fos:examples>
</fos:function>

   <fos:function name="parse-json" prefix="fn">
      <fos:signatures>
         <fos:proto name="parse-json" return-type="item()?">
            <fos:arg name="json-text" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="parse-json" return-type="item()?">
            <fos:arg name="json-text" type="xs:string?"/>
            <fos:arg name="options" type="map(*)" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Parses a string supplied in the form of a JSON text, returning the results typically in the form
            of a map or array.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the one-argument form of this function is the same as calling the
            two-argument form with an empty map as the value of the <code>$options</code>
            argument.</p>

         <p>The first argument is a JSON text as defined in <bibref ref="rfc7159"/>, in the form of a string. The function
            parses this string to return an XDM value.</p>
         
         <p diff="add" at="B">If the value of <code>$json-text</code> is the empty sequence, the function returns the empty sequence.</p>
         
         <note diff="add" at="B"><p>The result will also be an empty sequence if <code>$json-text</code> is the string <code>"null"</code>.</p></note>

         <p diff="chg" at="D">The <code>$options</code> argument can be used to control the way in which the parsing
            takes place. The <termref def="option-parameter-conventions">option parameter conventions</termref> apply.</p>
         
         <p>The entries that may appear in the <code>$options</code> map are as follows:</p>
         
         <fos:options>
            <fos:option key="liberal">
               <fos:meaning>Determines whether deviations from the syntax of RFC7159 are permitted.</fos:meaning>
               <fos:type>xs:boolean</fos:type>
               <fos:default>false</fos:default>
               <fos:values>
                  <fos:value value="false">
                     The input <rfc2119>must</rfc2119> consist of <phrase diff="add" at="D">an optional byte order mark (which is ignored) followed by</phrase> a string
                     that conforms to the grammar of <code>JSON-text</code> in <bibref ref="rfc7159"/>. An error <rfc2119>must</rfc2119> be raised
                     <errorref class="JS" code="0001"/> if the input does not conform to the grammar.
                  </fos:value>
                  <fos:value value="true">
                     The input <rfc2119>may</rfc2119> contain deviations from the grammar of <bibref ref="rfc7159"/>,
                     which are handled in an <termref def="implementation-defined">implementation-defined</termref> way. (Note: some popular
                     extensions include allowing quotes on keys to be omitted, allowing a comma
                     to appear after the last item in an array, allowing leading zeroes in numbers, and allowing control characters such as
                     tab and newline to be present in unescaped form.) Since the extensions accepted
                     are implementation-defined, an error <rfc2119>may</rfc2119> be raised
                     <errorref class="JS" code="0001"/> if the input does not conform to the grammar.
                  </fos:value>
               </fos:values>
            </fos:option>
            <fos:option key="duplicates">
               <fos:meaning>Determines the policy for handling duplicate keys in a JSON object.
                  To determine whether keys are duplicates, they are compared using the Unicode codepoint collation, after expanding escape
                  sequences, unless the <phrase diff="chg" at="D"><code>escape</code> option is set to <code>true</code></phrase>, in which
                  case keys are compared in escaped form. 
               </fos:meaning>
               <fos:type>xs:string</fos:type>
               <fos:default>use-first</fos:default>
               <fos:values>
                  <fos:value value="reject">
                     An error is raised <errorref class="JS" code="0003"/> if duplicate keys are encountered.
                  </fos:value>
                  <fos:value value="use-first">
                     If duplicate keys are present in a JSON object, all but the first of a set of duplicates are ignored.
                  </fos:value>
                  <fos:value value="use-last">
                     If duplicate keys are present in a JSON object, all but the last of a set of duplicates are ignored.
                  </fos:value>
               </fos:values>
            </fos:option>

            <fos:option key="escape">
               <fos:meaning>Determines whether special characters are represented in the XDM output in backslash-escaped form.</fos:meaning>
               <fos:type>xs:boolean</fos:type>
               <fos:default>true</fos:default>
               <fos:values>
                  <fos:value value="false">
                     All characters in the input that are valid
                     in the version of XML supported by the implementation, whether or not they are represented 
                     in the input by means of an escape sequence, are represented as unescaped characters in the result. Any
                     characters or codepoints that are not valid XML characters 
                     (for example, unpaired surrogates) <phrase diff="add" at="D">are passed to the <code>fallback</code> function
                        as described below; in the absence of a fallback function, they are replaced by
                        the Unicode <code>REPLACEMENT CHARACTER</code> (<code>xFFFD</code>)</phrase>.
                  </fos:value>
                  <fos:value value="true">
                     JSON escape sequences are used in the result to represent special characters in the JSON input, as defined below, 
                     whether or not they were represented using JSON escape sequences in the input.
                     The characters that are considered "special" for this purpose are:
                     <ulist>
                        <item><p>all codepoints in the range <code>x00</code> to <code>x1F</code> 
                           or <code>x7F</code> to <code>x9F</code>;</p></item>
                        <item><p>all codepoints that do not represent characters that are valid in the version of XML supported by the processor,
                           including codepoints representing unpaired surrogates;</p></item>
                        <item><p>the backslash character itself (<code>x5C</code>).</p></item>
                     </ulist>
                     
                     Such characters are represented using a two-character
                     escape sequence where available (for example, <code>\t</code>), or a six-character escape sequence otherwise
                     (for example <code>\uDEAD</code>). Characters other than these are not escaped in the result, even if they
                     were escaped in the input.
                  </fos:value>
               </fos:values>
            </fos:option>
            <fos:option key="fallback">
               <fos:meaning>
                  Provides a function which is called when the input contains an escape sequence 
                  that represents a character that is not valid in the version of XML
                  supported by the implementation. 
                  
                  It is an error to supply the <code>fallback</code> option if the <code>escape</code> option is present
                  with the value <code>true</code>.
               </fos:meaning>
               <fos:type>function(xs:string) as xs:string</fos:type>
               <fos:default>The default is effectively the function <code>function($s){"&amp;#xFFFD;"}</code>: that is,
                  a function that replaces the escape sequence with the Unicode <code>REPLACEMENT CHARACTER</code>.</fos:default>
               <fos:values>
                  <fos:value value="User-supplied function">
                     The function is called when the JSON input contains a special character (as defined under 
                     the <code>escape</code> option) that is valid according to the JSON 
                     grammar, whether the special character is represented in the input directly or as an escape sequence. 
                     The function is called once for any surrogate
                     that is not properly paired with another surrogate. The string supplied as the argument will always be a two- or six- character escape
                     sequence, starting with a backslash, that conforms to the rules in the JSON grammar (as extended by the
                     implementation if <code>liberal:true()</code> is specified): for example
                     <code>\b</code> or <code>\uFFFF</code> or <code>\uDEAD</code>. The function is <emph>not</emph>
                     called for an escape sequence that is invalid against the grammar (for example <code>\x0A</code>). The function returns a string
                     which is inserted into the result in place of the invalid character. The
                     function also has the option of raising a dynamic error by calling <code>fn:error</code>.
                  </fos:value>
               </fos:values>
            </fos:option>
         </fos:options>
         
         <!--<table border="1" cellpadding="1" summary="options for the parse-json function">
            <thead>
               <tr>
                  <th>Key</th>
                  <th>Value</th>
                  <th>Meaning</th>
               </tr>
            </thead>
            <tbody>
               <tr>
                  <td rowspan="3">
                     <code>liberal</code>
                  </td>
                  <td colspan="2">Determines whether deviations from the syntax of RFC7159 are permitted. The required type is <code>xs:boolean</code>.</td>
               </tr>
               <tr>
                  <td>
                     <code>false</code> (default)
                  </td>
                  <td>The input <rfc2119>must</rfc2119> consist of <phrase diff="add" at="D">an optional byte order mark (which is ignored) followed by</phrase> a string
                     that conforms to the grammar of <code>JSON-text</code> in <bibref ref="rfc7159"/>. An error <rfc2119>must</rfc2119> be raised
                     <errorref class="JS" code="0001"/> if the input does not conform to the grammar.</td>
               </tr>
               <tr>
                  <td>
                     <code>true</code>
                  </td>
                  <td>The input <rfc2119>may</rfc2119> contain deviations from the grammar of <bibref ref="rfc7159"/>,
                     which are handled in an <termref def="implementation-defined">implementation-defined</termref> way. (Note: some popular
                  extensions include allowing quotes on keys to be omitted, allowing a comma
                  to appear after the last item in an array, allowing leading zeroes in numbers, and allowing control characters such as
                  tab and newline to be present in unescaped form.) Since the extensions accepted
                  are implementation-defined, an error <rfc2119>may</rfc2119> be raised
                     <errorref class="JS" code="0001"/> if the input does not conform to the grammar.</td>
               </tr>
               
               <tr>
                  <td rowspan="4">
                     <code>duplicates</code>
                  </td>
                  <td colspan="2">Determines the policy for handling duplicate keys in a JSON object.
                     The required type is <code>xs:string</code>.
                     Keys are compared using the Unicode codepoint collation, after expanding escape
                     sequences, unless the <phrase diff="chg" at="D"><code>escape</code> option is set to <code>true</code></phrase>, in which
                     case keys are compared in escaped form. </td>
               </tr>
               <tr>
                  <td>
                     <code>reject</code>
                  </td>
                  <td>An error is raised <errorref class="JS" code="0003"/> if duplicate keys are encountered.</td>
               </tr>
               <tr>
                  <td>
                     <code>use-first</code> (default)
                  </td>
                  <td>If duplicate keys are present in a JSON object, all but the first of a set of duplicates are ignored.</td>
               </tr>
               <tr>
                  <td>
                     <code>use-last</code>
                  </td>
                  <td>If duplicate keys are present in a JSON object, all but the last of a set of duplicates are ignored.</td>
               </tr>
               
               <tr>
                  <td rowspan="3">
                     <phrase diff="chg" at="D"><code>escape</code></phrase>
                  </td>
                  <td colspan="2" diff="chg" at="D">Determines whether special characters are represented in the XDM output in backslash-escaped form. 
                     The required type is <code>xs:boolean</code>.
                      </td>
               </tr>
               <tr>
                  <td>
                     <phrase diff="chg" at="D"><code>false</code></phrase> (default)
                  </td>
                  <td diff="chg" at="D">All characters in the input that are valid
                     in the version of XML supported by the implementation, whether or not they are represented 
                     in the input by means of an escape sequence, are represented as unescaped characters in the result. Any
                     characters or codepoints that are not valid XML characters 
                     (for example, unpaired surrogates) <phrase diff="add" at="D">are passed to the <code>fallback</code> function
                     as described below; in the absence of a fallback function, they are replaced by
                     the Unicode <code>REPLACEMENT CHARACTER</code> (<code>xFFFD</code>)</phrase>.</td>
               </tr>
               <tr>
                  <td>
                     <phrase diff="chg" at="D"><code>true</code></phrase>
                  </td>
                  <td>JSON escape sequences are used in the result to represent special characters in the JSON input, as defined below, 
                     whether or not they were represented using JSON escape sequences in the input.
                  The characters that are considered "special" for this purpose are:
                  <ulist>
                     <item><p>all codepoints in the range <code>x00</code> to <code>x1F</code> 
                     or <code>x7F</code> to <code>x9F</code>;</p></item>
                     <item><p>all codepoints that do not represent characters that are valid in the version of XML supported by the processor,
                        including codepoints representing unpaired surrogates;</p></item>
                     <item><p>the backslash character itself (<code>x5C</code>).</p></item>
                  </ulist>
                  
                  Such characters are represented using a two-character
                  escape sequence where available (for example, <code>\t</code>), or a six-character escape sequence otherwise
                  (for example <code>\uDEAD</code>). Characters other than these are not escaped in the result, even if they
                  were escaped in the input.</td>
               </tr>
               
               <tr>
                  <td rowspan="2" diff="add" at="D">
                     <code>fallback</code>
                  </td>
                  <td colspan="2" diff="add" at="D">Provides a function which is called when the input contains an escape sequence 
                     that represents a character that is not valid in the version of XML
                     supported by the implementation. The required type is <code>function(xs:string) as xs:string</code>.
                     The default is effectively the function <code>function($s){"&amp;#xFFFD;"}</code> is used: that is,
                     a function that replaces the escape sequence with the Unicode <code>REPLACEMENT CHARACTER</code>.
                     It is an error to supply the <code>fallback</code> option if the <code>escape</code> option is present
                     with the value <code>true</code>.
                  </td>
               </tr>
               <tr>
                  <td diff="add" at="D">Function with signature <code>function(xs:string) as xs:string</code></td>
                  <td diff="add" at="D">The function is called when the JSON input contains a special character (as defined under 
                     the <code>escape</code> option) that is valid according to the JSON 
                     grammar, whether the special character is represented in the input directly or as an escape sequence. 
                     The function is called once for any surrogate
                     that is not properly paired with another surrogate. The string supplied as the argument will always be a two- or six- character escape
                     sequence, starting with a backslash, that conforms to the rules in the JSON grammar (as extended by the
                     implementation if <code>liberal:true()</code> is specified): for example
                     <code>\b</code> or <code>\uFFFF</code> or <code>\uDEAD</code>. The function is <emph>not</emph>
                     called for an escape sequence that is invalid against the grammar (for example <code>\x0A</code>). The function returns a string
                     which is inserted into the result in place of the invalid character. The
                     function also has the option of raising a dynamic error by calling <code>fn:error</code>.</td>
               </tr>
               
               
               
            </tbody>
         </table>
 -->

         <p>The various structures that can occur in JSON are transformed recursively to XDM values
            as follows:</p>

         <olist>
            <item>
               <p>A JSON <emph>object</emph> is converted to a map. 
                  The entries in the map correspond to the key/value
                  pairs in the JSON object. The key is always of type <code>xs:string</code>; the
                  associated value may be of any type, and is the result of converting the JSON
                  value by recursive application of these rules. For example, the JSON text
                     <code>{"x":2, "y":5}</code> is transformed to the value <code>map{"x":2,
                     "y":5}</code>.</p>
               <p>If duplicate keys are encountered in a JSON <emph>object</emph>, they are handled
                  as determined by the <code>duplicates</code> option defined above.</p>
            </item>
            <item>
               <p>A JSON <emph>array</emph> is transformed to an array whose members are the result of converting
                  the corresponding member of the array by recursive application of these rules. For
                  example, the JSON text <code>["a", "b", null]</code> is transformed to the value
                     <code>["a", "b", ()]</code>.</p>
            </item>
            <item>
               <p>A JSON <emph>string</emph> is converted to an <code>xs:string</code> value. 
               <phrase diff="chg" at="E">The handling of special characters depends on the
               <code>escape</code> and <code>fallback</code> options, as described in the table above.</phrase></p>
            </item>
            <item>
               <p>A JSON <emph>number</emph> is converted to an <code>xs:double</code> value using
                  the rules for casting from <code>xs:string</code> to <code>xs:double</code>.</p>
            </item>
            <item>
               <p>The JSON <emph>boolean</emph> values <code>true</code> and <code>false</code> are
                  converted to the corresponding <code>xs:boolean</code> values.</p>
            </item>
            <item>
               <p>The JSON value <emph>null</emph> is converted to the empty sequence.</p>
            </item>
         </olist>


      </fos:rules>
      <fos:errors>
         <p>A dynamic error <errorref class="JS" code="0001"/> occurs if the value of
               <code>$input</code> does not conform to the JSON grammar, unless the option
            <code>"liberal":true()</code> is present and the processor chooses to accept the deviation.</p>
         
         <p>A dynamic error <errorref class="JS" code="0003"/> occurs if the option
            <code>"duplicates":"reject"</code> is present and the value of
            <code>$input</code> contains a JSON object with duplicate keys.</p>
         
         <p diff="add" at="D">A dynamic error <errorref class="JS" code="0005"/> occurs if the <code>$options</code>
            map contains an entry whose key is defined in this specification and whose value is not valid for that key,
         or if it contains an entry with the key <code>fallback</code> when the option <code>"escape":true()</code>
         is also present.</p>
      </fos:errors>
      <fos:notes>
         <p>The result of the function will be an instance of one of the following types. An
               <code>instance of</code> test (or in XQuery, <code>typeswitch</code>) can be used to
            distinguish them:</p>
         <ulist>
            <item>
               <p><code>map(xs:string, item()?)</code> for a JSON object</p>
            </item>
            <item>
               <p><code>array(item()?)</code> for a JSON array</p>
            </item>
            <item>
               <p><code>xs:string</code> for a JSON string</p>
            </item>
            <item>
               <p><code>xs:double</code> for a JSON number</p>
            </item>
            <item>
               <p><code>xs:boolean</code> for a JSON boolean</p>
            </item>
            <item>
               <p><code>empty-sequence()</code> for a JSON null (or for empty input)</p>
            </item>
         </ulist>
         <p>If the input starts with a byte order mark, this function ignores it. The byte order mark may have been added
         to the data stream in order to facilitate decoding of an octet stream to a character string, but since this function
         takes a character string as input, the byte order mark serves no useful purpose.</p>
         
         <p>The possibility of the input containing characters that are not valid in XML (for example, unpaired surrogates)
            arises only when such characters are expressed using JSON escape sequences. The is because the input to the function
            is an instance of <code>xs:string</code>, which by definition can only contain characters that are valid in XML.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>parse-json('{"x":1, "y":[3,4,5]}')</fos:expression>
               <fos:result>map{"x":1e0,"y":[3e0,4e0,5e0]}</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>parse-json('"abcd"')</fos:expression>
               <fos:result>"abcd"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>parse-json('{"x":"\\", "y":"\u0025"}')</fos:expression>
               <fos:result>map{"x":"\","y":"%"}</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>parse-json('{"x":"\\", "y":"\u0025"}', map{'escape':true()})</fos:expression>
               <fos:result>map{"x":"\\","y":"%"}</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>parse-json('{"x":"\\", "y":"\u0000"}')</fos:expression>
               <fos:result>map{"x":"\","y":codepoints-to-string(65533)}</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>parse-json('{"x":"\\", "y":"\u0000"}', map{'escape':true()})</fos:expression>
               <fos:result>map{"x":"\\","y":"\u0000"}</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>parse-json('{"x":"\\", "y":"\u0000"}', map{'fallback':function($s){'['||$s||']'}})</fos:expression>
               <fos:result>map{"x":"\","y":"[\u0000]"}</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="json-doc" prefix="fn">
      <fos:signatures>
         <fos:proto name="json-doc" return-type="item()?">
            <fos:arg name="href" type="xs:string?"/>
         </fos:proto>
         <fos:proto name="json-doc" return-type="item()?">
            <fos:arg name="href" type="xs:string?"/>
            <fos:arg name="options" type="map(*)" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property dependency="static-base-uri">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Reads an external resource containing JSON, and returns the result of parsing the resource as JSON.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the single-argument call <code>fn:json-doc($H)</code> is the same as the effect of the two-argument call
            <code>fn:json-doc($H, map{})</code> where an empty map is supplied as the second argument.</p>
         <p>The effect of the two-argument function call <code>fn:json-doc($H, $M)</code>is equivalent to the function composition
            <code>fn:unparsed-text($H) => fn:parse-json($M)</code>; except that:</p>
         
         <olist>
            <item><p diff="chg" at="B">The function <rfc2119>may</rfc2119> accept a resource in any encoding. <bibref ref="rfc7159"/> requires
               UTF-8, UTF-16, or UTF-32 to be accepted, but it is not an error if a different encoding is used. 
               Unless external encoding information is available, the function <rfc2119>must</rfc2119>
               assume that the encoding is one of UTF-8, UTF-16, or UTF-32, and <rfc2119>must</rfc2119> distinguish these cases by examination 
               of the initial octets of the resource.</p></item>
            <item><p diff="chg" at="E">If the resource contains characters that are not valid in the version of XML used by the processor,
            then rather than raising an error as <code>fn:unparsed-text#1</code> does, the function replaces such characters by the equivalent
            JSON escape sequence prior to parsing.</p>
               <note><p diff="add" at="E">Equivalently, the implementation can use some other internal representation of strings that allows non-XML characters to
            be manipulated.</p></note></item>
         </olist>
         
         <p diff="chg" at="B">If the value of <code>$href</code> is the empty sequence, the function returns the empty sequence.</p>
         
         
    
      </fos:rules>
      <fos:errors>
         <p>The function may raise any error defined for the <code>fn:unparsed-text</code> or <code>fn:parse-json</code>
         functions.</p>
      </fos:errors>
      <fos:notes>
         <p>If the input cannot be decoded (that is, converted into a sequence of Unicode codepoints, which may or may not represent characters),
            then a dynamic error occurs as with the <code>fn:unparsed-text</code> function.</p>
         <p>If the input can be decoded,
            then the possibility still arises that the resulting sequence of codepoints includes codepoints that do not represent characters that are valid in the
            version of XML that the processor supports. Such codepoints are translated into JSON escape sequences (for example, <code>\uFFFF</code>),
            and the JSON escape sequence is then passed to the fallback function specified in the <code>$options</code> argument, which in turn
            defaults to a function that returns the Unicode <code>REPLACEMENT CHARACTER</code> (<code>xFFFD</code>).</p>
      </fos:notes>
   </fos:function>


   <fos:function name="size" prefix="array">
      <fos:signatures>
         <fos:proto name="size" return-type="xs:integer">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the number of members in the supplied array.</p>
      </fos:summary>
      <fos:rules>
         <p>If <code>$array</code> is empty the function returns zero.</p>
         <p>Otherwise, the function returns the number of members in <code>$array</code>.</p>
      </fos:rules>
      <fos:notes>
         <p>Note that because an array is an item, the <code>fn:count</code> function when applied to an array always returns 1 (one).</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:size(["a", "b", "c"])</fos:expression>
               <fos:result>3</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:size(["a", ["b", "c"]])</fos:expression>
               <fos:result>2</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:size([ ])</fos:expression>
               <fos:result>0</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:size([[ ]])</fos:expression>
               <fos:result>1</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>

   <fos:function name="get" prefix="array">
      <fos:signatures>
         <fos:proto name="get" return-type="item()*">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
            <fos:arg name="position" type="xs:integer"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the value at the specified position in the supplied array (counting from 1).</p>
      </fos:summary>
      <fos:rules>
         <p>The result is the value of <code>$array($position)</code>.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error occurs <errorref class="AY" code="0001"/> if <code>$position</code> is not in the range <code>1 to
               array:size($array)</code> inclusive.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>["a", "b", "c"] => array:get(2)</fos:expression>
               <fos:result>"b"</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>["a", ["b", "c"]] => array:get(2)</fos:expression>
               <fos:result>["b", "c"]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="put" prefix="array" diff="add" at="E">
      <fos:signatures>
         <fos:proto name="put" return-type="array(*)">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
            <fos:arg name="position" type="xs:integer" usage="inspection"/>
            <fos:arg name="member" type="item()*" usage="navigation"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns an array containing all the members of a supplied array, except for one member which is replaced with a new value.</p>
      </fos:summary>
      <fos:rules>
         <p>The result is an array whose size is <code>array:size($array)</code>, in which all
            members in positions other than <code>$position</code> are the same as the members in the corresponding position
            of <code>$array</code>, and the member in position <code>$position</code> is <code>$member</code>.</p>
         <p>The result is equivalent to the result of the expression
            <code>$array => array:remove($position) => array:insert-before($position, $member)</code>.</p>
         
      </fos:rules>
      <fos:errors>
         <p>A dynamic error occurs <errorref class="AY" code="0001"/> if <code>$position</code> is not in the range <code>1 to
            array:size($array)</code> inclusive.</p>
         <p>This error will always occur if <code>$array</code> is empty.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:put(["a", "b", "c"], 2, "d")</fos:expression>
               <fos:result>["a", "d", "c"]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:put(["a", "b", "c"], 2, ("d", "e"))</fos:expression>
               <fos:result>["a", ("d", "e"), "c"]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:put(["a"], 1, ["d", "e"])</fos:expression>
               <fos:result>[["d", "e"]]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="append" prefix="array">
      <fos:signatures>
         <fos:proto name="append" return-type="array(*)">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
            <fos:arg name="appendage" type="item()*" usage="navigation"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns an array containing all the members of a supplied array, plus one additional member at the end.</p>
      </fos:summary>
      <fos:rules>
         <p>The result is an array whose size is <code>array:size($array) + 1</code>, in which all
            members in positions 1 to <code>array:size($array)</code> are the same as the members in the corresponding position
            of <code>$array</code>, and the member in position <code>array:size($array) + 1</code> is <code>$appendage</code>.</p>
         <p>The result is equivalent to the result of the expression
            <code>op:array-concat( $array, [$appendage] )</code>.</p>
         
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:append(["a", "b", "c"], "d")</fos:expression>
               <fos:result>["a", "b", "c", "d"]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:append(["a", "b", "c"], ("d", "e"))</fos:expression>
               <fos:result>["a", "b", "c", ("d", "e")]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:append(["a", "b", "c"], ["d", "e"])</fos:expression>
               <fos:result>["a", "b", "c", ["d", "e"]]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="join" prefix="array">
      <fos:signatures>
         <fos:proto name="join" return-type="array(*)">
            <fos:arg name="arrays" type="array(*)*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Concatenates the contents of several arrays into a single array.</p>
      </fos:summary>
      <fos:rules>
         <p>The function can be expressed as follows in XQuery:</p>
         <eg diff="chg" at='E'><code>
declare function array:join($arrays as array(*)*) as array(*) {
   if (fn:empty($arrays))
      then []
   else if (fn:count($arrays) eq 1)
      then $arrays
   else 
      op:array-concat(fn:head($arrays), array:join(fn:tail($arrays)))
};</code></eg>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:join(())</fos:expression>
               <fos:result>[ ]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:join([1, 2, 3])</fos:expression>
               <fos:result>[1, 2, 3]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:join((["a", "b"], ["c", "d"]))</fos:expression>
               <fos:result>["a", "b", "c", "d"]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:join((["a", "b"], ["c", "d"], [ ]))</fos:expression>
               <fos:result>["a", "b", "c", "d"]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:join((["a", "b"], ["c", "d"], [["e", "f"]]))</fos:expression>
               <fos:result>["a", "b", "c", "d", ["e", "f"]]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="subarray" prefix="array">
      <fos:signatures>
         <fos:proto name="subarray" return-type="array(*)">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
            <fos:arg name="start" type="xs:integer"/>
         </fos:proto>
         <fos:proto name="subarray" return-type="array(*)">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
            <fos:arg name="start" type="xs:integer"/>
            <fos:arg name="length" type="xs:integer"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns an array containing all members from a supplied array starting at a supplied
            position, up to a specified length.</p>
      </fos:summary>
      <fos:rules>
         <p><phrase diff="add" at="D">Except in error cases,</phrase> 
            the two-argument version of the function returns the same result as the three-argument
            version when called with <code>$length</code> equal to the value of <code>array:size($array) -
               $start + 1</code>.</p>
         <p>The result of the three-argument version of the function is given by the expression
               <code>array:join( ($start to $start + $length - 1) ! [$array(.)] )</code></p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="AY" code="0001"/> if <code>$start</code> is less than one
            <phrase diff="add" at="D">or greater than <code>array:size($array) + 1</code></phrase>.</p>
         <p diff="add" at="D">For the three-argument version of the function:</p>
         <ulist>
            <item><p>A dynamic error is raised <errorref class="AY" code="0002"/> 
               if <code>$length</code> is less than zero.</p></item>
            <item><p>A dynamic error is raised <errorref class="AY" code="0001"/> 
               if <code>$start + $length</code> is greater than <code>array:size($array) + 1</code>.</p></item>
         </ulist>
      </fos:errors>
      <fos:notes>
         <p>The value of <code>$start</code> can be equal to <code>array:size($array) + 1</code> provided that <code>$length</code>
         is either equal to zero or omitted. In this case the result will be an empty array.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:subarray(["a", "b", "c", "d"], 2)</fos:expression>
               <fos:result>["b", "c", "d"]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:subarray(["a", "b", "c", "d"], 5)</fos:expression>
               <fos:result>[ ]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:subarray(["a", "b", "c", "d"], 2, 0)</fos:expression>
               <fos:result>[ ]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:subarray(["a", "b", "c", "d"], 2, 1)</fos:expression>
               <fos:result>["b"]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:subarray(["a", "b", "c", "d"], 2, 2)</fos:expression>
               <fos:result>["b", "c"]</fos:result>
            </fos:test>          
            <fos:test>
               <fos:expression>array:subarray(["a", "b", "c", "d"], 5, 0)</fos:expression>
               <fos:result>[ ]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:subarray([ ], 1, 0)</fos:expression>
               <fos:result>[ ]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>

   <fos:function name="remove" prefix="array">
      <fos:signatures>
         <fos:proto name="remove" return-type="array(*)">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
            <fos:arg name="positions" type="xs:integer*"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns an array containing all the members of the supplied array, except for the <phrase diff="chg" at="E">members at specified positions</phrase>.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns an array of size <phrase diff="chg" at="E"><code>array:size($array) - fn:count(fn:distinct-values($positions))</code></phrase> 
            containing all members from <code>$array</code>
         <phrase diff="chg" at="E">except the members whose position (counting from 1) is present in the sequence <code>$positions</code>.
         The order of the remaining members is preserved.</phrase></p>
         <p>The result of the function, except in error cases, is given by the expression
            <code diff="chg" at="E">array:join(for $i in (1 to array:size($array))[not(. = $positions)] return [$array($i)])</code>
            </p>
      </fos:rules>
      <fos:errors>
         <p diff="chg" at="E">A dynamic error is raised <errorref class="AY" code="0001"/> if any integer in <code>$positions</code> is not in the range <code>1 to
         array:size($array)</code> inclusive. By implication, an error occurs if <code>$array</code> is empty, unless <code>$positions</code>
         is also empty.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:remove(["a", "b", "c", "d"], 1)</fos:expression>
               <fos:result>["b", "c", "d"]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:remove(["a", "b", "c", "d"], 2)</fos:expression>
               <fos:result>["a", "c", "d" ]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:remove(["a"], 1)</fos:expression>
               <fos:result>[ ]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:remove(["a", "b", "c", "d"], 1 to 3)</fos:expression>
               <fos:result>["d"]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:remove(["a", "b", "c", "d"], ())</fos:expression>
               <fos:result>["a", "b", "c", "d"]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="insert-before" prefix="array">
      <fos:signatures>
         <fos:proto name="insert-before" return-type="array(*)">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
            <fos:arg name="position" type="xs:integer"/>
            <fos:arg name="member" type="item()*" usage="navigation"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p diff="chg" at="C">Returns an array containing all the members of the supplied array, with one additional member at a specified position.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns an array of size <code>array:size($array) + 1</code> containing all members from <code>$array</code>
            whose position is less than <code>$position</code>, then a new member given by <code>$member</code>, and
            then all members from <code>$array</code> whose position is greater than or equal to <code>$position</code>. 
            Positions are counted from 1.</p>
         <p>The result is equivalent to the result of the expression
         <code>array:join( (array:subarray($array, 1, $position - 1), [$member], array:subarray($array, $position)) )</code></p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error occurs <errorref class="AY" code="0001"/> if <code>$position</code> is not in the range <code>1 to
            array:size($array) + 1</code> inclusive.</p>
      </fos:errors>
      <fos:notes>
         <p>Setting <code>$position</code> to 1 has the effect of prepending the new member at the start of the array. Setting <code>$position</code>
         to the value <code>array:size($array) + 1</code> delivers the same result as <code>array:append($array, $member)</code>.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:insert-before(["a", "b", "c", "d"], 3, ("x", "y"))</fos:expression>
               <fos:result>["a", "b", ("x", "y"), "c", "d"]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:insert-before(["a", "b", "c", "d"], 5, ("x", "y"))</fos:expression>
               <fos:result>["a", "b", "c", "d", ("x", "y")]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:insert-before(["a", "b", "c", "d"], 3, ["x", "y"])</fos:expression>
               <fos:result>["a", "b", ["x", "y"], "c", "d"]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   


   <fos:function name="head" prefix="array">
      <fos:signatures>
         <fos:proto name="head" return-type="item()*">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns the first member of an array, that is <code>$array(1)</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns first member of <code>$array</code>, that is the value of <code>$array(1)</code>.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error occurs <errorref class="AY" code="0001"/> if <code>$array</code> is empty.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:head([5, 6, 7, 8])</fos:expression>
               <fos:result>5</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:head([["a", "b"], ["c", "d"]])</fos:expression>
               <fos:result>["a", "b"]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:head([("a", "b"), ("c", "d")])</fos:expression>
               <fos:result>"a", "b"</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>

   <fos:function name="tail" prefix="array">
      <fos:signatures>
         <fos:proto name="tail" return-type="array(*)">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns an array containing all members except the first from a supplied array.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns an array containing all members of the supplied array except the first,
            that is <code>array:remove($array, 1)</code>.</p>
      </fos:rules>
      <fos:errors>
         <p>A dynamic error occurs <errorref class="AY" code="0001"/> if <code>$array</code> is empty.</p>
      </fos:errors>
      <fos:notes>
         <p>If the supplied array contains exactly one member, the result will be an empty array.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:tail([5, 6, 7, 8])</fos:expression>
               <fos:result>[6, 7, 8]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:tail([5])</fos:expression>
               <fos:result>[ ]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>

   <fos:function name="reverse" prefix="array">
      <fos:signatures>
         <fos:proto name="reverse" return-type="array(*)">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns an array containing all the members of a supplied array, but in reverse order.</p>
      </fos:summary>
      <fos:rules>
         <p>The function returns the result of the expression:
         <code>array:join( fn:reverse(1 to array:size($array)) ! [$array(.)] )</code></p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:reverse(["a", "b", "c", "d"])</fos:expression>
               <fos:result>["d", "c", "b", "a"]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:reverse([("a", "b"), ("c", "d")])</fos:expression>
               <fos:result>[("c", "d"), ("a", "b")]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:reverse([(1 to 5)])</fos:expression>
               <fos:result>[(1, 2, 3, 4, 5)]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:reverse([])</fos:expression>
               <fos:result>[]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>

   <fos:function name="for-each" prefix="array">
      <fos:signatures>
         <fos:proto name="for-each" return-type="array(*)">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
            <fos:arg name="action" type="function(item()*) as item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns an array whose size is the same as <code>array:size($array)</code>, in which
            each member is computed by applying <code>$function</code> to the corresponding member of
            <code>$array</code>.</p>
      </fos:summary>
      <fos:rules>
         <p>Returns the result of the expression:
         <code>array:join( (1 to array:size($array)) ! [ $action($array(.)) ] )</code></p>
      </fos:rules>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:for-each(["A", "B", 1, 2], function($z) {$z instance of xs:integer})</fos:expression>
               <fos:result>[false(), false(), true(), true()]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:for-each(["the cat", "sat", "on the mat"], fn:tokenize#1)</fos:expression>
               <fos:result>[("the", "cat"), "sat", ("on", "the", "mat")]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>

   <fos:function name="filter" prefix="array">
      <fos:signatures>
         <fos:proto name="filter" return-type="array(*)">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
            <fos:arg name="function" type="function(item()*) as xs:boolean" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns an array containing those members of the <code>$array</code> for which 
            <code>$function</code> returns true.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the function is equivalent to the following recursive definition:</p>
         <eg><![CDATA[
if (array:size($array) eq 0)
then [ ]
else op:array-concat(
        if ($function(array:head($array))) then array:head($array) else [ ],
        array:filter(array:tail($array))
     )
]]></eg>

      </fos:rules>
      <fos:errors>
         <p>As a consequence of the function signature and the function calling rules, a type error occurs if the supplied
            function <code>$function</code> returns anything other than a single <code>xs:boolean</code> item; there is no conversion 
            to an effective boolean value.</p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:filter(["A", "B", 1, 2], function($x) {$x instance of xs:integer})</fos:expression>
               <fos:result>[1, 2]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:filter(["the cat", "sat", "on the mat"], function($s){fn:count(fn:tokenize($s)) gt 1})</fos:expression>
               <fos:result>["the cat", "on the mat"]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:filter(["A", "B", "", 0, 1], boolean#1)</fos:expression>
               <fos:result>["A", "B", 1]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>

   <fos:function name="fold-left" prefix="array">
      <fos:signatures>
         <fos:proto name="fold-left" return-type="item()*">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
            <fos:arg name="zero" type="item()*" usage="navigation"/>
            <fos:arg name="function" type="function(item()*, item()*) as item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Evaluates the supplied function cumulatively on successive members of the supplied
            array.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the function is equivalent to the following recursive definition:</p>
         <eg diff="chg" at="F-bug30045">
if (array:size($array) eq 0)
then $zero
else array:fold-left(array:tail($array), 
                     $function($zero, array:head($array)), 
                     $function )
         </eg>
      </fos:rules>
      <fos:notes>
         <p>If the supplied array is empty, the function returns <code>$zero</code>.</p>
         <p>If the supplied array contains a single member <code>$m</code>, the function returns <code>$zero => $function($m)</code>.</p>
         <p>If the supplied array contains two members <code>$m</code> and <code>$n</code>, the function returns 
            <code>$zero => $function($m) => $function($n)</code>; and similarly for an input array with more than two members.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:fold-left([true(), true(), false()], true(), function($x, $y){$x and $y})</fos:expression>
               <fos:result>false()</fos:result>
               <fos:postamble>Returns true if every member of the input array has an effective boolean value of <code>true()</code>.</fos:postamble>
            </fos:test>
            <fos:test>
               <fos:expression>array:fold-left([true(), true(), false()], false(), function($x, $y){$x or $y})</fos:expression>
               <fos:result>true()</fos:result>
               <fos:postamble>Returns true if at least one member of the input array has an effective boolean value of <code>true()</code>.</fos:postamble>
            </fos:test>
            <fos:test>
               <fos:expression>array:fold-left([1,2,3], [], function($x, $y){[$x, $y]})</fos:expression>
               <fos:result>[[[[], 1], 2], 3]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>

   <fos:function name="fold-right" prefix="array">
      <fos:signatures>
         <fos:proto name="fold-right" return-type="item()*">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
            <fos:arg name="zero" type="item()*" usage="navigation"/>
            <fos:arg name="function" type="function(item()*, item()*) as item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Evaluates the supplied function cumulatively on successive values of the supplied
            array.</p>
      </fos:summary>
      <fos:rules>
         <p>The effect of the function is equivalent to the following recursive definition:</p>
         <eg diff="chg" at="F-bug30045">
if (array:size($array) eq 0)
then $zero
else $function( array:head($array), 
                array:fold-right(array:tail($array), $zero, $function) 
              )
         </eg>
      </fos:rules>
      <fos:notes>
         <p>If the supplied array is empty, the function returns <code>$zero</code>.</p>
         <p>If the supplied array contains a single member <code>$m</code>, the function returns <code>$function($m, $zero)</code>.</p>
         <p>If the supplied array contains two members <code>$m</code> and <code>$n</code>, the function returns 
            <code>$function($m, $function($n, $zero))</code>; and similarly for an input array with more than two members.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:fold-right([true(), true(), false()], true(), function($x, $y){$x and $y})</fos:expression>
               <fos:result>false()</fos:result>
               <fos:postamble>Returns true if every member of the input array has an effective boolean value of <code>true()</code>.</fos:postamble>
            </fos:test>
            <fos:test>
               <fos:expression>array:fold-right([true(), true(), false()], false(), function($x, $y){$x or $y})</fos:expression>
               <fos:result>true()</fos:result>
               <fos:postamble>Returns true if at least one member of the input array has an effective boolean value of <code>true()</code>.</fos:postamble>
            </fos:test>
            <fos:test>
               <fos:expression>array:fold-right([1,2,3], [], function($x, $y){[$x, $y]})</fos:expression>
               <fos:result>[1, [2, [3, []]]]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>

   <fos:function name="for-each-pair" prefix="array">
      <fos:signatures>
         <fos:proto name="for-each-pair" return-type="array(*)">
            <fos:arg name="array1" type="array(*)" usage="inspection"/>
            <fos:arg name="array2" type="array(*)" usage="inspection"/>
            <fos:arg name="function" type="function(item()*, item()*) as item()*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Returns an array obtained by evaluating the supplied function once for each pair of members at the same position in
            the two supplied arrays.</p>
      </fos:summary>
      <fos:rules>
         <p>Returns the result of the recursive expression:</p>
         <eg><code>
if (array:size($array1) eq 0 or array:size($array2) eq 0)
then [ ]
else array:concat(
        $function(array:head($array1), array:head($array2)), 
        array:for-each-pair(array:tail($array1), array:tail($array2), $function)
     )
         </code></eg>
      </fos:rules>
      <fos:notes>
         <p>If the arrays have different size, excess members in the longer array are ignored.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:for-each-pair(["A", "B", "C"], [1, 2, 3], function($x, $y) { array {$x, $y}})</fos:expression>
               <fos:result>[["A", 1], ["B", 2], ["C", 3]]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>let $A := ["A", "B", "C", "D"] return array:for-each-pair($A, array:tail($A), concat#2)</fos:expression>
               <fos:result>["AB", "BC", "CD"]</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="sort" prefix="array" diff="chg" at="E">
      <fos:signatures>
         <fos:proto name="sort" return-type="array(*)">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
         </fos:proto>
         <fos:proto name="sort" return-type="array(*)">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
            <fos:arg name="collation" type="xs:string?" usage="absorption"/>
         </fos:proto>
         <fos:proto name="sort" return-type="array(*)">
            <fos:arg name="array" type="array(*)" usage="inspection"/>
            <fos:arg name="collation" type="xs:string?" usage="absorption"/>
            <fos:arg name="key" type="function(item()*) as xs:anyAtomicType*" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties arity="1">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property dependency="collations">context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:properties arity="2">
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p diff="chg" at="C">Returns an array containing all the members of the supplied array, sorted 
            according to the value of a sort key supplied as a function.</p>
      </fos:summary>
      <fos:rules>
         <p>Calling the single-argument version of the function is equivalent to calling the two-argument form
            with <code>default-collation()</code> as the second argument: that is, it sorts the members of an array according
            to the typed value of the items, using the default collation to compare strings.</p>
         
         <p>Calling the two-argument version of the function is equivalent to calling the three-argument form
            with <code>fn:data#1</code> as the third argument: that is, it sorts the members of an array according
            to the typed value of the items, using a specified collation to compare strings.</p>
         
         <p>In the case of both <code>array:sort#2</code> and <code>array:sort#3</code>, supplying an empty
            sequence as the second argument is equivalent to supplying <code>fn:default-collation()</code>. For more
            information on collations see <specref ref="choosing-a-collation"/>.</p>
         
         <p>The result of the function is obtained as follows:</p>
         <ulist>
            <item><p>For each member of the array <code>$array</code>, the function supplied as <code>$key</code> 
               is evaluated with that member as its argument. 
               The resulting values are the sort keys of the members of the array.
            </p></item>
            <item><p>The result array contains the same members as the input array <code>$array</code>, but generally in a different order.</p></item>
            <item><p>Let <var>$C</var> be the selected collation, or the default collation where applicable.</p></item>
            <item><p>The order of items in the result is such that, given two items <code>$A</code> and <code>$B</code>:</p>
               <ulist>
                  <item><p>If <code>(fn:deep-equal($key($A), $key($B), $C)</code>, then the relative order of <code>$A</code> and <code>$B</code> 
                     in the output is the same as their relative order in the input (that is, the sort is stable)
                  </p></item>
                  <item><p>Otherwise, if <code>(deep-less-than($key($A), $key($B), $C)</code>, then <code>$A</code> precedes <code>$B</code> in the output. 
                     The function <code>deep-less-than</code> is defined as the boolean result of the expression:
                  </p>
                     <eg diff="chg" at="D"><code>if (fn:empty($A)) 
     then fn:exists($B)
else if (fn:deep-equal($A[1], $B[1], $C)) 
     then deep-less-than(fn:tail($A), fn:tail($B), $C)
else if ($A[1] ne $A[1] (:that is, $A[1] is NaN:)) 
     then fn:true()
else if (is-string($A[1]) and is-string($B[1]) 
     then fn:compare($A[1], $B[1], $C) lt 0
else $A[1] lt $B[1]</code></eg>          
                     <p>where the function <code>is-string($X)</code> returns true if and only if <code>$X</code> is an instance of 
                        <code>xs:string</code>, <code>xs:anyURI</code>, or <code>xs:untypedAtomic</code>.</p>
                     
                     
                     <p>This ordering of sequences is referred to by mathematicians as "lexicographic ordering".
                     </p>
                  </item>
               </ulist>
            </item>
         </ulist>
         
      </fos:rules>
      <fos:errors>
         <p>If the set of computed sort keys contains values that are not comparable using the <code>le</code> operator then the sort 
            operation will fail with a dynamic error.
         </p>
      </fos:errors>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:sort([1, 4, 6, 5, 3])</fos:expression>
               <fos:result>[1, 3, 4, 5, 6]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:sort([1, -2, 5, 10, -10, 10, 8], (), fn:abs#1)</fos:expression>
               <fos:result>[1, -2, 5, 8, 10, -10, 10]</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:sort([(1,0), (1,1), (0,1), (0,0)])</fos:expression>
               <fos:result>[(0,0), (0,1), (1,0), (1,1)]</fos:result>
            </fos:test>
         </fos:example>
         <fos:example>
            <p>To sort an array of strings <code>$in</code> using Swedish collation:</p>
            <eg>
let $SWEDISH := "http://www.w3.org/2013/collation/UCA?lang=se"
return array:sort($in, $SWEDISH)
            </eg>
         </fos:example>
         <fos:example>
            <p>To sort an array of maps representing employees, using last name as the major sort key and first name as the minor sort key,
               with the default collation:
            </p>
            <eg>array:sort($employees, (), function($emp) {$emp?name?last, $emp?name?first})</eg>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   <fos:function name="flatten" prefix="array" diff="add" at="C">
      <fos:signatures>
         <fos:proto name="flatten" return-type="item()*">
            <fos:arg name="input" type="item()*"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Replaces any array appearing in a supplied sequence with the members of the array, recursively.</p>
      </fos:summary>
      <fos:rules>
         <p>The function processes the items in the supplied sequence <code>$input</code> as follows:</p>
         <ulist>
            <item><p>An item that is an array is replaced by its members, retaining order.</p></item>
            <item><p>Any other item is retained unchanged.</p></item>
         </ulist>
         <p>The process is then repeated so long as the sequence contains an array among its items.</p>   
         <p>The function is equivalent to the following XQuery implementation (assuming static typing is not in force):</p>
                     <eg><code>declare function flatten ($S as item()*) {
    for $s in $S return (
      typeswitch($s)
        case $a as array(*) return flatten($a?*)
        default return $s
)}</code></eg>      
 
      </fos:rules>
      <fos:notes>
         <p>The argument to the function will often be a single array item, but this is not essential.</p>
         <p>Unlike atomization, this function retains any nodes contained in the array.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <fos:test>
               <fos:expression>array:flatten([1, 4, 6, 5, 3])</fos:expression>
               <fos:result>(1, 4, 6, 5, 3)</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:flatten(([1, 2, 5], [[10, 11], 12], [], 13))</fos:expression>
               <fos:result>(1, 2, 5, 10, 11, 12, 13)</fos:result>
            </fos:test>
            <fos:test>
               <fos:expression>array:flatten([(1,0), (1,1), (0,1), (0,0)])</fos:expression>
               <fos:result>(1, 0, 1, 1, 0, 1, 0, 0)</fos:result>
            </fos:test>
         </fos:example>
      </fos:examples>
   </fos:function>
   
   
   <fos:function name="load-xquery-module" prefix="fn">
      <fos:signatures>
         <fos:proto name="load-xquery-module" return-type="map(*)">
            <fos:arg name="module-uri" type="xs:string"/> 
         </fos:proto>
         <fos:proto name="load-xquery-module" return-type="map(*)">
            <fos:arg name="module-uri" type="xs:string"/>
            <fos:arg name="options" type="map(*)" usage="inspection"/>
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Provides access to the public functions and global variables of a dynamically-loaded XQuery library module.</p>
      </fos:summary>
      <fos:rules>
         <p>The function loads an implementation-defined set of modules having the target namespace <code>$module-uri</code>.</p>
         <p>Calling the one-argument version of the function has the same effect as calling the two-argument version with an empty map
            as the second argument.</p>
         <p diff="chg" at="D">The <code>$options</code> argument can be used to control the way in which the function operates. 
            The <termref def="option-parameter-conventions">option parameter conventions</termref> apply.</p>
         
         
         <fos:options>
            <fos:option key="xquery-version">
               <fos:meaning>The minimum level of the XQuery language that the
                  processor must support. </fos:meaning>
               <fos:type>xs:decimal</fos:type>
               <fos:default>The version given in the prolog of the library module; or
                  <termref def="dt-implementation-defined">implementation-defined</termref> if this is absent.</fos:default>
            </fos:option>
            <fos:option key="location-hints">
               <fos:meaning>A sequence of URIs (in the form of <code>xs:string</code> values) which may be used or ignored in an
                  <termref def="implementation-defined">implementation-defined</termref> way.</fos:meaning>
               <fos:type>xs:string*</fos:type>
               <fos:default>Empty sequence</fos:default>
            </fos:option>
            <fos:option key="context-item">
               <fos:meaning>The item to be used as the initial context item when evaluating global variables in the library module. Supplying
                  an empty sequence is equivalent to omitting the entry from the map, and indicates the absence of a context item.
                  If the library module specifies a required type for the context item, then the supplied value <rfc2119>must</rfc2119> conform to
                  this type, without conversion.</fos:meaning>
               <fos:type>item()?</fos:type>
               <fos:default>Absent</fos:default>
            </fos:option>
            <fos:option key="variables">
               <fos:meaning>Values for external variables defined in the library module. Values <rfc2119>must</rfc2119> be supplied
                  for external variables that have no default value, and <rfc2119>may</rfc2119> be supplied for external variables
                  that do have a default value. The supplied value <rfc2119>must</rfc2119> conform to the required type of the variable, without conversion.
                  The map contains one entry for each external variable: the key is the variable's name, and the associated value is
                  the variable's value. The <termref def="option-parameter-conventions">option parameter conventions</termref> do not apply
                  to this contained map.</fos:meaning>
               <fos:type>map(xs:QName, item()*)</fos:type>
               <fos:default>An empty map</fos:default>
            </fos:option>
            <fos:option key="vendor-options">
               <fos:meaning>Values for vendor-defined configuration options for the XQuery processor used to process the request. The key is the
                  name of an option, expressed as a QName: the namespace URI of the QName <rfc2119>should</rfc2119> be a URI controlled
                  by the vendor of the XQuery processor. The meaning of the associated value is <termref def="implementation-defined">implementation-defined</termref>.
                  Implementations <rfc2119>should</rfc2119> ignore options whose names are in an unrecognized namespace. 
                  The <termref def="option-parameter-conventions">option parameter conventions</termref> do not apply
                  to this contained map.</fos:meaning>
               <fos:type>map(xs:QName, item()*)</fos:type>
               <fos:default>An empty map</fos:default>
            </fos:option>
         </fos:options>
            
         <!--<table border="1" summary="Options for use in the second argument of the fn:load-query-module function">
               <thead>
                  <tr>
                     <th>Key</th>
                     <th>Required Type</th>
                     <th>Effect</th>
                  </tr>
               </thead>
               <tbody>
                  <tr>
                     <td valign="top"><code>xquery-version</code></td>
                     <td valign="top"><code>xs:decimal</code></td>
                     <td>The minimum level of the XQuery language that the
                        processor must support. Defaults to the version given in the prolog of the library module; or
                        <termref def="dt-implementation-defined">implementation-defined</termref> if this is absent.</td>
                  </tr>
                  <tr>
                     <td valign="top"><code>location-hints</code></td>
                     <td valign="top"><code>xs:string*</code></td>
                     <td valign="top">A sequence of URIs (in the form of <code>xs:string</code> values) which may be used or ignored in an
                     <termref def="implementation-defined">implementation-defined</termref> way.</td>
                  </tr>
                  <tr>
                     <td valign="top"><code>context-item</code></td>
                     <td valign="top"><code>item()?</code></td>
                     <td valign="top">The item to be used as the initial context item when evaluating global variables in the library module. Supplying
                     an empty sequence is equivalent to omitting the entry from the map, and indicates the absence of a context item.
                     If the library module specifies a required type for the context item, then the supplied value <rfc2119>must</rfc2119> conform to
                     this type, without conversion.</td>
                  </tr>
                  <tr>
                     <td valign="top"><code>variables</code></td>
                     <td valign="top"><code>map(xs:QName, item()*)</code></td>
                     <td valign="top">Values for external variables defined in the library module. Values <rfc2119>must</rfc2119> be supplied
                     for external variables that have no default value, and <rfc2119>may</rfc2119> be supplied for external variables
                     that do have a default value. The supplied value <rfc2119>must</rfc2119> conform to the required type of the variable, without conversion.
                     The map contains one entry for each external variable: the key is the variable's name, and the associated value is
                     the variable's value. The <termref def="option-parameter-conventions">option parameter conventions</termref> do not apply
                     to this contained map.</td>
                  </tr>
                  <tr>
                     <td valign="top"><code>vendor-options</code></td>
                     <td valign="top"><code>map(xs:QName, item()*)</code></td>
                     <td valign="top">Values for vendor-defined configuration options for the XQuery processor used to process the request. The key is the
                     name of an option, expressed as a QName: the namespace URI of the QName <rfc2119>should</rfc2119> be a URI controlled
                     by the vendor of the XQuery processor. The meaning of the associated value is <termref def="implementation-defined">implementation-defined</termref>.
                        Implementations <rfc2119>should</rfc2119> ignore options whose names are in an unrecognized namespace. 
                        The <termref def="option-parameter-conventions">option parameter conventions</termref> do not apply
                        to this contained map.</td>
                  </tr>
               </tbody>
            </table>-->
         <p>The result of the function is a map <var>R</var> with two entries:</p>
         <olist>
            <item><p>There is an entry whose key is the <code>xs:string</code> value <code>"variables"</code> and whose associated value
               is a map <var>V</var>. This map (<var>V</var>) contains one entry for each public global variable declared in the library module. 
               The key of the
            entry is the name of the variable, as an <code>xs:QName</code> value; the associated value is the value of the variable.</p></item>
            <item><p>There is an entry whose key is the <code>xs:string</code> value <code>"functions"</code> and whose associated value
               is a map <var>F</var>. This map (<var>F</var>) contains one entry for each public function declared in the library module, except that when two functions
               have the same name (but different arity), they share the same entry. The key of the
               entry is the name of the function(s), as an <code>xs:QName</code> value; the associated value is a map <var>A</var>.
               This map (<var>A</var>) contains one entry for each function with the given name; its key is the arity of the function,
               as an <code>xs:integer</code> value, and its associated value is the function itself, as a function item. The function
               can be invoked using the rules for dynamic function invocation.
            </p></item>
         </olist>
         
         <p>The static and dynamic context of the library module are established according to the rules in 
            <xspecref spec="XQ31" ref="id-xq-context-components"/>.</p>
         
         <p>It is <termref def="dt-implementation-defined">implementation-defined</termref> whether constructs in the library module 
            are evaluated in the same <termref def="execution-scope">execution scope</termref> as the calling module.</p>
         
         <p>The library module that is loaded may import other modules using an <code>import module</code> declaration. The result of
            <code>fn:load-xquery-module</code> does not include global variables or functions declared in such a transitively-imported module.
            However, the <code>options</code> map supplied in the function call <rfc2119>may</rfc2119> 
            (and if no default is defined, <rfc2119>must</rfc2119>)
            supply values for external variables declared in transitively-loaded library modules.</p>
         
         <p>The library module that is loaded may import schema declarations using an <code>import schema</code> declaration. It is
            <termref def="dt-implementation-defined">implementation-defined</termref> whether schema components in the in-scope 
            schema definitions of the calling module
            are automatically added to the in-scope schema definitions of the dynamically loaded module. The in-scope schema definitions
            of the calling and called modules must be consistent, according to the rules defined in 
            <xspecref spec="XQ31" ref="id-consistency-constraints"/>.</p>
         
         <p diff="chg" at="D">Where nodes are passed to or from the dynamically loaded module, for example as an argument or result of a function, 
            they <rfc2119>should</rfc2119> if possible retain their node identity, their base URI, their type annotations, and their relationships to all other nodes 
            in the containing tree (including ancestors and siblings). If this is not possible, for example because the only way of passing nodes 
            to the chosen XQuery implementation is by serializing and re-parsing, then a node <rfc2119>may</rfc2119> be passed in the form of a deep 
            copy, which may lose information about the identity of the node, about its ancestors and siblings, about its base URI, about its type annotations, and about its 
            relationships to other nodes passed across the interface.</p>
 
       
      </fos:rules>
      <fos:errors>
         <p>If <code>$module-uri</code> is a zero length string, a dynamic error is raised <errorref class="QM" code="0001"/>.</p>
         <p>If the implementation is not able to find a library module with the specified target namespace, 
            an error is raised <errorref class="QM" code="0002"/>.</p>
         <p>If a static error (including a statically-detected type error) is encountered when processing the library module, 
            a dynamic error is raised <errorref class="QM" code="0003"/>.</p>
         <p diff="del" at="E">If the imported module requires a value for the initial context item or for an external variable, and no value is supplied,
            an error is raised [FOQM0004]</p>
         <p>If a value is supplied for the initial context item or for an external variable and the value does not conform to the required
            type declared in the dynamically loaded module, a dynamic error is raised <errorref class="QM" code="0005"/>.</p>
         <p diff="add" at="D">If no suitable XQuery processor is available, a dynamic error is raised <errorref class="QM" code="0006"/>.
         This includes (but is not limited to) the following cases:</p>
         <olist diff="add" at="D">
            <item><p>No XQuery processor is available;</p></item>
            <item><p>Use of the function has been disabled;</p></item>
            <item><p>No XQuery processor supporting the requested version of XQuery is available;</p></item>
            <item><p>No XQuery processor supporting the optional Module Feature is available.</p></item>
         </olist>
         <p diff="del" at="E">If the supplied options are invalid according to the rules of the <termref def="option-parameter-conventions"/>, 
            a dynamic error is raised [FOQM0007].</p>
         <p>If a dynamic error (including a dynamically-detected type error) is encountered when processing the module 
            (for example, when evaluating its global variables), the dynamic error is returned <emph>as is</emph>.</p>
      </fos:errors>
      
      <fos:notes><p>As with all other functions in this specification, conformance requirements depend on the host language.
         For example, a host language might specify that provision of this function is optional, or that it is excluded entirely,
         or that implementations are required to support XQuery modules using a specified version of XQuery.</p>
      
      <p>Even where support for this function is mandatory, it is <rfc2119>recommended</rfc2119> for security reasons that implementations
         should provide a user option to disable its use, or to disable aspects of its functionality.</p>
      </fos:notes>
      
   </fos:function>
   
   <fos:function name="transform" prefix="fn">
      <fos:signatures>
         <fos:proto name="transform" return-type="map(*)">
            <fos:arg name="options" type="map(*)" usage="inspection"/> 
         </fos:proto>
      </fos:signatures>
      <fos:properties>
         <fos:property>nondeterministic</fos:property>
         <fos:property>context-dependent</fos:property>
         <fos:property>focus-independent</fos:property>
      </fos:properties>
      <fos:summary>
         <p>Invokes a transformation using a dynamically-loaded XSLT stylesheet.</p>
      </fos:summary>
      <fos:rules>
         <p>This function loads an XSLT stylesheet and invokes it to perform a transformation.</p>
         <p>The inputs to the transformation are supplied in the form of a map. 
            The <termref def="option-parameter-conventions">option parameter conventions</termref> apply
            to this map; they do not apply to any nested map unless otherwise specified.</p>
         
         <p>The function first identifies the <term>requested XSLT version</term>, as follows:</p> 
         
         <ulist>
            <item><p>If the <code>xslt-version</code>
               option is present, the requested XSLT version is the value of that option. </p></item>
            <item><p>Otherwise, the requested XSLT version
               is the value of the <code>[xsl:]version</code> attribute of the outermost element in the supplied stylesheet or package.</p></item>
         </ulist>
         
         <p>The function then attempts to locate an XSLT processor that implements the requested XSLT version.</p>
         
         <ulist>
            <item><p>If a processor that implements the requested XSLT version is available, then it is used. </p></item>
            <item><p>Otherwise, if a processor that implements a version later than the requested version is available, then it is used. </p></item>
            <item><p>Otherwise, the function fails indicating that no suitable XSLT processor is available.</p></item>
         </ulist>
         
         <note><p>The phrase <emph>locate an XSLT processor</emph> includes the possibility of locating a software product and
         configuring it to act as an XSLT processor that implements the requested XSLT version.</p></note>
         
         <p>If more than one XSLT processor is available under the above rules, then the one that is chosen may be selected according to
         the availability of requested features: see below.</p>
         
         <p>Once an XSLT processor has been selected that implements a given version of XSLT, the processor
         follows the rules of that version of the XSLT specification. This includes any decision to operate in backwards or forwards
         compatibility mode. For example, if an XSLT 2.0 processor is selected, and the stylesheet specifies <code>version="1.0"</code>,
         then the processor will operate in backwards compatibility mode; if the same processor is selected and the stylesheet
         specifies <code>version="3.0"</code>, the processor will operate in forwards compatibility mode.</p>
         
         <p>The combinations of options that are relevant to each version of XSLT, other than <code>xslt-version</code> 
            itself, are listed below. This is followed by a table giving the meaning of each option.</p>
         
  
         
         <olist>
            <item>
               <p>For invocation of an XSLT 1.0 processor (see <bibref ref="xslt10"/>), 
                  the supplied options must include all of the following <phrase duff="chg" at="E">(if anything else is present, it is ignored)</phrase>:</p>
               <olist>
                  <item><p>The stylesheet, provided by supplying exactly one of the following:</p>
                     <slist>
                        <sitem><code>stylesheet-location</code></sitem>
                        <sitem><code>stylesheet-node</code></sitem>
                        <sitem><code>stylesheet-text</code></sitem>
                     </slist>
                  </item>
                  <item><p>The source tree, provided as the value of the <code>source-node</code> option.</p></item>
                  <item>
                     <p>Zero or more of the following additional options:</p>
                     <slist>
                        <sitem><code>stylesheet-base-uri</code></sitem>
                        <sitem><code>stylesheet-params</code> (defaults to an empty map)</sitem>
                        <sitem><code>initial-mode</code> (defaults to the unnamed mode)</sitem>
                        <sitem><code>delivery-format</code> (defaults to <code>document</code>)</sitem>
                        <sitem><code>serialization-params</code> (defaults to an empty map)</sitem>
                        <sitem><code>enable-messages</code> (default is implementation-defined)</sitem>
                        <sitem><code>requested-properties</code> (default is an empty map)</sitem>
                        <sitem><code>vendor-options</code> (defaults to an empty map)</sitem>
                        <sitem><code>cache</code> (default is implementation-defined)</sitem>
                     </slist>
                  </item>
               </olist>           
            </item>
            <item>
               <p>For invocation of an XSLT 2.0 processor (see <bibref ref="xslt20"/>), 
                  the supplied options must include all of the following <phrase duff="chg" at="E">(if anything else is present, it is ignored)</phrase>:</p>
               <olist>
                  <item><p>The stylesheet, provided by supplying exactly one of the following:</p>
                     <slist>
                        <sitem><code>stylesheet-location</code></sitem>
                        <sitem><code>stylesheet-node</code></sitem>
                        <sitem><code>stylesheet-text</code></sitem>
                     </slist>
                  </item> 
                  <item><p>Invocation details, as exactly one of the following:</p>
                     <olist>
                        <item>
                           <p>For apply-templates invocation, all of the following:</p>
                           <p><code>source-node</code></p>
                           <p>Optionally, <code>initial-mode</code> (defaults to the unnamed mode)</p>
                        </item>
                        <item>
                           <p>For call-template invocation, all of the following:</p>
                           <p><code>initial-template</code></p>
                           <p>Optionally, <code>source-node</code></p>
                        </item>
                     </olist>
                  </item> 
                  <item>
                     <p>Zero or more of the following additional options:</p>
                     <slist>
                        <sitem><code>stylesheet-base-uri</code></sitem>
                        <sitem><code>stylesheet-params</code> (defaults to an empty map)</sitem>
                        <sitem><code>base-output-uri</code> (defaults to absent)</sitem>
                        <sitem><code>delivery-format</code> (defaults to <code>document</code>)</sitem>
                        <sitem><code>serialization-params</code> (defaults to an empty map)</sitem>
                        <sitem><code>enable-messages</code> (default is implementation-defined)</sitem>
                        <sitem><code>enable-trace</code> (default is implementation-defined)</sitem>
                        <sitem><code>requested-properties</code> (default is an empty map)</sitem>
                        <sitem><code>vendor-options</code> (defaults to an empty map)</sitem>
                        <sitem><code>cache</code> (default is implementation-defined)</sitem>
                     </slist>
                  </item>
               </olist>           
            </item>
            <item>
               <p>For invocation of an XSLT 3.0 processor (see <bibref ref="xslt-30"/>), 
                  the supplied options must include all of the following <phrase duff="chg" at="E">(if anything else is present, it is ignored)</phrase>:</p>
               <olist>
                  <item><p>The stylesheet, provided either by supplying exactly one of the following:</p>                
                     <slist>
                        <sitem><code>stylesheet-location</code></sitem>
                        <sitem><code>stylesheet-node</code></sitem>
                        <sitem><code>stylesheet-text</code></sitem>
                     </slist>
                  
                     <p>Or by supplying exactly one of the following:</p>                      
                     <slist>
                        <sitem><code>package-location</code></sitem>
                        <sitem><code>package-node</code></sitem>
                        <sitem><code>package-text</code></sitem>
                        <sitem><code>package-name</code> plus optionally <code>package-version</code></sitem>
                     </slist>                 
                  </item> 
                  <item><p>Invocation details, as exactly one of the following combinations:</p>
                     <olist>
                        <item>
                           <p>For apply-templates invocation, all of the following:</p>
                           <p>Exactly one of <code>source-node</code> or <code>initial-match-selection</code></p>
                           <p>Optionally, <code>initial-mode</code></p>
                           <p>Optionally, <code>template-params</code></p>
                           <p>Optionally, <code>tunnel-params</code></p>
                        </item>
                        <item>
                           <p>For call-template invocation using an explicit template name, all of the following:</p>
                           <p><code>initial-template</code></p>
                           <p>Optionally, <code>template-params</code></p>
                           <p>Optionally, <code>tunnel-params</code></p>
                           <p>Optionally, <code>source-node</code></p>
                        </item>
                        <item>
                           <p>For call-template invocation using the defaulted template name <code>xsl:initial-template</code>, all of the following:</p>
                           <p>Optionally, <code>template-params</code></p>
                           <p>Optionally, <code>tunnel-params</code></p>
                           <note><p>If the <code>source-node</code> option is present and <code>initial-template</code> is absent,
                              then apply-templates invocation will be used. To use call-template invocation on the template
                              named <code>xsl:initial-template</code> while also supplying a context item for use when evaluating
                              global variables, either (a) supply the context item using the <code>global-context-item</code> option,
                              or (b) supply <code>source-node</code>, and set the <code>initial-template</code> option explicitly to the 
                              QName <code>xsl:initial-template</code></p></note>
                        </item>
                        <item>
                           <p>For call-function invocation, all of the following:</p>
                           <p><code>initial-function</code></p>
                           <p><code>function-params</code></p>
                        </item>
                     </olist>
                     <note><p>The invocation method can be determined as the first of the following which applies:</p>
                        <ulist>
                           <item><p>If <code>initial-function</code> is present, then call-function invocation.</p></item>
                           <item><p>If <code>initial-template</code> is present, then call-template invocation.</p></item>
                           <item><p>If <code>source-node</code> or <code>initial-match-selection</code>
                              is present, then apply-templates invocation.</p></item>
                           <item><p>Otherwise, <code>call-template</code> invocation using
                              the default entry point <code>xsl:initial-template</code>.</p></item>
                        </ulist>
                     </note>
                  </item> 
                  <item>
                     <p>Zero or more of the following additional options:</p>
                     <slist>
                        <sitem><code>stylesheet-base-uri</code></sitem>
                        <sitem><code>static-params</code> (defaults to an empty map)</sitem>
                        <sitem><code>stylesheet-params</code> (defaults to an empty map)</sitem>
                        <sitem><code>global-context-item</code> (defaults to absent)</sitem>
                        <sitem><code>base-output-uri</code> (defaults to absent)</sitem>
                        <sitem><code>delivery-format</code></sitem>
                        <sitem><code>serialization-params</code> (defaults to an empty map)</sitem>
                        <sitem><code>enable-assertions</code> (default is false)</sitem>
                        <sitem><code>enable-messages</code> (default is implementation-defined)</sitem>
                        <sitem><code>enable-trace</code> (default is implementation-defined)</sitem>
                        <sitem><code>requested-properties</code> (default is an empty map)</sitem>
                        <sitem><code>vendor-options</code> (defaults to an empty map)</sitem>
                        <sitem><code>cache</code> (default is implementation-defined)</sitem>
                     </slist>
                  </item>
               </olist>           
            </item>
         </olist>
         
         <p>The meanings of each option are defined in the table below.</p>
         
         <fos:options>

    <fos:option key="base-output-uri">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>The URI of the principal result document; also used as the base URI for
            resolving relative URIs of secondary result documents. If the value is a relative 
            reference, it is resolved against the static base URI of the <code>fn:transform</code> 
            function call. </fos:meaning>

        <fos:type>xs:string</fos:type>
        <fos:default>The effect of not
            supplying a base output URI is defined by the XSLT specification; the implementation
            <rfc2119>may</rfc2119> supply a default, for example the directory containing the
            stylesheet, or the current working directory. </fos:default>
    </fos:option>
    <fos:option key="cache">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>This option has no effect on the result of the transformation but may affect
            efficiency. The value <code>true</code> indicates an expectation that the same
            stylesheet is likely to be used for more than one transformation; the value
                <code>false</code> indicates an expectation that the stylesheet will be used once
            only.</fos:meaning>
        <fos:type>xs:boolean</fos:type>
        <fos:default>true()</fos:default>
    </fos:option>
    <fos:option key="delivery-format">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>The manner in which the transformation results should be delivered. Applies both to the
            principal result document and to secondary result documents created using
                <code>xsl:result-document</code>.</fos:meaning>
         <fos:type>xs:string</fos:type>
        <fos:default><code>document</code>, unless the relevant
            <code>xsl:output</code> or <code>xsl:result-document</code> element specifies
            <code>build-tree="no"</code> (applies to XSLT 3.0 only), in which case the default
            is <code>raw</code>.</fos:default>
        <fos:values>
            <fos:value value="document">The result is delivered as a
                        document node.</fos:value>
            <fos:value value="serialized">The result is delivered as
                        a string, representing the results of serialization. Note that (as with the
                            <code>fn:serialize</code> function) the final encoding stage of
                        serialization (which turns a sequence of characters into a sequence of
                        octets) is either skipped, or reversed by decoding the octet stream back
                        into a character stream.</fos:value>
            <fos:value value="raw">The result of the initial
                template or function is returned as an arbitrary XDM value (after conversion
                to the declared type, but without wrapping in a document node, and without
                serialization): when this option is chosen, the returned map contains the
                raw result.</fos:value>
        </fos:values>
        
    </fos:option>
    <fos:option key="enable-assertions">
        <fos:applies-to>3.0</fos:applies-to>
        <fos:meaning>Indicates whether any <code>xsl:assert</code> instructions in the stylesheet
            are to be evaluated.</fos:meaning>
        <fos:type>xs:boolean</fos:type>
        <fos:default>false()</fos:default>
    </fos:option>
    <fos:option key="enable-messages">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>Indicates whether any <code>xsl:message</code> instructions in the stylesheet
            are to be evaluated. The destination and formatting of any such messages is
            implementation-defined.</fos:meaning>
        <fos:type>xs:boolean</fos:type>
        <fos:default>Implementation-defined</fos:default>
    </fos:option>
    <fos:option key="enable-trace">
        <fos:applies-to>2.0, 3.0</fos:applies-to>
        <fos:meaning>Indicates whether any <code>fn:trace</code> functions in the stylesheet are to
            generate diagnostic messages. The destination and formatting of any such messages is
            implementation-defined.</fos:meaning>
        <fos:type>xs:boolean</fos:type>
        <fos:default>Implementation-defined</fos:default>
    </fos:option>
    <fos:option key="function-params">
        <fos:applies-to>3.0</fos:applies-to>
        <fos:meaning>An array of values to be used as the arguments to the initial function call.
            The value is converted to the required type of the declared parameter using the function
            conversion rules.</fos:meaning>
        <fos:type>array(item()*)</fos:type>
        <fos:default>Empty array</fos:default>
    </fos:option>
    <fos:option key="global-context-item">
        <fos:applies-to>3.0</fos:applies-to>
        <fos:meaning>The value of the global context item, as defined in XSLT 3.0</fos:meaning>
        <fos:type>item()</fos:type>
        <fos:default>The value of <code>source-node</code></fos:default>
    </fos:option>
    <fos:option key="initial-function">
        <fos:applies-to>3.0</fos:applies-to>
        <fos:meaning>The name of the initial function to be called for call-function invocation. The
            arity of the function is inferred from the length of
            <code>function-params</code>.</fos:meaning>
        <fos:type>xs:QName</fos:type>
        <fos:default>n/a</fos:default>
    </fos:option>
    <fos:option key="initial-match-selection">
        <fos:applies-to>3.0</fos:applies-to>
        <fos:meaning>The value of the initial match selection, as defined in XSLT 3.0</fos:meaning>
        <fos:type>item()*</fos:type>
        <fos:default>The value of <code>source-node</code></fos:default>
    </fos:option>
    <fos:option key="initial-mode">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>The name of the initial processing mode.</fos:meaning>
        <fos:type>xs:QName</fos:type>
        <fos:default></fos:default>
    </fos:option>
    <fos:option key="initial-template">
        <fos:applies-to>2.0, 3.0</fos:applies-to>
        <fos:meaning>The name of a named template in the stylesheet to act as the initial entry
            point.</fos:meaning>
        <fos:type>xs:QName</fos:type>
        <fos:default>xsl:initial-template</fos:default>
    </fos:option>
    <fos:option key="package-name">
        <fos:applies-to>3.0</fos:applies-to>
        <fos:meaning>The name of the top-level stylesheet package to be invoked (an absolute
            URI)</fos:meaning>
        <fos:type>xs:string</fos:type>
        <fos:default>n/a</fos:default>
    </fos:option>
    <fos:option key="package-location">
        <fos:applies-to>3.0</fos:applies-to>
        <fos:meaning>The location of the top-level stylesheet package, as a relative or absolute
            URI</fos:meaning>
        <fos:type>xs:string</fos:type>
        <fos:default>n/a</fos:default>
    </fos:option>
    <fos:option key="package-node">
        <fos:applies-to>3.0</fos:applies-to>
        <fos:meaning>A document or element node containing the top-level stylesheet
            package</fos:meaning>
        <fos:type>node()</fos:type>
        <fos:default>n/a</fos:default>
    </fos:option>
    <fos:option key="package-text">
        <fos:applies-to>3.0</fos:applies-to>
        <fos:meaning>The top-level stylesheet package in the form of unparsed lexical
            XML.</fos:meaning>
        <fos:type>xs:string</fos:type>
        <fos:default>n/a</fos:default>
    </fos:option>

    <fos:option key="package-version">
        <fos:applies-to>3.0</fos:applies-to>
        <fos:meaning>The version of the top-level stylesheet package to be invoked.</fos:meaning>
        <fos:type>xs:string</fos:type>
        <fos:default>"*" (any version)</fos:default>
    </fos:option>
            <fos:option key="post-process">
               <fos:applies-to>1.0 2.0 3.0</fos:applies-to>
               <fos:meaning>A function that is used to post-process each result document of
                  the transformation (both the principal result and secondary results), in whatever
                  form it would otherwise be delivered (document, serialized, or raw). The first 
                  argument of the function is the key used to identify the result in the map return
                  by the <code>fn:transform</code> function (for example, this will be the supplied 
                  base output URI in the case of the principal result, or the string "output" if no
                  base output URI was supplied). The second argument is the 
                  actual value. The value that is returned in the result of the <code>fn:transform</code> 
                  function is the result of applying this post-processing.
                  
                  <note>
                     <p>If the implementation provides a way of writing or invoking functions 
                        with side-effects, this post-processing function might be used to save 
                        a copy of the result document to persistent storage. For example, if the 
                        implementation provides access to the EXPath File library <bibref ref="expath"/>, 
                        then a serialized document might be written to filestore by calling the 
                        <code>file:write</code> function. Similar mechanisms might be used to issue 
                        an HTTP POST request that posts the result to an HTTP server, or to send 
                        the document to an email recipient. The semantics of calling functions 
                        with side-effects are entirely <termref def="implementation-defined">implementation-defined</termref>.</p>
                     
                     <p>If the primary purpose of the post-processing function is achieved by 
                        means of such side-effects, and if the actual results are not needed by 
                        the caller of the <code>fn:transform</code> function, then it does not matter what 
                        the post-processing function actually returns (it could be an empty 
                        sequence, for example).</p>
                     
                     <p>Calls to <code>fn:transform</code> can potentially have side-effects 
                        even in the absence of the post-processing option, because the XSLT 
                        specification allows a stylesheet to invoke extension functions 
                        that have side-effects. The semantics in this case are <termref def="implementation-defined">implementation-defined</termref>.</p>
                     
                     
                  </note></fos:meaning>
               <fos:type>function(xs:string, item()*) as item()*</fos:type>
               <fos:default>function($a, $b) { $b }</fos:default>
            </fos:option>
    <fos:option key="requested-properties">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>The keys in the map are QNames that could legitimately be supplied in a call to
            the XSLT <code>system-property</code> function; the values in the map are the requested
            settings of the corresponding property. The boolean values <code>true()</code> and
                <code>false()</code> are equivalent to the string values <code>yes</code> and
                <code>no</code>. As a special case, setting a value for <code>xsl:version</code> has
            no effect, because of the potential for conflict with other options. For example: <ulist>
                <item><p>Setting <code>xsl:product-name</code> to a particular value requests a
                        particular XSLT software product.</p></item>
                <item><p>Setting <code>xsl:product-version</code> requests a specific version of
                        that product.</p></item>
                <item><p>Setting <code>xsl:is-schema-aware</code> to <code>true()</code> requests a
                        schema-aware processor.</p></item>
                <item><p>Setting <code>xsl:xsd-version</code> to <code>"1.1"</code> requests a
                        processor that supports XML Schema version 1.1.</p></item>
            </ulist> Setting a boolean property such as <code>xsl:supports-dynamic-evaluation</code>
            to <code>false()</code> is interpreted as an explicit request for a processor in which
            the value of the property is false. The effect if the requests cannot be precisely met
            is implementation-defined. In some cases it may be appropriate to ignore the request or
            to provide an alternative (for example, a later version of the product than the one
            requested); in other cases it may be more appropriate to raise an error <errorref
                class="XT" code="0001" type="dynamic"/> indicating that no suitable XSLT processor
            is available. </fos:meaning>
        <fos:type>map(xs:QName, xs:anyAtomicType)</fos:type>
        <fos:default>Empty map</fos:default>
    </fos:option>
    <fos:option key="serialization-params">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>Serialization parameters for the principal result document. The supplied map
            follows the same rules that apply to a map supplied as the second argument of
                <code>fn:serialize</code>. <ulist>
                <item><p>When a parameter is supplied, the corresponding value overrides or augments
                        the value specified in the unnamed <code>xsl:output</code> declaration (or
                        its default), following the same rules as when one <code>xsl:output</code>
                        declaration overrides another with lower import precedence.</p></item>
                <item><p>When a parameter is supplied and the corresponding value is an empty
                        sequence (for example, <code>map{"standalone":()}</code>), any value
                        specified in the unnamed <code>xsl:output</code> declaration is overridden
                        by the default value. </p></item>
                <item><p>When a parameter is not supplied in <code>serialization-params</code> (that
                        is, when the key is absent) the value that applies is the value appearing in
                        the unnamed <code>xsl:output</code> declaration, or its default. </p></item>
            </ulist></fos:meaning>
        <fos:type>map(xs:anyAtomicType, item()*)</fos:type>
        <fos:default>Empty map</fos:default>
    </fos:option>
    <fos:option key="source-node">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>When <code>source-node</code> is supplied then the
                <code>global-context-item</code> (the context item for evaluating global variables)
            is the root of the tree containing the supplied node. In addition, for apply-templates
            invocation, the <code>source-node</code> acts as the
                <code>initial-match-selection</code>, that is, stylesheet execution starts by
            applying templates to this node.</fos:meaning>
        <fos:type>node()</fos:type>
        <fos:default>n/a</fos:default>
    </fos:option>

    <fos:option key="static-params">
        <fos:applies-to>3.0</fos:applies-to>
        <fos:meaning>The values of static parameters defined in the stylesheet; the keys are the
            names of the parameters, and the associated values are their values. The value is
            converted to the required type of the declared parameter using the function conversion
            rules.</fos:meaning>
        <fos:type>map(xs:QName, item()*)</fos:type>
        <fos:default>Empty map</fos:default>
    </fos:option>
    <fos:option key="stylesheet-base-uri">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>A string intended to be used as the static base URI of the principal stylesheet
            module. This value <rfc2119>must</rfc2119> be used if no other static base URI is
            available. If the supplied stylesheet already has a base URI (which will generally be
            the case if the stylesheet is supplied using <code>stylesheet-node</code> or
                <code>stylesheet-location</code>) then it is <termref
                def="dt-implementation-defined">implementation-defined</termref> whether this
            parameter has any effect. If the value is a relative reference, it is resolved against
            the static base URI of the <code>fn:transform</code> function call.</fos:meaning>
        <fos:type>xs:string</fos:type>
        <fos:default>n/a</fos:default>
    </fos:option>
    <fos:option key="stylesheet-location">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>URI that can be used to locate the principal stylesheet module. If relative, it
            is resolved against the static base URI of the <code>fn:transform</code> function call.
            The value also acts as the default for stylesheet-base-uri.</fos:meaning>
        <fos:type>xs:string</fos:type>
        <fos:default>n/a</fos:default>
    </fos:option>
    <fos:option key="stylesheet-node">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>Root of the tree containing the principal stylesheet module, as a document or
            element node. The base URI of the node acts as the default for
            stylesheet-base-uri.</fos:meaning>
        <fos:type>node()</fos:type>
        <fos:default>n/a</fos:default>
    </fos:option>
    <fos:option key="stylesheet-params">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>A map holding values to be supplied for stylesheet parameters. The keys are the
            parameter names; the values are the corresponding parameter values. The values are
            converted if necessary to the required type using the function conversion rules. The
            default is an empty map.</fos:meaning>
        <fos:type>map(xs:QName, item()*)</fos:type>
        <fos:default>Empty map</fos:default>
    </fos:option>

    <fos:option key="stylesheet-text">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>The principal stylesheet module in the form of unparsed lexical
            XML.</fos:meaning>
        <fos:type>xs:string</fos:type>
        <fos:default>n/a</fos:default>
    </fos:option>
    <fos:option key="template-params">
        <fos:applies-to>3.0</fos:applies-to>
        <fos:meaning>The values of non-tunnel parameters to be supplied to the initial template,
            used with both apply-templates and call-template invocation. Each value is converted to
            the required type of the declared parameter using the function conversion
            rules.</fos:meaning>
        <fos:type>map(xs:QName, item()*)</fos:type>
        <fos:default></fos:default>
    </fos:option>
    <fos:option key="tunnel-params">
        <fos:applies-to>3.0</fos:applies-to>
        <fos:meaning>The values of tunnel parameters to be supplied to the initial template, used
            with both apply-templates and call-template invocation. Each value is converted to the
            required type of the declared parameter using the function conversion
            rules.</fos:meaning>
        <fos:type>map(xs:QName, item()*)</fos:type>
        <fos:default>Empty map</fos:default>
    </fos:option>

    <fos:option key="vendor-options">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>Values for vendor-defined configuration options for the XSLT processor used to
            process the request. The key is the name of an option, expressed as a QName: the
            namespace URI of the QName <rfc2119>should</rfc2119> be a URI controlled by the vendor
            of the XSLT processor. The meaning of the associated value is <termref
                def="implementation-defined">implementation-defined</termref>. Implementations
                <rfc2119>should</rfc2119> ignore options whose names are in an unrecognized
            namespace. Default is an empty map.</fos:meaning>
        <fos:type>map{xs:QName, item()*}</fos:type>
        <fos:default>Empty map</fos:default>
    </fos:option>

    <fos:option key="xslt-version">
        <fos:applies-to>1.0, 2.0, 3.0</fos:applies-to>
        <fos:meaning>The minimum level of the XSLT language that the processor must support.</fos:meaning>
        <fos:type>xs:decimal</fos:type>
        <fos:default>The <code>[xsl:]version</code> attribute at the outermost level of the
            stylesheet.</fos:default>
    </fos:option>

</fos:options>

         
 
         
         <p>The result of the transformation is returned as a map. There is one entry in the map for the principal result document, and one
            for each secondary result document. The key is a URI in the form of an <code>xs:string</code> value. The key for the principal
            result document is the base output URI if specified, or the string <code>"output"</code> otherwise. The key for secondary
            result documents is the URI of the document, as an absolute URI. The associated value in each entry depends on the requested
            delivery format. If the delivery format is <code>document</code>, the value is a document node. If the delivery format is
            <code>serialized</code>, the value is a string containing the serialized result. <phrase diff="del" at="G">If the delivery format is <code>saved</code>,
            the value is the absolute URI of the location where the serialized result has been saved. The saved document will not be accessible
            at this location within the current <termref def="execution-scope">execution scope</termref>
            (this is to prevent any dependency on order of execution).</phrase></p>
         
         <p diff="chg" at="D">Where nodes are passed to or from the transformation, for example as the value of a stylesheet parameter or the result of a function, 
            they <rfc2119>should</rfc2119> if possible retain their node identity, their base URI, their type annotations, and their relationships to all other nodes 
            in the containing tree (including ancestors and siblings). If this is not possible, for example because the only way of passing nodes 
            to the chosen XSLT implementation is by serializing and re-parsing, then a node <rfc2119>may</rfc2119> be passed in the form of a deep 
            copy, which may lose information about the identity of the node, about its ancestors and siblings, about its base URI, about its type annotation, and about its 
            relationships to other nodes passed across the interface.</p>
         
         <p diff="chg" at="D">It is <termref def="dt-implementation-defined">implementation-defined</termref> whether the XSLT transformation is executed
            within the same <termref def="execution-scope">execution scope</termref> as the calling code.</p>
         
         <p>The function is <termref def="dt-nondeterministic">nondeterministic</termref> in that it is 
            <termref def="dt-implementation-dependent">implementation-dependent</termref> whether running the function twice against the same
         inputs produces identical results. The results of two invocations may differ in the identity of any returned nodes; they may also
         differ in other respects, for example because the value of <code>fn:current-dateTime</code> is different for the two invocations,
         or because the contents of external documents accessed using <code>fn:doc</code> or <code>xsl:source-document</code> change between
         one invocation and the next.</p>
         
         <p diff="del" at="G">The delivery format <code>saved</code> indicates that the transformation should modify the state of the external environment. 
            This has two noteworthy consequences:
         </p>
         
         <ulist diff="del" at="G">
            <item><p>It creates a potential security risk.</p></item>
            <item><p>The <code>fn:transform</code> function ceases to be a pure function, because it has side-effects.</p></item>
         </ulist>
         <p diff="del" at="G">Implementations <rfc2119>may</rfc2119> mitigate these problems in a number of ways, including the following:</p>
         
         <olist diff="del" at="G">
            <item><p>Use of the <code>delivery-format=saved</code> option <rfc2119>may</rfc2119> be disallowed, either 
               completely or at user option.
            </p></item>
            <item><p>The environment that the <code>delivery-format=saved</code> option is allowed to modify <rfc2119>may</rfc2119> be 
               sand-boxed in some way. For example: resources that are created using this option may be accessible only 
               via some special interface; the resource may become available only on completion of the execution scope 
               in which the fn:transform function is evaluated; or the implementation may prevent the use functions 
               such as <code>fn:doc</code> and <code>fn:collection</code> to access such resources.
            </p></item>
            <item><p>Creating multiple resources with the same URI <rfc2119>may</rfc2119> be disallowed.</p></item>
            <item><p>The implementation may define circumstances in which the side-effect of 
               creating external resources is thwarted as a consequence of query optimization
               (for example, any situation in which a query calls fn:transform but has no functional 
               dependency on the result of the call). 
            </p></item>
            <item><p>There <rfc2119>may</rfc2119> be restrictions on the URIs that can be used to identify saved resources</p></item>
         </olist>

      </fos:rules>
      <fos:errors>
         <p>A dynamic error is raised <errorref class="XT" code="0001" type="dynamic"/> if the transformation cannot be invoked 
            because no suitable XSLT processor is available. This includes (but is not limited to) the following cases:</p>
         <olist diff="add" at="D">
            <item><p>No XSLT processor is available;</p></item>
            <item><p>No XSLT processor supporting the requested version of XSLT is available;</p></item>
            <item><p>The XSLT processor API does not support some requested feature (for example, the ability to supply tunnel parameters externally);</p></item>
         </olist>
         <p>A dynamic error is raised <errorref class="XT" code="0002" type="dynamic"/> if an error is detected in the supplied
            parameters (for example if two mutually-exclusive parameters are supplied).</p>
         <p>If a static or dynamic error is reported by the XSLT processor, this function fails with a dynamic error, retaining the XSLT error code.</p>
         <p>A dynamic error is raised <errorref class="XT" code="0003" type="dynamic"/> if the XSLT transformation invoked by a call on
            <code>fn:transform</code> fails with a static or dynamic error, and no more specific error code is available. </p>
         <note><p>XSLT 1.0 does not define any error codes, so this is the likely outcome with an XSLT 1.0 processor. XSLT 2.0 and 3.0 do
         define error codes, but some APIs do not expose them. If multiple errors are signaled by the transformation (which is most likely
         to happen with static errors) then the error code should where possible be that of one of these errors, chosen arbitrarily; the processor
         may make details of additional errors available to the application in an <termref def="dt-implementation-defined">implementation-defined</termref>
         way.</p></note>
         <p>A dynamic error is raised <errorref class="XT" code="0004" type="dynamic"/> if the use of this function (or of selected options)
            has been externally disabled, for example for security reasons.</p>
         <p diff="del" at="G">A dynamic error is raised <errorref class="XT" code="0005" type="dynamic"/> if <code>delivery-format</code> is <code>saved</code>
            and the results cannot be saved at the specified location.</p>
         <p>A dynamic error is raised <errorref class="XT" code="0006" type="dynamic"/> if the transformation produces output containing
            characters available only in XML 1.1, and the calling processor cannot handle such characters.</p>
         <p diff="del" at="G">A dynamic error is raised <errorref class="XT" code="0007" type="dynamic"/> if the option <code>delivery-format:saved</code>
            is used in a way that violates any implementation-defined restrictions on its use.</p>
         <p>Recursive use of the <code>fn:transform</code> function may lead to catastrophic failures such as
         non-termination or stack overflow. No error code is assigned to such conditions, since they cannot necessarily
         be detected by the processor.</p>

      </fos:errors>
      <fos:notes>
         
         <p>As with all other functions in this specification, conformance requirements depend on the host language.
            For example, a host language might specify that provision of this function is optional, or that it is excluded entirely,
            or that implementations are required to support a particular set of values for the <code>xslt-version</code>
            parameter.</p>
         
         <p>Even where support for this function is mandatory, it is <rfc2119>recommended</rfc2119> for security reasons that implementations
            should provide a user option to disable its use, or to disable aspects of its functionality such as
            the ability to write to persistent resources.</p>
         
         
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p>The following example loads a stylesheet from the location <code>render.xsl</code>,
               applies it to a document loaded from <code>test.xml</code>, and uses an XPath expression
               to examine the result:</p>
            <eg><![CDATA[
let $result := fn:transform(
  map {
    "stylesheet-location" : "render.xsl",
    "source-node"    : fn:doc('test.xml')
  })
return $result?output//body  
               ]]></eg>
         </fos:example>
      </fos:examples>
      
   </fos:function>
   
   
   <fos:function name="random-number-generator" prefix="fn">
      <fos:signatures>

         <fos:proto name="random-number-generator" return-type="map(xs:string, item())"/>
      
         <fos:proto name="random-number-generator" return-type="map(xs:string, item())">
            <fos:arg name="seed" type="xs:anyAtomicType?"/>
         </fos:proto>

      </fos:signatures>
      <fos:properties>
         <fos:property>deterministic</fos:property>
         <fos:property>context-independent</fos:property>
         <fos:property>focus-independent</fos:property>
         <fos:property>higher-order</fos:property>
      </fos:properties>
      <fos:summary><p>Returns a random number generator, which can be used to generate sequences of random numbers.</p></fos:summary>
      <fos:rules>
         <p>The function returns a random number generator. A random number generator is represented as a map containing three entries. 
            The keys of each entry are strings:</p>
         <olist>
            <item><p>The entry with key <code>"number"</code> holds a random number; it is an <code>xs:double</code> greater than or equal
               to zero (0.0e0), and less than one (1.0e0).</p></item>
            <item><p>The entry with key <code>"next"</code> is a zero-arity function that can be called to return another random number
            generator.</p>
            <p diff="add" at="D">The properties of this function are as follows:</p>
               <ulist diff="add" at="D">
               <item><p>name: absent</p></item>
               <item><p>parameter names: ()</p></item>
               <item><p>signature: <code>() => map(xs:string, item())</code></p></item>
               <item><p>non-local variable bindings: none</p></item>
               <item><p>implementation: implementation-dependent</p></item>
            </ulist>    
            </item>
            <item><p>The entry with key <code>"permute"</code> is a function with arity 1 (one), which takes an arbitrary sequence
            as its argument, and returns a random permutation of that sequence.</p>
               <p diff="add" at="D">The properties of this function are as follows:</p>
               <ulist diff="add" at="D">
                  <item><p>name: absent</p></item>
                  <item><p>parameter names: ("arg")</p></item>
                  <item><p>signature: <code>(item()*) => item()*</code></p></item>
                  <item><p>non-local variable bindings: none</p></item>
                  <item><p>implementation: implementation-dependent</p></item>
               </ulist>   </item>
         </olist>
         <p>Calling the <code>fn:random-number-generator</code> function with no arguments is equivalent to calling the single-argument
         form of the function with an implementation-dependent seed.</p>
         <p diff="add" at="E">Calling the <code>fn:random-number-generator</code> function with an empty sequence as the value of <code>$seed</code> 
            is equivalent to calling the single-argument form of the function with an implementation-dependent seed.</p>
         <p>If a <code>$seed</code> is supplied, it may be an atomic value of any type.</p>
         <p>Both forms of the function are <termref def="dt-deterministic"/>: calling the function twice with the same arguments, within a single
         <termref def="execution-scope">execution scope</termref>, produces the same results.</p>
         
         
         <p>The value of the <code>number</code> entry <rfc2119>should</rfc2119> be such that all eligible <code>xs:double</code>
         values are equally likely to be chosen.</p>
         
         <p>The function returned in the <code>permute</code> entry <rfc2119>should</rfc2119> be such that all permutations 
            of the supplied sequence are equally likely to be chosen.</p>
         
         <p>The map returned by the <code>fn:random-number-generator</code> function <rfc2119>may</rfc2119> contain additional entries beyond
            those specified here, but it <rfc2119>must</rfc2119> match the type <code>map(xs:string, item())</code>. The meaning of any additional entries
         is <termref def="implementation-defined">implementation-defined</termref>. To avoid conflict with any future version of this specification, the keys of any
         such entries <rfc2119>should</rfc2119> start with an underscore character.</p>
      </fos:rules>
      <fos:notes>
         <p>It is not meaningful to ask whether the functions returned in the <code>next</code> and <code>permute</code>
            functions resulting from two separate calls with the same seed are "the same function", but the functions must be equivalent in the sense
            that calling them produces the same sequence of random numbers.</p>
         <p>The repeatability of the results of function calls in different execution scopes is outside the scope of this
            specification. It is <rfc2119>recommended</rfc2119> that when the same seed is provided explicitly, the same random number sequence
            should be delivered even in different execution scopes; while if no seed is provided, the processor should choose a seed
            that is likely to be different from one execution scope to another. (The same effect can be achieved explicitly by using
         <code>fn:current-dateTime()</code> as a seed.)</p>
         <p>The specification does not place strong conformance requirements on the actual randomness of the result; this is left to 
            the implementation. It is desirable, for example, when generating a sequence
         of random numbers that the sequence should not get into a repeating loop; but the specification does not attempt to dictate this.</p>
      </fos:notes>
      <fos:examples>
         <fos:example>
            <p>The following example returns a random permutation of the integers in the range 1 to 100: 
               <code>fn:random-number-generator()?permute(1 to 100)</code>
            </p>
            <p>The following example returns a 10% sample of the items in an input sequence <code>$seq</code>, chosen at random: 
                  <code>fn:random-number-generator()?permute($seq)[position() = 1 to (count($seq) idiv 10)]</code>
            </p>
            <p>The following code defines a function that can be called to produce a random sequence of <code>xs:double</code>
            values in the range zero to one, of specified length:</p>
            <eg>
declare %public function r:random-sequence($length as xs:integer) as xs:double* {
  r:random-sequence($length, fn:random-number-generator())
};

declare %private function r:random-sequence($length as xs:integer, 
                                            $G as map(xs:string, item())) {
  if ($length eq 0)
  then ()
  else ($G?number, r:random-sequence($length - 1, $G?next()))
};

r:random-sequence(200);
            </eg>
            
               
            
         </fos:example>
      </fos:examples>
   </fos:function>
   


</fos:functions>
