<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:f="http://fxsl.sf.net/" version="2.0" exclude-result-prefixes="f xs">

  <xsl:import href="../f/func-XpathConstructors.xsl"/>
  <xsl:import href="../f/func-apply.xsl"/>

  <xsl:function name="f:copy-with-type" as="node()">
    <xsl:param name="arg" as="item()*"/>
    <copy xsl:use-when="system-property('xsl:is-schema-aware') eq 'yes'" xsl:validation="preserve">
      <xsl:sequence select="for $a in $arg return f:copy-with-type-1($a)"/>
    </copy>
    <copy xsl:use-when="system-property('xsl:is-schema-aware') ne 'yes'">
      <xsl:sequence select="for $a in $arg return f:copy-with-type-1($a)"/>
    </copy>
  </xsl:function>

  <xsl:function name="f:get-typed" as="item()*">
    <xsl:param name="arg" as="element(copy)"/>
    <xsl:apply-templates select="$arg/*" mode="f:get-typed"/>
  </xsl:function>

  <xsl:template match="node" mode="f:get-typed" as="node()">
    <xsl:sequence select="@*|node()"/>
  </xsl:template>

  <xsl:template match="atomic" mode="f:get-typed" as="item()" use-when="system-property('xsl:is-schema-aware') eq 'yes'">
    <xsl:sequence select="data(.)"/>
  </xsl:template>

  <xsl:template match="f:*" mode="f:get-typed" as="item()" use-when="system-property('xsl:is-schema-aware') ne 'yes'">
    <xsl:sequence select="f:apply(., data(.))"/>
  </xsl:template>

  <xsl:function name="f:copy-with-type-1" as="node()" use-when="system-property('xsl:is-schema-aware') eq 'yes'">
    <xsl:param name="arg" as="item()"/>
    <xsl:choose>
      <xsl:when test="$arg instance of node()">
        <node xsl:validation="preserve">
          <xsl:copy-of select="$arg" validation="preserve"/>
        </node>
      </xsl:when>
      <xsl:otherwise>
        <!--
            The following inclusion results in an xsl:choose
            instruction whose the when instructions are of the form:

                <xsl:when test="$arg instance of xs:a-type">
                   <atomic xsl:type="xs:a-type">
                      <xsl:copy-of select="$arg" validation="preserve"/>
                   </atomic>
                </xsl:when>

            That code is generated.  See ../data/func-copy-make-whens.xsl,
            ../data/func-copy-whens.xml, and ../data/xs-simple-types.xml
        -->
        <xsl:choose xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xml:id="sa" xml:base="../data/func-copy-whens.xml">
      <xsl:when test="$arg instance of xs:string">
         <xsl:choose>
            <xsl:when test="$arg instance of xs:language">
               <atomic xsl:type="xs:language">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:ID">
               <atomic xsl:type="xs:ID">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:IDREF">
               <atomic xsl:type="xs:IDREF">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:ENTITY">
               <atomic xsl:type="xs:ENTITY">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:NCName">
               <atomic xsl:type="xs:NCName">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:Name">
               <atomic xsl:type="xs:Name">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:NMTOKEN">
               <atomic xsl:type="xs:NMTOKEN">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:token">
               <atomic xsl:type="xs:token">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:normalizedString">
               <atomic xsl:type="xs:normalizedString">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:otherwise>
               <atomic xsl:type="xs:string">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:otherwise>
         </xsl:choose>
      </xsl:when>
      <xsl:when test="$arg instance of xs:decimal">
         <xsl:choose>
            <xsl:when test="$arg instance of xs:negativeInteger">
               <atomic xsl:type="xs:negativeInteger">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:nonPositiveInteger">
               <atomic xsl:type="xs:nonPositiveInteger">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:byte">
               <atomic xsl:type="xs:byte">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:short">
               <atomic xsl:type="xs:short">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:int">
               <atomic xsl:type="xs:int">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:long">
               <atomic xsl:type="xs:long">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:unsignedByte">
               <atomic xsl:type="xs:unsignedByte">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:unsignedShort">
               <atomic xsl:type="xs:unsignedShort">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:unsignedInt">
               <atomic xsl:type="xs:unsignedInt">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:unsignedLong">
               <atomic xsl:type="xs:unsignedLong">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:positiveInteger">
               <atomic xsl:type="xs:positiveInteger">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:nonNegativeInteger">
               <atomic xsl:type="xs:nonNegativeInteger">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:when test="$arg instance of xs:integer">
               <atomic xsl:type="xs:integer">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:when>
            <xsl:otherwise>
               <atomic xsl:type="xs:decimal">
                  <xsl:copy-of select="$arg" validation="preserve"/>
               </atomic>
            </xsl:otherwise>
         </xsl:choose>
      </xsl:when>
      <xsl:when test="$arg instance of xs:boolean">
         <atomic xsl:type="xs:boolean">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:double">
         <atomic xsl:type="xs:double">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:float">
         <atomic xsl:type="xs:float">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:date">
         <atomic xsl:type="xs:date">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:time">
         <atomic xsl:type="xs:time">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:dateTime">
         <atomic xsl:type="xs:dateTime">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:yearMonthDuration">
         <atomic xsl:type="xs:yearMonthDuration">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:dayTimeDuration">
         <atomic xsl:type="xs:dayTimeDuration">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:duration">
         <atomic xsl:type="xs:duration">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:QName">
         <atomic xsl:type="xs:QName">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:anyURI">
         <atomic xsl:type="xs:anyURI">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:gDay">
         <atomic xsl:type="xs:gDay">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:gMonthDay">
         <atomic xsl:type="xs:gMonthDay">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:gMonth">
         <atomic xsl:type="xs:gMonth">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:gYearMonth">
         <atomic xsl:type="xs:gYearMonth">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:gYear">
         <atomic xsl:type="xs:gYear">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:base64Binary">
         <atomic xsl:type="xs:base64Binary">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:when test="$arg instance of xs:hexBinary">
         <atomic xsl:type="xs:hexBinary">
            <xsl:copy-of select="$arg" validation="preserve"/>
         </atomic>
      </xsl:when>
      <xsl:otherwise>
         <atomic>
            <xsl:copy-of select="$arg"/>
         </atomic>
      </xsl:otherwise>
   </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:function>

  <xsl:function name="f:copy-with-type-1" as="node()" use-when="system-property('xsl:is-schema-aware') ne 'yes'">
    <xsl:param name="arg" as="item()"/>
    <xsl:choose>
      <xsl:when test="$arg instance of node()">
        <node>
          <xsl:copy-of select="$arg"/>
        </node>
      </xsl:when>
      <xsl:otherwise>
        <!--
            The following inclusion results in an xsl:choose
            instruction whose the when instructions are of the form:

                <xsl:when test="$arg instance of xs:a-basic-type">
                   <f:a-basic-type>
                      <xsl:copy-of select="$arg"/>
                   </f:a-basic-type>
                </xsl:when>

            That code is generated.  See ../data/func-copy-make-whens.xsl,
            ../data/func-copy-whens.xml, and ../data/xs-simple-types.xml
        -->
        <xsl:choose xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:f="http://fxsl.sf.net/" xml:id="basic" xml:base="../data/func-copy-whens.xml">
      <xsl:when test="$arg instance of xs:string">
         <f:string>
            <xsl:copy-of select="$arg"/>
         </f:string>
      </xsl:when>
      <xsl:when test="$arg instance of xs:boolean">
         <f:boolean>
            <xsl:copy-of select="$arg"/>
         </f:boolean>
      </xsl:when>
      <xsl:when test="$arg instance of xs:integer">
         <f:integer>
            <xsl:copy-of select="$arg"/>
         </f:integer>
      </xsl:when>
      <xsl:when test="$arg instance of xs:decimal">
         <f:decimal>
            <xsl:copy-of select="$arg"/>
         </f:decimal>
      </xsl:when>
      <xsl:when test="$arg instance of xs:double">
         <f:double>
            <xsl:copy-of select="$arg"/>
         </f:double>
      </xsl:when>
      <xsl:when test="$arg instance of xs:float">
         <f:float>
            <xsl:copy-of select="$arg"/>
         </f:float>
      </xsl:when>
      <xsl:when test="$arg instance of xs:date">
         <f:date>
            <xsl:copy-of select="$arg"/>
         </f:date>
      </xsl:when>
      <xsl:when test="$arg instance of xs:time">
         <f:time>
            <xsl:copy-of select="$arg"/>
         </f:time>
      </xsl:when>
      <xsl:when test="$arg instance of xs:dateTime">
         <f:dateTime>
            <xsl:copy-of select="$arg"/>
         </f:dateTime>
      </xsl:when>
      <xsl:when test="$arg instance of xs:yearMonthDuration">
         <f:yearMonthDuration>
            <xsl:copy-of select="$arg"/>
         </f:yearMonthDuration>
      </xsl:when>
      <xsl:when test="$arg instance of xs:dayTimeDuration">
         <f:dayTimeDuration>
            <xsl:copy-of select="$arg"/>
         </f:dayTimeDuration>
      </xsl:when>
      <xsl:when test="$arg instance of xs:duration">
         <f:duration>
            <xsl:copy-of select="$arg"/>
         </f:duration>
      </xsl:when>
      <xsl:when test="$arg instance of xs:QName">
         <f:QName>
            <xsl:copy-of select="$arg"/>
         </f:QName>
      </xsl:when>
      <xsl:when test="$arg instance of xs:anyURI">
         <f:anyURI>
            <xsl:copy-of select="$arg"/>
         </f:anyURI>
      </xsl:when>
      <xsl:when test="$arg instance of xs:gDay">
         <f:gDay>
            <xsl:copy-of select="$arg"/>
         </f:gDay>
      </xsl:when>
      <xsl:when test="$arg instance of xs:gMonthDay">
         <f:gMonthDay>
            <xsl:copy-of select="$arg"/>
         </f:gMonthDay>
      </xsl:when>
      <xsl:when test="$arg instance of xs:gMonth">
         <f:gMonth>
            <xsl:copy-of select="$arg"/>
         </f:gMonth>
      </xsl:when>
      <xsl:when test="$arg instance of xs:gYearMonth">
         <f:gYearMonth>
            <xsl:copy-of select="$arg"/>
         </f:gYearMonth>
      </xsl:when>
      <xsl:when test="$arg instance of xs:gYear">
         <f:gYear>
            <xsl:copy-of select="$arg"/>
         </f:gYear>
      </xsl:when>
      <xsl:when test="$arg instance of xs:base64Binary">
         <f:base64Binary>
            <xsl:copy-of select="$arg"/>
         </f:base64Binary>
      </xsl:when>
      <xsl:when test="$arg instance of xs:hexBinary">
         <f:hexBinary>
            <xsl:copy-of select="$arg"/>
         </f:hexBinary>
      </xsl:when>
      <xsl:otherwise>
         <f:untypedAtomic>
            <xsl:copy-of select="$arg"/>
         </f:untypedAtomic>
      </xsl:otherwise>
   </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:function>

</xsl:stylesheet>
