<?xml version="1.0" encoding="UTF-8"?>
<!--
  Copyright (c) 2000-2026 held by the author(s).  All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer
      in the documentation and/or other materials provided with the
      distribution.
    * Neither the names of the Naval Postgraduate School (NPS)
      Modeling Virtual Environments and Simulation (MOVES) Institute
      (https://www.nps.edu and https://www.MovesInstitute.org)
      nor the names of its contributors may be used to endorse or
      promote products derived from this software without specific
      prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->

<project name="X3D stylesheets" default="all" basedir=".">
    <description>Build and test the X3D stylesheets project.</description>

    <!-- configuration properties ============================================================== -->

    <property name="access.properties.filename"  value="../content/examples/access.properties"/>
    <property file="${access.properties.filename}"/>
    
    <!-- properties common to all build files and archives ======================================== -->
    <property environment="env"/>

    <!-- java jvmarg parameters ignored on server unless forked -->
    <property name="fork"                value="true"/>

    <!-- ignoreSetupDownloadErrors can be overridden by Hudson configuration, ensure initialized by previous invocations -->
    <property name="ignoreSetupDownloadErrors" value="true"/>

    <!-- note that Netbeans default path is built in and has to be overridden by going to     -->
    <!-- Netbeans > Tools > Options > Java > Ant                                              -->
    <!-- and then pointing to C:\apache-ant-1.10.5 (or somesuch locally installed directory)  -->

    <!-- ANT Contrib archive at http://sourceforge.net/projects/ant-contrib/files    (v1.0b3) -->
    <!-- must have ant-contrib-1.0b3.jar in ANT_HOME/lib (or else specify path)               -->
    <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
    
    <!-- jslint4java: a Java wrapper around Douglas Crockford's jslint tool. -->
    <!-- https://code.google.com/p/jslint4java -->
    <!-- http://docs.jslint4java.googlecode.com/git/2.0.5/ant.html -->
    <!-- http://happygiraffe.github.io/jslint4java/cli.html -->
    <!-- http://kaatz-media.com/2011/10/06/uberprufen-von-javascript-dateien-ant-und-jslint-jenkins-using-ant-on-jenkins-for-jslint -->
    <!-- TODO bug report: https://code.google.com/p/jslint4java/issues/detail?id=101 -->
    <property name="jslint.jar"     value="lib/jslint4java-2.0.5.jar"/>
    <taskdef name="jslint" 
             classname="com.googlecode.jslint4java.ant.JSLintTask"
             classpath="${jslint.jar}" />
    <property name="jslint.options" value="white"/>
    <!-- unused options: ass,bitwise,browser,closure,continue,debug,devel,eqeq,es5,evil,forin,indent,maxerr,maxlen,newcap,node,nomen,passfail,plusplus,predef,properties,regexp,rhino,sloppy,stupid,sub,todo,unparam,vars,warnings, -->

    <!-- https://github.com/fge/json-schema-validator -->
    <!-- https://stackoverflow.com/questions/22867521/how-to-run-json-schema-validator-from-the-command-line -->
    <!-- fix double-hyphen switch when running on command line: -->
    <!-- java -jar lib/json-schema-validator-2.2.6-lib.jar - -help -->
    <!-- java -jar lib/json-schema-validator-2.2.6-lib.jar - -syntax ../../specifications/x3d-3.3-JSONSchema.json -->
    <!-- java -jar lib/json-schema-validator-2.2.6-lib.jar ../../specifications/x3d-3.3-JSONSchema.json test/HelloWorld.json -->
    <!-- https://github.com/java-json-tools/json-schema-validator/issues/287#issuecomment-543603403 -->
    <!-- https://github.com/java-json-tools/json-schema-validator/blob/master/README.md -->
    <!-- https://mvnrepository.com/artifact/com.github.java-json-tools/json-schema-validator -->
    <!-- trouble report json-schema-validator-2.2.11.jar at https://github.com/java-json-tools/json-schema-validator/issues/287#issuecomment-544100447 -->
    <property name="json-schema-validator.jar"     value="lib/json-schema-validator-2.2.6-lib.jar"/>
    
    <!-- Alternate validation library candidate: https://github.com/everit-org/json-schema -->
    <!-- TODO stable ant invocation needed, see  https://github.com/everit-org/json-schema/issues/257 -->

    <!-- https://stackoverflow.com/questions/919692/how-to-execute-xslt-2-0-with-ant -->
    <!-- https://sourceforge.net/projects/saxon/files/Saxon-HE jar download handled in X3DJSAIL build -->
    <!-- https://github.com/Saxonica/Saxon-HE/tree/main/12/Java -->
    <!-- https://www.saxonica.com/documentation10/#!about/gettingstarted/gettingstartedjava -->
    <!-- SaxonHE 11 (java.lang.NoClassDefFoundError: org/xmlresolver/Resolver) https://saxonica.plan.io/boards/3/topics/8478?r=8480 -->
    <property name="saxon.dir"         location="lib" description="relative path from stylesheets directory"/>
    <!-- previously saxon-he-12.5.jar, saxon-he-12.4.jar saxon-he-11.4.jar saxon-he-11.3.jar saxon-he-11.2.jar saxon-he-10.6.jar saxon9he.jar -->
    <property name="saxon.jar"            value="saxon-he-12.8.jar"/>
    <property name="xmlresolver.jar"      value="xmlresolver-5.3.3.jar"/><!-- required with saxon-he-11+.jar -->
    <property name="xmlresolver-data.jar" value="xmlresolver-5.3.3-data.jar"/><!-- provided with saxon-he-11+.jar -->
    <property name="jline.jar"            value="jline-2.14.6.jar"/>
    <property name="saxon.classpath"      value="${saxon.dir}/${saxon.jar};${saxon.dir}/${jline.jar};${saxon.dir}/${xmlresolver.jar};${saxon.dir}/${xmlresolver-data.jar};."/>
    
    <property name="jsai.full.archive.jar.name"     value="X3DJSAIL.4.0.full.jar"/>
    
    <!-- no need to set path since Python installation adds at top of system PATH environment variable -->
    <property name=   "python" value="python" description="local executable"/>
    
    <property name=   "node.exe" value="node.exe"/>

    <!-- http://openexi.sourceforge.net -->
    <!-- https://sourceforge.net/projects/openexi/files -->
    <property name="openexi.dir"      value="C:\languages\java\openexi-code\trunk\nagasena\build" description="local development path"/>
    <!-- updates in local lib directory are copied when building jar -->
    <property name="nagasena.jar"     value="nagasena.jar"/>
    <property name="nagasena-rta.jar" value="nagasena-rta.jar"/>
    
    <!-- https://exificient.github.io/java -->
    <!-- https://exificient.github.io/java/exificient-gui-jar-with-dependencies.jar -->
    <property name="exificient.dir" value="C:\languages\java\exificient-code\exificient-gui\target" description="local development path"/>
    <property name="exificient.jar" value="exificient-gui-jar-with-dependencies.jar"/>
    
    <!-- X3D Canonicalization (C14N) -->
    <property name="c14n.dir"        value="../tools/canonical/dist/lib"              description="local development path"/>
    <property name="c14n.jar"        value="X3dC14n.jar"/>

    <property name="stylesheets.dir" location="."/>

    <!-- ant jar manifest properties -->
    <property name="user.name.build" value="Don Brutzman, don.brutzman@gmail.com"/>

    <target name="get.saxon" description="get saxon.jar if not checked out" depends="get.saxon.check" unless="${saxon.found}"> 
        <echo message="get tested saxon.jar from project version control if not already checked out locally"/>
        <mkdir dir="${saxon.dir}"/>
        <get src="https://svn.code.sf.net/p/x3d/code/www.web3d.org/x3d/tools/jar/${saxon.jar}"
             dest="${saxon.dir}/${saxon.jar}" verbose="true" failonerror="false" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <get src="https://svn.code.sf.net/p/x3d/code/www.web3d.org/x3d/tools/jar/${xmlresolver.jar}"
             dest="${saxon.dir}/${xmlresolver.jar}" verbose="true" failonerror="false" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <get src="https://svn.code.sf.net/p/x3d/code/www.web3d.org/x3d/tools/jar/${xmlresolver-data.jar}"
             dest="${saxon.dir}/${xmlresolver-data.jar}" verbose="true" failonerror="false" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <get src="https://svn.code.sf.net/p/x3d/code/www.web3d.org/x3d/tools/jar/${ saxon-jline.jar}"
             dest="${saxon.dir}/${ saxon-jline.jar}" verbose="true" failonerror="false" ignoreerrors="${ignoreSetupDownloadErrors}"/>
    </target>
    <target name="get.saxon.check">
        <condition property="saxon.found" else="false">
            <and>
                <available file="${saxon.dir}/${saxon.jar}"/>
                <available file="${saxon.dir}/${xmlresolver.jar}"/>
                <available file="${saxon.dir}/${xmlresolver-data.jar}"/>
                <available file="${saxon.dir}/${saxon-jline.jar}"/>
            </and>
        </condition>
        <echo message="found ${saxon.dir}/${saxon.jar}, ${xmlresolver.jar}, ${xmlresolver-data.jar} and ${saxon-jline.jar}: ${saxon.found}"/>
    </target>
    
    <target name="versions" description="show tool versions and environment values">
        <echo>=============</echo>
        <echo>ant -version</echo>
        <exec executable="ant" dir="." vmlauncher="false">
            <arg value="-version"/>
        </exec>
        <echo message="NetBeans ant directory is set under Tools > Options > Java"/>
        <echo>which ant</echo>
        <exec executable="which" dir="." vmlauncher="false">
            <arg value="ant"/>
        </exec>
        <echo>=============</echo>
        <echo>java -version</echo>
        <exec executable="java" dir="." vmlauncher="false">
            <arg value="-version"/>
        </exec>
        <echo>which java</echo>
        <exec executable="which" dir="." vmlauncher="false">
            <arg value="java"/>
        </exec>
        <echo>=============</echo>
        <echo>python -version</echo>
        <exec executable="${python}" dir="." vmlauncher="false">
            <arg value="--version"/>
        </exec>
        <echo>which python</echo>
        <exec executable="which" dir="." vmlauncher="false">
            <arg value="python"/>
        </exec>
        <echo>=============</echo>
        <!-- https://www.saxonica.com/documentation12/index.html#!using-xsl/commandline -->
        <echo>saxon -? help</echo>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.classpath}" failonerror="true">
            <arg value="-?" description="help information"/>
        </java>
        <!-- <echo>$saxon.classpath=${saxon.classpath}</echo> -->
        <echo>$saxon.dir=${saxon.dir}</echo>
        <echo>=============</echo>
        <echo>System environment variables:</echo>
        <!-- Ant environment variables https://ant.apache.org/manual/Tasks/property.html -->
        <echo>  ANT_HOME=${env.ANT_HOME}</echo>
        <echo> JAVA_HOME=${env.JAVA_HOME}</echo>
        <echo>PYTHONPATH=${env.PYTHONPATH}</echo>
    <!--<echo>USER      =${env.USER}</echo> -->
        <!-- https://stackoverflow.com/questions/949678/ant-is-using-wrong-java-version -->
        <echo>javac source version     $java.source=${java.source}</echo>
        <echo>Java/JVM version    $ant.java.version=${ant.java.version}</echo>
        <echo>Java/JVM detail version $java.version=${java.version}</echo>
        <echo>Ant version              $ant.version=${ant.version}</echo>
        <echo>=============</echo>
        <echo>Check for node.js installation from https://nodejs.org</echo>
        <exec executable="${node.exe}">
            <arg value="--version"/>
        </exec>
        <echo>=============</echo>
        <echo>Check for locally bundled copy of X3DJSAIL at ${jsai.full.archive.jar.name}</echo>
        <echo>CLASSPATH=${env.CLASSPATH}</echo>
        <echo>java java/jars/${jsai.full.archive.jar.name} -version</echo>
        <java jar="java/jars/${jsai.full.archive.jar.name}" fork="${fork}">
            <arg value="-version" description="log report"/>
        </java>
        <echo>Further detail on configuration settings:  https://www.web3d.org/x3d/content/examples/X3dDevelopersGuide.html</echo>
        <!-- DEBUG: in order to show all environment and local properties, add
        <echoproperties/> -->
        <!-- TODO NetBeans version -->
        <!-- TODO NetBeans project version -->
        <echo message="==========================================="/>
    </target>

    <xmlcatalog id="X3dCatalog">
        <dtd    publicId="ISO//Web3D//DTD X3D 3.0//EN"                                   location="../../../../specifications/x3d-3.0.dtd"/>
        <dtd    publicId="ISO//Web3D//DTD X3D 3.1//EN"                                   location="../../../../specifications/x3d-3.1.dtd"/>
        <dtd    publicId="ISO//Web3D//DTD X3D 3.2//EN"                                   location="../../../../specifications/x3d-3.2.dtd"/>
        <dtd    publicId="ISO//Web3D//DTD X3D 3.3//EN"                                   location="../../../../specifications/x3d-3.3.dtd"/>
        <dtd    publicId="ISO//Web3D//DTD X3D 4.0//EN"                                   location="../../../../specifications/x3d-4.0.dtd"/>
        <dtd    publicId="ISO//Web3D//DTD X3D 4.1//EN"                                   location="../../../../specifications/x3d-4.1.dtd"/>
        <dtd    publicId="http://www.web3D.org/specifications/x3d-3.0.dtd"               location="../../../../specifications/x3d-3.0.dtd"/>
        <dtd    publicId="http://www.web3D.org/specifications/x3d-3.1.dtd"               location="../../../../specifications/x3d-3.1.dtd"/>
        <dtd    publicId="http://www.web3D.org/specifications/x3d-3.2.dtd"               location="../../../../specifications/x3d-3.2.dtd"/>
        <dtd    publicId="http://www.web3D.org/specifications/x3d-3.3.dtd"               location="../../../../specifications/x3d-3.3.dtd"/>
        <dtd    publicId="http://www.web3D.org/specifications/x3d-4.0.dtd"               location="../../../../specifications/x3d-4.0.dtd"/>
        <dtd    publicId="http://www.web3D.org/specifications/x3d-4.1.dtd"               location="../../../../specifications/x3d-4.1.dtd"/>
        <entity publicId="http://www.web3D.org/specifications/x3d-3.0.xsd"               location="../../../../specifications/x3d-3.0.xsd"/>
        <entity publicId="http://www.web3D.org/specifications/x3d-3.1.xsd"               location="../../../../specifications/x3d-3.1.xsd"/>
        <entity publicId="http://www.web3D.org/specifications/x3d-3.2.xsd"               location="../../../../specifications/x3d-3.2.xsd"/>
        <entity publicId="http://www.web3D.org/specifications/x3d-3.3.xsd"               location="../../../../specifications/x3d-3.3.xsd"/>
        <dtd    publicId="http://www.web3D.org/specifications/x3d-4.0.dtd"               location="../../../../specifications/x3d-4.0.dtd"/>
        <dtd    publicId="http://www.web3D.org/specifications/x3d-4.1.dtd"               location="../../../../specifications/x3d-4.1.dtd"/>
        <dtd    publicId="https://www.web3D.org/specifications/x3d-3.0.dtd"              location="../../../../specifications/x3d-3.0.dtd"/>
        <dtd    publicId="https://www.web3D.org/specifications/x3d-3.1.dtd"              location="../../../../specifications/x3d-3.1.dtd"/>
        <dtd    publicId="https://www.web3D.org/specifications/x3d-3.2.dtd"              location="../../../../specifications/x3d-3.2.dtd"/>
        <dtd    publicId="https://www.web3D.org/specifications/x3d-3.3.dtd"              location="../../../../specifications/x3d-3.3.dtd"/>
        <dtd    publicId="http://www.web3D.org/specifications/x3d-4.0.dtd"               location="../../../../specifications/x3d-4.0.dtd"/>
        <dtd    publicId="http://www.web3D.org/specifications/x3d-4.1.dtd"               location="../../../../specifications/x3d-4.1.dtd"/>
        <entity publicId="https://www.web3D.org/specifications/x3d-3.0.xsd"              location="../../../../specifications/x3d-3.0.xsd"/>
        <entity publicId="https://www.web3D.org/specifications/x3d-3.1.xsd"              location="../../../../specifications/x3d-3.1.xsd"/>
        <entity publicId="https://www.web3D.org/specifications/x3d-3.2.xsd"              location="../../../../specifications/x3d-3.2.xsd"/>
        <entity publicId="https://www.web3D.org/specifications/x3d-3.3.xsd"              location="../../../../specifications/x3d-3.3.xsd"/>
        <entity publicId="https://www.web3D.org/specifications/x3d-4.0.xsd"              location="../../../../specifications/x3d-4.0.xsd"/>
        <entity publicId="https://www.web3D.org/specifications/x3d-4.1.xsd"              location="../../../../specifications/x3d-4.1.xsd"/>
        <!-- Transitional DTD, versions 3.1 and 3.1 only -->
        <dtd    publicId="file:///www.web3d.org/TaskGroups/x3d/translation/x3d-3.0.dtd"  location="../../../../specifications/x3d-3.0.dtd"/>
        <dtd    publicId="file:///www.web3d.org/TaskGroups/x3d/translation/x3d-3.1.dtd"  location="../../../../specifications/x3d-3.1.dtd"/>
    </xmlcatalog>

    <property name="examples.dir"       location="../content/examples"/>
    <property name="semantics.dir"      location="../../semantics"/>
    <property name="specifications.dir" location="../../specifications"/>
    <property name="X3dDtdsSchemas.dir" location="../../specifications"/>
    <!-- Current official X3D Schema source file is version 4.0, development testing underway for 4.1 -->
    <property name="X3dSchemaSource"    value="x3d-4.1.xsd"/>
    <property name="X3dSchemaSource4.1" value="x3d-4.1.xsd"/>
    <property name="X3dSchemaSource4.0" value="x3d-4.0.xsd"/>
    <property name="X3dSchemaSource3.3" value="x3d-3.3.xsd"/>
    <property name="X3dSchemaSource3.2" value="x3d-3.2.xsd"/>
    <property name="X3dSchemaSource3.1" value="x3d-3.1.xsd"/>
    <property name="X3dSchemaSource3.0" value="x3d-3.0.xsd"/>
    <!-- Current official X3D Unified Object Model (X3DUOM) source file is version 4.0, development testing underway for 4.1 -->
    <property name="X3dUnifiedObjectModel"    value="X3dUnifiedObjectModel-4.1.xml"/><!-- default for X3DJSAIL -->
    <property name="X3dUnifiedObjectModel4.1" value="X3dUnifiedObjectModel-4.1.xml"/>
    <property name="X3dUnifiedObjectModel4.0" value="X3dUnifiedObjectModel-4.0.xml"/>
    <property name="X3dUnifiedObjectModel3.3" value="X3dUnifiedObjectModel-3.3.xml"/>
    <property name="X3dUnifiedObjectModel3.2" value="X3dUnifiedObjectModel-3.2.xml"/>
    <property name="X3dUnifiedObjectModel3.1" value="X3dUnifiedObjectModel-3.1.xml"/>
    <property name="X3dUnifiedObjectModel3.0" value="X3dUnifiedObjectModel-3.0.xml"/>
    <property name="X3duomGlossary4.1" value="glossary"/><!-- add .xml .xsd .html; matches X3D 4.1 spec -->
    <property name="X3duomGlossary4.0" value="glossary"/><!-- add .xml .xsd .html; matches X3D 4.0 spec -->

    <!-- target tasks ===================================================================== -->

    <target name="all" depends="versions,build,upload,upload.SpecificationInterfaces" description="build, upload XSLT stylesheets and X3dSpecificationInterfaces page">
    </target>

    <target name="all.X3DJSAIL" depends="clean.X3DJSAIL,create.X3DJSAIL" description="clean, build, test X3DJSAIL"/>
    
    <target name="build" 
            depends="validate,BuildX3dUnifiedObjectModel.saxon.all,BuildSpecificationXmlEncodingFromSchema.saxon,BuildSpecificationVrmlEncodingFromSchema.saxon,BuildSpecificationLanguageBindingJava.saxon,test,BuildAllX3dElementsAttributes.txt,zip.X3dToXhtmlStylesheetExamples"
            description="compile and test XSLT stylesheets">
    </target>

    <target name="diagnostics" description="Ant diagnostics, shows jars and classpaths">
        <diagnostics/>
        <!-- Hudson project description:
    <p>
    This project runs the
    <a href="http://ant.apache.org/manual/Tasks/diagnostics.html">Ant diagnostics</a>
    command on the SavageDefense Hudson server.  This task documents all local ant settings and environment variables.
    </p>
    <p>
    Additional information about
    <a href="http://ant.apache.org">Ant</a>
    is available via the
    <a href="http://ant.apache.org/manual">Ant Manual</a>.
    </p>
    <p>
    Additional information about this
    <a href="http://hudson-ci.org">Hudson</a>
    server is available under the top-level
    <a href="../../manage">Manage Hudson</a>
    command, specifically
    <a href="../../systemInfo">System Information (Properties)</a>
    and
    <a href="../../log">System Log Recorders</a>.
    </p>
        -->
    </target>
	
    <!-- ensure backwards compatibility to specified version of Java -->
    <!-- https://stackoverflow.com/questions/66068153/java-warning-options-system-modules-path-not-set-in-conjunction-with-source -->
    <property name="java.source"                 value="17"/><!-- 1.8 is strictest, 15 or higher allows use of """text blocks""" for Script CDATA -->
    <property name="java.target"                 value="17"/><!-- 17 is LTS -->
    <!-- TODO compiler bug, java source and target 17 not supported as advertised -->
    
    <property name="javac.verbose"               value="false"/>
    <property name="X3DJSAIL.relative.dir"       value="java"/>
    <property name="X3DJSAIL.classes.dir"     location="${X3DJSAIL.relative.dir}/classes"/>
    <property name="X3DJSAIL.examples.dir"    location="${X3DJSAIL.relative.dir}/examples"/>
    <property name="X3DJSAIL.jars.dir"        location="${X3DJSAIL.relative.dir}/jars"/>
    <property name="X3DJSAIL.lib.dir"         location="${X3DJSAIL.relative.dir}/lib"/>
    <property name="X3DJSAIL.src.dir"         location="${X3DJSAIL.relative.dir}/src"/>
    <property name="X3DSCHEMATRON.dir"        location="../tools/schematron"/>
    <property name="jaxb.dir"                 location="${X3DJSAIL.lib.dir}/support/jaxb" description="local path for JAXB directory"/>
    <property name="src.org.web3d.x3d.tests"     value="${X3DJSAIL.relative.dir}/tests"/>        <!-- tests -->
    <property name="nashorn.dir"                 value="nashorn"/>

    <property name="src.org.web3d.x3d.jsail"       value="${X3DJSAIL.src.dir}/org/web3d/x3d/jsail"/>      <!-- concretes  -->
    <property name="src.org.web3d.x3d.sai"         value="${X3DJSAIL.src.dir}/org/web3d/x3d/sai"/>        <!-- interfaces -->
    <property name="src.org.web3d.x3d.util"        value="${X3DJSAIL.src.dir}/org/web3d/x3d/util"/>       <!-- utilities  -->
    <property name="src.org.web3d.x3d.util.exi"    value="${X3DJSAIL.src.dir}/org/web3d/x3d/util/exi"/>   <!-- utilities EXI -->
    <property name="src.org.web3d.x3d.util.x3duom" value="${X3DJSAIL.src.dir}/org/web3d/x3d/util/x3duom"/><!-- JAXB-generated classes and X3DUOM classes -->
    <property name="jsai.classes.archive.jar.name" value="X3DJSAIL.4.0.classes.jar"/>
    <property name=  "jsail.full.archive.jar.name" value="X3DJSAIL.4.0.full.jar"/>
	
    <property name="javadoc.additionalparam" value=""/>
    <property name="javadoc.author"          value="Don Brutzman don.brutzman@gmail.com"/>
    <property name="javadoc.dir"             value="${X3DJSAIL.relative.dir}/javadoc"/>
    <property name="javadoc.encoding"        value="ISO-8859-1"/>
    <property name="javadoc.copyright"       value="Copyright &#169;2005-2026 &lt;a href='https://www.web3d.org'&gt;Web3D Consortium&lt;/a&gt; under an &lt;a href='../license.html'&gt;open-source license&lt;/a&gt; and free for any use. &lt;a href='mailto:x3d-public@web3D.org;don.brutzman@gmail.com?subject=X3DJSAIL%20Javadoc%20feedback'&gt;Feedback&lt;/a&gt; is welcome."/>
    <property name="javadoc.noindex"         value="false"/>
    <property name="javadoc.nonavbar"        value="false"/>
    <property name="javadoc.notree"          value="false"/>
    <property name="javadoc.private"         value="false"/>
    <property name="javadoc.source"          value="${java.source}"/>
    <property name="javadoc.splitindex"      value="true"/>
    <property name="javadoc.breakiterator"   value="true"/>
    <property name="javadoc.use"             value="true"/><!-- Create class and package usage pages -->
    <property name="javadoc.version"         value="true"/>
    <property name="javadoc.windowtitle"     value="X3DJSAIL Javadoc, X3D Java Scene Access Interface Library"/>
    <property name="javadoc.doctitle"        value="${javadoc.windowtitle}"/>
	
    <property name="junit5.dir"              location="${X3DJSAIL.relative.dir}/lib/support"   description="do not create local copies of junit for project"/>
    <property name="junit5.jupiter.dir"      location="${junit5.dir}/jupiter" description="do not create local copies of junit for project"/>
    <property name="junit5.site"                value="http://central.maven.org/maven2/org/junit" description="Maven repository"/>
    <property name="junit5.version"             value="1.5.0" description="latest supported version"/>
    <property name="jupiter.version"            value="5.6.0" description="latest supported version"/>
    <property name="opentest4j"                 value="opentest4j"/>
    <!-- opentest4j 1.1.1 failing -->
    <property name="opentest4j.version"         value="1.1.0" description="latest supported version"/>
    <property name="junit-platform-commons"     value="junit-platform-commons"/>
    <property name="junit-platform-engine"      value="junit-platform-engine"/>
    <property name="junit-platform-launcher"    value="junit-platform-launcher"/>
    <property name="junit-jupiter-api"          value="junit-jupiter-api"/>
    <property name="junit-jupiter-engine"       value="junit-jupiter-engine"/>
    
    <property name=   "castle-model-viewer.dir"    location="C:\Program Files\castle-model-viewer"/>
    <property name=   "castle-model-converter.exe"    value="castle-model-converter.exe"/>
	
    <path id="junit5.classpath">
        <fileset dir="${junit5.dir}">
            <include name="**/*.jar" />
        </fileset>
        <fileset dir="${junit5.jupiter.dir}">
            <include name="**/*.jar" />
        </fileset>
    </path>
	
    <!-- TODO debug/update -->
    <target name="get.junit5.jars" description="Get latest versions of JUnit5 .jar test suite">
        <ant antfile="java/build.xml" target="antVersionCheck"/>
        <echo message="get junit5 .jar files if not already available) and install in ANT_HOME/lib=${env.ANT_HOME}/lib"/>
        <echo message="Retrieving JUnit5 version ${junit5.version} and jupiter version ${jupiter.version}, note version number gets stripped from destination file name"/>
        <mkdir dir="${junit5.dir}"/>
        <mkdir dir="${junit5.dir}/jupiter"/>

        <!-- http://central.maven.org/maven2/org/junit/platform/junit-platform-commons/1.2.0/junit-platform-commons-1.2.0.jar -->
        <get src="${junit5.site}/platform/${junit-platform-commons}/${junit5.version}/${junit-platform-commons}-${junit5.version}.jar"
             dest="${junit5.dir}/${junit-platform-commons}.jar" verbose="true" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <get src="${junit5.site}/platform/${junit-platform-engine}/${junit5.version}/${junit-platform-engine}-${junit5.version}.jar"
                     dest="${junit5.dir}/${junit-platform-engine}.jar" verbose="true" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <get src="${junit5.site}/platform/${junit-platform-launcher}/${junit5.version}/${junit-platform-launcher}-${junit5.version}.jar"
                     dest="${junit5.dir}/${junit-platform-launcher}.jar" verbose="true" ignoreerrors="${ignoreSetupDownloadErrors}"/>
		
        <get src="http://central.maven.org/maven2/org/${opentest4j}/${opentest4j}/${opentest4j.version}/${opentest4j}-${opentest4j.version}.jar"
                     dest="${junit5.dir}/${opentest4j}-${opentest4j.version}.jar" verbose="true" ignoreerrors="${ignoreSetupDownloadErrors}"/>
		
        <!--  example http://central.maven.org/maven2/org/junit/jupiter/junit-jupiter-engine/5.2.0/junit-jupiter-engine-5.2.0.jar
        redirect from https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine/5.2.0/junit-jupiter-api.jar -->
        <!-- note that these go into the jupiter subdirectory -->
        <get src="${junit5.site}/jupiter/${junit-jupiter-api}/${jupiter.version}/${junit-jupiter-api}-${jupiter.version}.jar"
                     dest="${junit5.dir}/jupiter/${junit-jupiter-api}.jar" verbose="true" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <get src="${junit5.site}/jupiter/${junit-jupiter-engine}/${jupiter.version}/${junit-jupiter-engine}-${jupiter.version}.jar"
             dest="${junit5.dir}/jupiter/${junit-jupiter-engine}.jar" verbose="true" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        
        <echo message="bugfix: silence junit5 package warnings"/>
        <!-- https://github.com/junit-team/junit5/issues/1104 warning: unknown enum constant Status.STABLE while compiling org.junit.jupiter.api.Test -->
        <!-- https://mvnrepository.com/artifact/org.apiguardian/apiguardian-api/1.0.0 -->
        <!-- at   http://central.maven.org/maven2/org/apiguardian/apiguardian-api/1.0.0/apiguardian-api-1.0.0.jar -->
        <get src="http://central.maven.org/maven2/org/apiguardian/apiguardian-api/1.0.0/apiguardian-api-1.0.0.jar"
             dest="${junit5.dir}/apiguardian-api-1.0.0.jar" verbose="true" ignoreerrors="${ignoreSetupDownloadErrors}"/>
    </target>

    <target name="create.X3DPSAIL" depends="BuildX3dPythonPackageFromX3duom.saxon" description="Build API for X3D Python Scene Authoring Interface Library (X3DJSAIL) from X3D Unified Object Model (X3DUOM)" >
    </target>

    <target name="create.X3DJSAIL" depends="" description="Build API for X3D Java Scene Authoring Interface Library (X3DJSAIL) from X3D Unified Object Model (X3DUOM)" >
        <echo message="Build API for X3D Java Scene Authoring Interface Library (X3DJSAIL) from X3D Unified Object Model (X3DUOM)"/>
        <antcall target="versions"/>
        <echo message="clean prior autogenerated products, if any..."/>
        <!-- originating java.dir already exists and includes files in version control, so be careful to not delete everything! -->
        <!-- verbose="true" failonerror="false" -->
        <delete failonerror="false">
            <fileset dir="${src.org.web3d.x3d.jsail}">
                <include name="*"/>
                <include name="**/*.java"/>
                <include name="**/*.bak"/>
                <include name="**/*.$$$$$$"/>
                <exclude name="**/package.html"/>
            </fileset>
            <fileset dir="${src.org.web3d.x3d.sai}">
                <include name="*"/>
                <include name="**/*.java"/>
                <include name="**/*.bak"/>
                <include name="**/*.$$$$$$"/>
                <exclude name="**/package.html"/>
            </fileset>
            <fileset dir="${src.org.web3d.x3d.tests}">
                <!-- do not delete test cases! -->
                <include name="**/*.bak"/>
                <include name="**/*.$$$$$$"/>
                <exclude name="**/*.java"/>
            </fileset>
            <fileset dir="${X3DJSAIL.classes.dir}">
                <include name="**/*"/>
                <exclude name="**/license.*"/>
                <exclude name="**/README*.txt"/>
                <exclude name="index.html"/>
                <exclude name="**/X3DJSAIL.html"/>
            </fileset>
            <fileset dir="${javadoc.dir}">
                <include name="**/*"/>
            </fileset>
            <fileset dir="${X3DJSAIL.jars.dir}">
                <include name="**/*.jar"/>
            </fileset>
            <fileset dir="${X3DJSAIL.lib.dir}">
                <include name="**/*"/>
                <exclude name="README.lib.txt"/>
                <exclude name="index.html"/>
                <exclude name="**/*.jar"/>
            </fileset>
        </delete>
        <echo message="delete autogenerated test class SmokeTestProgramOutput.java"/>
        <delete file="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.java" verbose="true" failonerror="false"/>
        <echo message="delete autogenerated test class flowers7.java"/>
        <delete file="${X3DJSAIL.examples.dir}/flowers7.java" verbose="true" failonerror="false"/>
        
        <echo message="copy latest stylesheets:"/>
        <mkdir dir="${X3DJSAIL.lib.dir}/stylesheets"/>
        <!-- copying of local/latest updates is optional since the following files are in version control -->
        <copy file="${saxon.dir}/${saxon.jar}"                todir="${X3DJSAIL.lib.dir}"             force="true" verbose="true" failonerror="false"/>
        <copy file="${saxon.dir}/${xmlresolver.jar}"          todir="${X3DJSAIL.lib.dir}"             force="true" verbose="true" failonerror="false"/>
        <copy file="${saxon.dir}/${xmlresolver-data.jar}"     todir="${X3DJSAIL.lib.dir}"             force="true" verbose="true" failonerror="false"/>
        <copy file="${saxon.dir}/${saxon-jline.jar}"          todir="${X3DJSAIL.lib.dir}"             force="true" verbose="true" failonerror="false"/>
        <copy file=      "${c14n.dir}/${c14n.jar}"            todir="${X3DJSAIL.lib.dir}"             force="true" verbose="true" failonerror="false"/>
        <copy file="${exificient.dir}/${exificient.jar}"      todir="${X3DJSAIL.lib.dir}"             force="true" verbose="true" failonerror="false"/>
        <copy file=   "${openexi.dir}/${nagasena.jar}"        todir="${X3DJSAIL.lib.dir}"             force="true" verbose="true" failonerror="false"/>
        <copy file=   "${openexi.dir}/${nagasena-rta.jar}"    todir="${X3DJSAIL.lib.dir}"             force="true" verbose="true" failonerror="false"/>
        <copy file="X3dExtrusionCrossSectionToSvg.xslt"       todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/>
        <copy file="X3dToJava.xslt"                           todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/>
        <copy file="X3dToNodeJS.xslt"                         todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/>
        <copy file="X3dToJson.xslt"                           todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/>
        <copy file="X3dToPython.xslt"                         todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/>
        <copy file="X3dToVrml97.xslt"                         todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/>
        <copy file="X3dToX3dvClassicVrmlEncoding.xslt"        todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/>
        <copy file="X3dToX3domX_ITE.xslt"                          todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/> 
        <copy file="X3dToHtml.xslt"                           todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/>
        <copy file="X3dToXhtml.xslt"                          todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/>
        <copy file="${X3DSCHEMATRON.dir}/SvrlReportText.xslt" todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/>
        <copy file="${X3DSCHEMATRON.dir}/X3dSchematronValidityChecks.xslt"      
                                                              todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/>
        <copy file="X3dTidy.xslt"                             todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/>
        <copy file="X3dModelMetaToMarkdown.xslt"              todir="${X3DJSAIL.lib.dir}/stylesheets" force="true" verbose="true" failonerror="false"/>
        <!-- requires local copy of specifications directory -->
        <copy todir="${X3DJSAIL.lib.dir}/specifications" verbose="true" failonerror="false">
            <fileset dir="../../specifications" defaultexcludes="yes">
                <include name="*.xsd"/>
                <include name="x3d-schema-changelog.txt"/>
                <include name="X3dUnifiedObjectModel*.xml"/>
            </fileset>
        </copy>
        <echo message="System environment variable $env.CLASSPATH=${env.CLASSPATH}"/>
        <echo message="create autogenerated Java source code for X3DUOM using JAXB:"/>
        <antcall target="create.X3DUOM.JAXB.schema" inheritAll="true"/>
        <echo message="create autogenerated Java source code:"/>
        <!-- https://stackoverflow.com/questions/51916221/javax-xml-bind-jaxbexception-implementation-of-jaxb-api-has-not-been-found-on-mo -->
        <!-- https://stackoverflow.com/questions/48204141/replacements-for-deprecated-jpms-modules-with-java-ee-apis/48279048#48279048 -->
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}" failonerror="true">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:TempSaiJava.txt" description="output-doc"/>
            <arg value="-s:${specifications.dir}/${X3dUnifiedObjectModel}" description="source-doc"/>
            <arg value="-xsl:CreateX3dSceneAccessInterfaceJava.xslt" description="style-doc"/>
            <arg value="targetDirectory=${X3DJSAIL.relative.dir}"/> <!-- stylesheet parameter -->
        </java>
        <copy file="${X3DJSAIL.relative.dir}/X3DJSAIL.html"  tofile="${src.org.web3d.x3d.sai}/overview.html" verbose="true" failonerror="true"/>
        <!-- precise cleanup of directories occurred earlier -->
        <!-- empty classpath to ensure internal consistency of package compilation -->
        <echo message="Compiling ${src.org.web3d.x3d.sai} interfaces"/>
        <mkdir  dir="${X3DJSAIL.classes.dir}"/>
        <!-- avoid warning by using -release rather than -source and -target, https://ant.apache.org/manual/Tasks/javac.html -->
        <javac   srcdir="${src.org.web3d.x3d.sai}"
                destdir="${X3DJSAIL.classes.dir}"
              classpath=""
                  debug="on"
               encoding="UTF-8"
                release="${java.source}"
                verbose="${javac.verbose}"
                includeantruntime="false">
            <!-- -Xlint reports problems with no definition of serialVersionUID
            <compilerarg value="-Xlint:all"/>
            -->
            <!-- https://stackoverflow.com/questions/1554538/how-can-i-suppress-javac-warnings-about-deprecated-api -->
            <compilerarg value="-Xlint:deprecation"/>
            <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap -->
            <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac -->
            <!-- https://stackoverflow.com/questions/20174355/how-class-loading-is-done-by-using-xbootclasspath-ppath -->
            <!-- https://stackoverflow.com/questions/48148607/how-to-add-a-jar-to-the-boot-classpath-in-java-9 -->
            <!-- -Xbootclasspath/p became -Xbootclasspath/a in jdk 9 -->
            <!-- <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> not allowed with target 15 -->
        </javac>
        <!-- compiling interfaces must precede concrete classes -->
        <echo message="Compiling org.web3d.x3d.jsail, .util.exi, and .util.x3duom concrete classes"/>
        <!-- avoid warning by using -release rather than -source and -target, https://ant.apache.org/manual/Tasks/javac.html -->
        <javac  destdir="${X3DJSAIL.classes.dir}"
                  debug="on"
               encoding="UTF-8"
                release="${java.source}"
                verbose="${javac.verbose}"
      includeantruntime="false">
            <src path="${src.org.web3d.x3d.jsail}"/>
            <src path="${src.org.web3d.x3d.util.exi}"/>
            <src path="${src.org.web3d.x3d.util.x3duom}"/>
            <!-- -Xlint reports problems (mysteriously) with missing numbered versions of included lib/*.jar files, perhaps from other jars
            <compilerarg value="-Xlint:all"/>
            -->
            <!-- https://stackoverflow.com/questions/1554538/how-can-i-suppress-javac-warnings-about-deprecated-api -->
            <compilerarg value="-Xlint:deprecation"/>
            <classpath>
                <fileset dir="${X3DJSAIL.lib.dir}">
                    <include name="*.jar"/>
                    <include name="lib/*.jar"/><!-- saxon lib jars including xmlresolver -->
                    <!-- SaxonHE 11 (java.lang.NoClassDefFoundError: org/xmlresolver/Resolver) https://saxonica.plan.io/boards/3/topics/8478?r=8480 -->
                    <include name="support/jaxb/*.jar"/>
                </fileset>
            </classpath>
            <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap -->
            <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac -->
            <!-- https://stackoverflow.com/questions/20174355/how-class-loading-is-done-by-using-xbootclasspath-ppath -->
            <!-- https://stackoverflow.com/questions/48148607/how-to-add-a-jar-to-the-boot-classpath-in-java-9 -->
            <!-- -Xbootclasspath/p became -Xbootclasspath/a in jdk 9 -->
            <!-- <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> not allowed with target 15 -->
        </javac>
        <echo message="Compiling org.web3d.x3d.java test classes, two different ways:"/>
        <antcall target="compile.X3DJSAIL.tests"/>
        <ant dir="java" antfile="build.xml" target="compile.examples" inheritAll="false"/>
        <antcall target="create.X3DJSAIL.javadoc"/>
        <antcall target="create.X3DJSAIL.jars"/>
        <echo message="create.X3DJSAIL complete"/>
    </target>
	
    <target name="compile.examples.java">
        <echo message="delete *.class bytecode..."/>
        <delete verbose="true" failonerror="false">
            <fileset dir="${X3DJSAIL.examples.dir}">
                <include name="New3dModel.class"/>
                <include name="SmokeTestProgram.class"/>
            </fileset>
        </delete>
        <echo message="compile SmokeTestProgram.java source... ${X3DJSAIL.examples.dir}"/>
        <!-- avoid warning by using -release rather than -source and -target, https://ant.apache.org/manual/Tasks/javac.html -->
        <javac   srcdir="${X3DJSAIL.examples.dir}"
                destdir="${X3DJSAIL.examples.dir}"
              classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};"
                  debug="on"
               encoding="UTF-8"
                release="${java.source}"
                verbose="${javac.verbose}"
      includeantruntime="false" fork="${fork}">
        <!--<include name="NewX3dModel.java"/>-->
            <include name="SmokeTestProgram.java"/>
            <exclude name="SmokeTestProgramOutput.java"/>
            <!-- -Xlint reports problem with direct object invocation of .isNode() or isStatement()
            <compilerarg value="-Xlint:all"/> -->
            <!-- https://stackoverflow.com/questions/1554538/how-can-i-suppress-javac-warnings-about-deprecated-api -->
            <compilerarg value="-Xlint:deprecation"/>
            <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap -->
            <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac -->
            <!-- https://stackoverflow.com/questions/20174355/how-class-loading-is-done-by-using-xbootclasspath-ppath -->
            <!-- https://stackoverflow.com/questions/48148607/how-to-add-a-jar-to-the-boot-classpath-in-java-9 -->
            <!-- -Xbootclasspath/p became -Xbootclasspath/a in jdk 9 -->
            <!-- <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> not allowed with target 15 -->
        </javac>
    </target>
        
    <target name="compile.X3DJSAIL.tests">
        <!-- TODO fix problem requiring full rebuild, rather than this target -->
        <echo message="Compiling test classes at ${src.org.web3d.x3d.tests}"/>
        <!-- avoid warning by using -release rather than -source and -target, https://ant.apache.org/manual/Tasks/javac.html -->
        <javac   srcdir="${src.org.web3d.x3d.tests}"
                destdir="${X3DJSAIL.classes.dir}" 
              classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}"
                  debug="on"
               encoding="UTF-8"
                release="${java.source}"
                verbose="${javac.verbose}"
      includeantruntime="false"
            failonerror="false"><!-- permit library recompilation to continue even if unit tests fail during development -->
            <classpath refid="junit5.classpath"/><!-- includes jupiter subdirectory -->
            <!-- -Xlint reports problems (mysteriously) with missing numbered versions of included lib/*.jar files, perhaps from other jars
            <compilerarg value="-Xlint:all"/>
            -->
            <!-- https://stackoverflow.com/questions/1554538/how-can-i-suppress-javac-warnings-about-deprecated-api -->
            <compilerarg value="-Xlint:deprecation"/>
            <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap -->
            <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac -->
            <!-- https://stackoverflow.com/questions/20174355/how-class-loading-is-done-by-using-xbootclasspath-ppath -->
            <!-- https://stackoverflow.com/questions/48148607/how-to-add-a-jar-to-the-boot-classpath-in-java-9 -->
            <!-- -Xbootclasspath/p became -Xbootclasspath/a in jdk 9 -->
            <!-- <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> not allowed with target 15 -->
        </javac>
    </target>
	
    <target name="create.X3DJSAIL.javadoc">
        <echo message="Preparing javadoc:"/>
        <delete dir="${javadoc.dir}" failonerror="false"/>
        <mkdir  dir="${javadoc.dir}"/>
        <copy file="${X3DJSAIL.relative.dir}/X3DJSAIL.html" tofile="${src.org.web3d.x3d.sai}/overview.html" verbose="true" failonerror="true"/>
        <!-- javadoc options https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html 
                             https://docs.oracle.com/en/java/javase/16/docs/specs/javadoc/doc-comment-spec.html -->
        <javadoc     destdir="${javadoc.dir}"
                      author="${javadoc.author}"
                      bottom="${javadoc.copyright}"
               breakiterator="${javadoc.breakiterator}"
                   classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}"
                    doctitle="${javadoc.doctitle}"
                    encoding="${javadoc.encoding}"
                 failonerror="false"
               failonwarning="false"
                      header="${javadoc.doctitle}"
                     noindex="${javadoc.noindex}"
                    nonavbar="${javadoc.nonavbar}"
                      notree="${javadoc.notree}"
                    Overview="java/src/overview.html"
                     private="${javadoc.private}"
                      source="${javadoc.source}"
                  splitindex="${javadoc.splitindex}"
                         use="${javadoc.use}"
             useexternalfile="true"
                     verbose="${javac.verbose}"
                     version="${javadoc.version}"
                 windowtitle="${javadoc.windowtitle}">
            <!--
                    helpfile="do not override"
            -->
        <!-- problem with javadoc frames being taken away but no replacement offered:
             https://stackoverflow.com/questions/51992347/missing-iframe-view-for-javadocs-jdk-11-12
             https://bugs.openjdk.java.net/browse/JDK-8202961
             https://openjdk.java.net/groups/compiler/javadoc-architecture.html
                 
             https://docs.oracle.com/en/java/javase/13/tools/javadoc.html
             https://docs.oracle.com/en/java/javase/13/javadoc/javadoc.html
             https://stackoverflow.com/questions/624422/how-do-i-document-packages-in-java
        -->
            <!-- <arg value="- -frames"/> --><!-- enable frames in javadoc output, JDK 11-12 -->
            <!-- <arg value='-keywords="X3D X3Dv4 X3DJSAIL"'/> -->
            <classpath>
                <fileset dir="${X3DJSAIL.lib.dir}">
                    <include name="**/*.jar"/>
                </fileset>
            </classpath>
            <classpath refid="junit5.classpath"/><!-- includes jupiter subdirectory -->
            <fileset dir="${src.org.web3d.x3d.sai}" defaultexcludes="yes">
                <include name="*.java"/>
                <include name="**/*.java"/>
                <exclude name="**/*.html"/>
            </fileset>
            <fileset dir="${src.org.web3d.x3d.jsail}" defaultexcludes="yes">
                <include name="*.java"/>
                <include name="**/*.java"/>
                <exclude name="**/*.html"/>
            </fileset>
            <!-- TODO test classes not appearing?? -->
            <!-- https://stackoverflow.com/questions/45160647/include-link-to-unit-test-classes-in-javadoc -->
            <fileset dir="${src.org.web3d.x3d.tests}" defaultexcludes="yes">
                <include name="*.java"/>
                <include name="**/*.java"/>
                <exclude name="**/*.html"/>
            </fileset>
            <fileset dir="${src.org.web3d.x3d.util}" defaultexcludes="yes">
                <include name="*.java"/>
                <include name="**/*.java"/>
                <exclude name="**/*.html"/>
            </fileset>
			
            <!-- previous switches
       maxmemory="4096m"
             useexternalfile="yes" explained at:
             https://stackoverflow.com/questions/10519558/createprocess-error-206-the-filename-or-extension-is-too-long-when-running-main

      sourcepath="${src.org.web3d.x3d.sai}"
 useexternalfile="true"
<classpath refid="app.classpath"/>
    <include name="*/*.java"/>
            <packageset dir="${src.org.web3d.x3d.sai}" defaultexcludes="yes">
                            <include name="*.java"/>
                            <include name="*/*.java"/>
                            <exclude name="**/*.html"/>
            </packageset>
            -->
            <!--
                    <fileset dir="${src.org.web3d.x3d.sai}" defaultexcludes="yes">
                            <include name="*.java"/>
                            <exclude name="**/*.html"/>
                    </fileset>
                    <fileset dir="${src.org.web3d.x3d.sai}" defaultexcludes="yes">
                            <include name="BrowserEvent.java"/>
                            <include name="BrowserFactory.java"/>
                            <include name="BrowserFactoryImpl.java"/>
                            <include name="BrowserListener.java"/>
                            <include name="BrowserNotSharedException.java"/>
                            <include name="ComponentInfo.java"/>
                            <include name="ConnectionException.java"/>
                            <include name="ExternalBrowser.java"/>
                            <include name="ImportedNodeException.java"/>
                            <include name="InsufficientCapabilitiesException.java"/>
                            <include name="InvalidBrowserException.java"/>
                            <include name="InvalidDocumentException.java"/>
                            <include name="InvalidExecutionContextException.java"/>
                            <include name="InvalidFieldException.java"/>
                            <include name="InvalidFieldValueException.java"/>
                            <include name="InvalidNodeException.java"/>
                            <include name="InvalidOperationTimingException.java"/>
                            <include name="InvalidProtoException.java"/>
                            <include name="InvalidRouteException.java"/>
                            <include name="InvalidURLException.java"/>
                            <include name="InvalidX3DException.java"/>
                            <include name="NodeInUseException.java"/>
                            <include name="NodeUnavailableException.java"/>
                            <include name="NoSuchBrowserException.java"/>
                            <include name="NotSupportedException.java"/>
                            <include name="ProfileInfo.java"/>
                            <include name="UnitInfo.java"/>
                            <include name="URLUnavailableException.java"/>
                            <include name="X3DComponent.java"/>
                            <include name="X3DException.java"/>
                    </fileset>
            -->
        </javadoc>
        <copy todir="${javadoc.dir}" verbose="true" failonerror="false"><!-- -->
            <fileset dir="." defaultexcludes="yes">
                <include name="license.*"/>
                <include name="README.txt"/>
                <include name="images/*.gif"/>
                <include name="images/*.png"/>
            </fileset>
        </copy>
		
        <!--
                                        <include name="Matrix3.java"/>
                                        <include name="Matrix4.java"/>
                                        <include name="MFBool.java"/>
                                        <include name="MFColor.java"/>
                                        <include name="MFColorRGBA.java"/>
                                        <include name="MFDouble.java"/>
                                        <include name="MFFloat.java"/>
                                        <include name="MField.java"/>
                                        <include name="MFImage.java"/>
                                        <include name="MFInt32.java"/>
                                        <include name="MFMatrix3d.java"/>
                                        <include name="MFMatrix3f.java"/>
                                        <include name="MFMatrix4d.java"/>
                                        <include name="MFMatrix4f.java"/>
                                        <include name="MFRotation.java"/>
                                        <include name="MFString.java"/>
                                        <include name="MFTime.java"/>
                                        <include name="MFVec2d.java"/>
                                        <include name="MFVec2f.java"/>
                                        <include name="MFVec3d.java"/>
                                        <include name="MFVec3f.java"/>
                                        <include name="MFVec4d.java"/>
                                        <include name="MFVec4f.java"/>
                                        
        <include name="SFBool.java"/>
        <include name="SFColor.java"/>
        <include name="SFColorRGBA.java"/>
        <include name="SFDouble.java"/>
        <include name="SFFloat.java"/>
        <include name="SFImage.java"/>
        <include name="SFInt32.java"/>
        <include name="SFMatrix3d.java"/>
        <include name="SFMatrix3f.java"/>
        <include name="SFMatrix4d.java"/>
        <include name="SFMatrix4f.java"/>
        <include name="SFRotation.java"/>
        <include name="SFString.java"/>
        <include name="SFTime.java"/>
        <include name="SFVec2d.java"/>
        <include name="SFVec2f.java"/>
        <include name="SFVec3d.java"/>
        <include name="SFVec3f.java"/>
        <include name="SFVec4d.java"/>
        <include name="SFVec4f.java"/>
        <include name="X3DField.java"/>
        <include name="X3DFieldDefinition.java"/>
        <include name="X3DFieldEvent.java"/>
        <include name="X3DFieldEventListener.java"/>
        <include name="X3DFieldTypes.java"/>
        -->
		
        <!-- TODO test suite
        <echo message="running test suite"/> -->
		
        <!-- TODO uploading
        <echo message="uploading products"/>
        <antcall target="uploadX3DJSAIL"/> -->
    </target>

    <target name="clean.X3DJSAIL.jars" depends="" description="Build X3DJSAIL jars" >
        <echo message="cleaning X3DJSAIL jar files"/>
        <delete dir="jars" verbose="true" failonerror="false">
            <fileset dir="${X3DJSAIL.jars.dir}">
                <include name="*"/>
            </fileset>
        </delete>
    </target>

    <target name="create.X3DJSAIL.jars" depends="" description="Build X3DJSAIL jars" >
        <!-- TODO jar files for each X3D version -->
        <!-- https://dzone.com/articles/what-is-jar-hell -->
        <!-- http://docs.oracle.com/javase/8/docs/technotes/guides/deploy/toc.html -->
        <echo message="preparing .jar files"/>
        <mkdir dir="${X3DJSAIL.jars.dir}"/>
        <!-- ===================================================================== -->
        <echo message="${jsai.classes.archive.jar.name} contains only compiled .class files and dependency jars"/>
        <jar destfile="${jsai.classes.archive.jar.name}" duplicate="fail" strict="warn">
            <!-- http://docs.oracle.com/javase/8/docs/technotes/guides/deploy/manifest.html -->
            <manifest id="ClassesJarManifest">
                <!-- Who is building this jar? -->
                <attribute name="Built-By" value="${user.name.build}"/>
                <!-- Information about the program itself -->
                <attribute name="Implementation-Vendor" value="Web3D Consortium https://www.web3D.org"/>
                <attribute name="Implementation-Title" value="X3DJSAIL X3D Java Scene Access Interface Library"/>
                <attribute name="Implementation-Version" value="4.0"/>
                <!-- Sealing Packages within a JAR File https://docs.oracle.com/javase/tutorial/deployment/jar/sealman.html -->
                <attribute name="Sealed" value="true"/>
            </manifest>
            <fileset dir="${X3DJSAIL.relative.dir}">
                <include name="*.txt"/>
                <include name="*.html"/>
                <exclude name="build/**/*"/><!-- TODO mysteriously caused by SmokeTestProgram.java testing -->
            </fileset>
            <fileset dir="${X3DJSAIL.classes.dir}">
                <include name="**/*.class"/>
                <include name="X3DJSAIL.properties"/>
                <!-- might need to avoid test cases to facilitate test debugging
                <exclude name="**/tests/**"/> -->
            </fileset>
            <fileset dir="${X3DJSAIL.src.dir}">
                <include name="**/tests/*.class"/>
            </fileset>
            <!-- lib, stylesheets -->
            <fileset dir="${X3DJSAIL.lib.dir}">
                <include name="lib/*.jar"/><!-- saxon lib jars including xmlresolver -->
                <!-- SaxonHE 11 (java.lang.NoClassDefFoundError: org/xmlresolver/Resolver) https://saxonica.plan.io/boards/3/topics/8478?r=8480 -->
                <include name="specifications/**"/>
                <include name="stylesheets/**"/>
                <!-- Note that no external-dependency jar files are included in this stripped-down jar -->
            </fileset>
            <fileset dir="${X3DJSAIL.src.dir}">
                <!-- python scripts for blender -->
                <include name="python/blenderScripts/*.py"/>
            </fileset>
        </jar>
        <!-- ===================================================================== -->
        <echo>(ensure that destination ${jsai.classes.archive.jar.name} is not already in use, for example a pending debugger session) </echo>
        <move file="${jsai.classes.archive.jar.name}"     todir="${X3DJSAIL.jars.dir}" verbose="true" failonerror="false"/>
        <length property="jsai.classes.archive.jar.length" file="${X3DJSAIL.jars.dir}/${jsai.classes.archive.jar.name}"/>
        <echo>Build .jar complete: ${jsai.classes.archive.jar.name} for Java SAI .class interfaces only (${jsai.classes.archive.jar.length} bytes) </echo>
        <!-- ===================================================================== -->
        <echo message="${jsail.full.archive.jar.name} contains all compiled .class files, all source .java files, and javadoc documentation"/>
        <echo message="${jsail.full.archive.jar.name} is a 'fat jar' that can be run independently on command line or elsewhere"/>
        <echo message="First create intermediate jar..."/>
        <!-- https://stackoverflow.com/questions/19150811/what-is-a-fat-jar -->
        <jar destfile="${jsail.full.archive.jar.name}.withSignatures" duplicate="preserve" strict="warn">
            <manifest id="IntermediateJarManifest">
                <attribute name="Implementation-Vendor" value="Web3D Consortium https://www.web3D.org"/>
                <attribute name="Implementation-Title" value="X3DJSAIL intermediate jar"/>
                <attribute name="Implementation-Version" value="4.0"/>
            </manifest>
            <!-- no need for manifest here, this is an intermediate jar. proper manifest added later. -->
            <!-- add mostly everything -->
            <fileset dir="${X3DJSAIL.relative.dir}">
                <include name="*.txt"/>
                <include name="*.html"/>
                <!-- not build -->
                <include name="draftJavaLanguageBindingAnnexes/**/*"/>
                <include name="images/**/*"/>
                <include name="javadoc/**/*"/>
                <include name="references/**/*"/>
                <include name="src/**/*"/>
                <!-- do not include examples in jar, since they evolve and we don't want jar overriding test of actual examples -->
                <exclude name="examples/**/*"/>
                <exclude name="**/*.class"/>
                <exclude name="**/~*"/>
                <exclude name="**/*.bak"/>
                <exclude name="**/*.$$$$$$"/>
                <exclude name="**/private/**"/>
                <exclude name="examples/images/SmokeTestProgramOutput/**"/>
                <exclude name="build/**/*"/><!-- TODO mysteriously caused by SmokeTestProgram.java testing -->
            </fileset>
            <fileset dir="${X3DJSAIL.classes.dir}">
                <include name="**/*.class"/>
                <include name="X3DJSAIL.properties"/> 
                <exclude name="**/python/**"/>
                <!-- might need to avoid test cases to facilitate test debugging
                <exclude name="**/tests/**"/>  -->
            </fileset>
            <fileset dir="${X3DJSAIL.src.dir}">
                <!-- include sources so that javadoc is available when using full jar -->
                <include name="**/*.java"/>
                <exclude name="python/jacoco/*"/>
                <exclude name="python/python.environment/*"/>
                <exclude name="python/pythonapi/*"/>
                <exclude name="python/pythonnet/*"/>
                <!-- python scripts for blender -->
                <include name="python/blenderScripts/*.py"/>
                <include name="python/blenderScripts/*.*"/><!-- test model and build file -->
                <!-- do not include python/blenderScripts/products/ subdirectory which is produced by build.xml examples -->
            </fileset>
            <!-- lib, stylesheets -->
            <fileset dir="${X3DJSAIL.lib.dir}">
                <include name="lib/*.jar"/><!-- saxon lib jars including xmlresolver -->
                <!-- SaxonHE 11 (java.lang.NoClassDefFoundError: org/xmlresolver/Resolver) https://saxonica.plan.io/boards/3/topics/8478?r=8480 -->
                <include name="specifications/**"/>
                <include name="stylesheets/**"/>
                <!-- lib jar dependencies are extracted and reintegrated in a later step -->
                <!-- TODO confirm that all licenses are preserved, renaming as necessary -->
            </fileset>
            <!-- nashorn -->
            <fileset dir="${X3DJSAIL.relative.dir}">
                <include name="${nashorn.dir}/**/*"/>
                <exclude name="${nashorn.dir}/test.bat"/>
                <exclude name="${nashorn.dir}/examples/**"/>
                <exclude name="${nashorn.dir}/**/*.class"/>
            </fileset>
            <!-- include all lib/*.jar dependencies for inclusion in sealed jar -->
            <zipgroupfileset dir="${X3DJSAIL.lib.dir}">
                <!-- https://stackoverflow.com/questions/24347301/class-classformaterror-absent-code-attribute-in-method-that-is-not-native -->
                <include name="*.jar"/> <!-- beware of additional jar conflicts (typically duplicate classes) that can lead to sealing violation errors at run time -->
                <include name="support/jaxb/istack-commons-runtime.jar"/> <!-- from jaxb-ri-2.3.1/jaxb-ri/mod -->
                <include name="support/jaxb/jaxb-api.jar"/>               <!-- from jaxb-ri-2.3.1/jaxb-ri/mod -->
                <include name="support/jaxb/jaxb-runtime.jar"/>           <!-- from jaxb-ri-2.3.1/jaxb-ri/mod -->
                
                <exclude name="javax.json-api-1.0.jar"/> <!-- already included in exificient, xerces -->
                <exclude name="jdom.jar"/>
                <exclude name="org/w3c/**/*"/> <!-- omit duplicated classes and interfaces already in exificient jar, further copies lead to run-time errors -->
                <!-- apparently unable to avoid inclusion, and so removed later...
                    <exclude name="META-INF/SAXONICA.DSA"/>
                    <exclude name="META-INF/SAXONICA.RSA"/>
                    <exclude name="META-INF/SAXONICA.SF"/>
                -->
            </zipgroupfileset>
        </jar>
        <!-- now remove prior signatures, which are no longer valid since other code products have been integrated.
                    to learn more about why removing signatures from integrated "fat" jar files is necessary:
        https://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar -->
        <!-- remove signatures from external jars: see "Have you tried using the zipfileset task?"
        https://stackoverflow.com/questions/2521231/ant-task-to-remove-files-from-a-jar -->
        <!-- zipfileset: https://ant.apache.org/manual/Tasks/zip.html and https://ant.apache.org/manual/Types/zipfileset.html -->
        <jar destfile="${jsail.full.archive.jar.name}" duplicate="preserve" strict="warn">
            <!-- http://docs.oracle.com/javase/8/docs/technotes/guides/deploy/manifest.html -->
            <manifest id="FullJarManifest">
                <!-- If this is an Applet or Web Start application, include
                     the proper attributes from http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/index.html
                <attribute name="Permissions" value="sandbox"/>
                <attribute name="Codebase" value="example.com"/> -->
                <!-- Who is building this jar? -->
                <attribute name="Built-By" value="${user.name.build}"/>
                <!-- Information about the program itself -->
                <attribute name="Implementation-Vendor" value="Web3D Consortium https://www.web3D.org"/>
                <attribute name="Implementation-Title" value="X3DJSAIL X3D Java Scene Access Interface Library"/>
                <attribute name="Implementation-Version" value="4.0"/>
                <!-- Sealing Packages within a JAR File https://docs.oracle.com/javase/tutorial/deployment/jar/sealman.html -->
                <!-- Sealing Packages in Extensions     https://docs.oracle.com/javase/tutorial/ext/security/sealing.html -->
                <!-- Ant manifest examples              https://ant.apache.org/manual/Tasks/manifest.html -->
                <attribute name="Main-Class" value="org.web3d.x3d.jsail.CommandLine"/>
                <section name="common">
                    <attribute name="Sealed" value="true"/>
                </section>
                <section name="org/w3/**/*">
                  <attribute name="Sealed" value="false"/>
                </section>
                <!-- https://dzone.com/articles/what-is-jar-hell -->
                <!-- of interest but apparently not pertinent to "fat jar" constructions where no jars are internal:
                     http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html
                    "Note: The Class-Path header points to classes or JAR files on the local network, 
                     not JAR files within the JAR file or classes accessible over Internet protocols.
                     To load classes in JAR files within a JAR file into the class path, you must write custom code to load those classes."
                     So one or more Class-Path entries won't provide general portability:
               <attribute name="Class-Path" value="./${saxon.jar};./${nagasena-rta.jar};./${exificient.jar}"/>
                -->
            </manifest>
            <zipfileset src="${jsail.full.archive.jar.name}.withSignatures">
                <!-- https://stackoverflow.com/questions/2521231/ant-task-to-remove-files-from-a-jar -->
                <exclude name="META-INF/*.DSA"/>
                <exclude name="META-INF/*.RSA"/>
                <exclude name="META-INF/*.SF"/>
                <!-- <exclude name="org/w3c/**/*"/> duplicated classes and interfaces in exificient lead to run-time errors since DOM already part of JDK 1.8+ -->
                <!-- <exclude name="org/w3c"/> eliminates stub directory -->
            </zipfileset>
        </jar>
        <delete file="${jsail.full.archive.jar.name}.withSignatures" verbose="true" failonerror="false"/>

        <!-- ===================================================================== -->
        <echo>(ensure that destination ${jsail.full.archive.jar.name} is not already in use, for example from a pending debugger session)</echo>
        <move file="${jsail.full.archive.jar.name}"     todir="${X3DJSAIL.jars.dir}" verbose="true" failonerror="false"/>
        <length property="jsail.full.archive.jar.length" file="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}"/>
        <echo>Build .jar complete: ${jsail.full.archive.jar.name} for all .class interfaces, .java sources (${jsail.full.archive.jar.length} bytes) </echo>
        <!-- TODO also provide option in archive build file to download current version -->
        <!-- TODO are exificient and nagasena/openexi needed? -->
        <!-- ===================================================================== -->
        <echo>Copy ${jsail.full.archive.jar.name} to lib/ subdirectories in X3D Example Archives:</echo>
        <copy file="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" todir="../content/examples/Basic/lib"                       verbose="true" failonerror="false"/>
        <copy file="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" todir="../content/examples/ConformanceNist/lib"             verbose="true" failonerror="false"/>
        <copy file="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" todir="../content/examples/HumanoidAnimation/lib"           verbose="true" failonerror="false"/>
        <copy file="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" todir="../content/examples/Vrml2Sourcebook/lib"             verbose="true" failonerror="false"/>
        <copy file="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" todir="../content/examples/Savage/lib"                      verbose="true" failonerror="false"/>
        <copy file="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" todir="../content/examples/SavageDefense/lib"               verbose="true" failonerror="false"/>
        <copy file="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" todir="../content/examples/X3dForAdvancedModeling/lib"      verbose="true" failonerror="false"/>
        <copy file="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" todir="../content/examples/X3dForWebAuthors/lib"            verbose="true" failonerror="false"/>
        <!-- ModelExchangeStagingArea pulls a copy to models\lib -->
        <echo message="create.X3DJSAIL.jars complete"/>
    </target>

    <target name="BuildSpecificationLanguageBindingJava.saxon" depends="" description="Build X3D specification XML encodings clause 6, Encoding of Nodes" >
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:unused.html" description="output-doc"/>
            <arg value="-s:${specifications.dir}/${X3dSchemaSource}" description="source-doc"/>
            <arg value="-xsl:BuildSpecificationLanguageBindingJava.xslt" description="style-doc"/>
        </java>
        <echo message="Remove extraneous namespace attributes from result file:"/>
        <replace file="JavaLanguageBinding.Part2.nodeTypeInterfaces.html" token=' xmlns:fn="http://www.w3.org/2005/xpath-functions"' value=""  summary="true" failonnoreplacements="false"/>
        <replace file="JavaLanguageBinding.Part2.nodeInterfaces.html"     token=' xmlns:fn="http://www.w3.org/2005/xpath-functions"' value=""  summary="true" failonnoreplacements="false"/>
        <echo message="Produced new X3D Java SAI Appendix B JavaLanguageBinding.Part2.nodeTypeInterfaces.html and Appendix C JavaLanguageBinding.Part2.nodeInterfaces.html"/>
        <mkdir dir="../../specifications/JavaLanguageBinding/Part2"/>
        <mkdir dir="../../specifications/JavaLanguageBinding/images"/>
        <echo message="move to subdirectory specifications/JavaLanguageBinding, rename to match specification filenames:"/>
        <move file="JavaLanguageBinding.Part2.nodeTypeInterfaces.html" tofile="../../specifications/JavaLanguageBinding/Part2/nodeTypeInterfaces.html" verbose="true" failonerror="false"/>
        <move file="JavaLanguageBinding.Part2.nodeInterfaces.html"     tofile="../../specifications/JavaLanguageBinding/Part2/nodeInterfaces.html"     verbose="true" failonerror="false"/>
        <copy file="Web3D_LB.css"      todir="../../specifications/JavaLanguageBinding/Part2/" verbose="true" failonerror="false"/>
        <copy file="images/cube.gif"   todir="../../specifications/JavaLanguageBinding/images" verbose="true" failonerror="false"/>
        <copy file="images/x3dbar.png" todir="../../specifications/JavaLanguageBinding/images" verbose="true" failonerror="false"/>
		
        <echo message="Update draft Java specification annexes"/>
        <echo message="==========================================="/>
        <echo message="BuildSpecificationLanguageBindingJava.saxon"/>
        <echo message="==========================================="/>
        <echo message="Copy open-source license and draft Java specification annexes"/>
        <copy file="license.txt"  todir="${src.org.web3d.x3d.jsail}"/>
        <copy file="license.html" todir="${src.org.web3d.x3d.jsail}"/>
        <copy file="license.txt"  todir="${src.org.web3d.x3d.sai}"/>
        <copy file="license.html" todir="${src.org.web3d.x3d.sai}"/>
        <copy todir="${X3DJSAIL.relative.dir}/draftJavaLanguageBindingAnnexes"><!-- verbose="true" failonerror="false" -->
            <fileset dir="../../specifications/JavaLanguageBinding/" defaultexcludes="yes">
                <include name="Part2/**/*"/>
                <include name="Images/*.gif"/>
                <include name="Images/*.png"/>
            </fileset>
        </copy>
    </target>

    <target name="BuildSpecificationLanguageBindingC.saxon" depends="" description="Build X3D specification XML encodings clause 6, Encoding of Nodes" >
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:unused.html" description="output-doc"/>
            <arg value="-s:${specifications.dir}/${X3dSchemaSource3.3}" description="source-doc"/>
            <arg value="-xsl:BuildSpecificationLanguageBindingC.xslt" description="style-doc"/>
        </java>
        <echo message="Remove extraneous namespace attributes from result file:"/>
        <replace file="CLanguageBinding.Part3.nodeTypeInterfaces.html" token=' xmlns:fn="http://www.w3.org/2005/xpath-functions"' value=""  summary="true" failonnoreplacements="false"/>
        <replace file="CLanguageBinding.Part3.nodeInterfaces.html" token=' xmlns:fn="http://www.w3.org/2005/xpath-functions"' value=""  summary="true" failonnoreplacements="false"/>
        <echo message="Produced new X3D C SAI Appendix B CLanguageBinding.Part3.nodeTypeInterfaces.html and Appendix C CLanguageBinding.Part3.nodeInterfaces.html"/>
        <mkdir dir="../../specifications/CLanguageBinding/Part3"/>
        <mkdir dir="../../specifications/CLanguageBinding/images"/>
        <echo message="move to subdirectory specifications/CSharpLanguageBinding, rename to match specification filenames:"/>
        <move file="CLanguageBinding.Part3.nodeTypeInterfaces.html" tofile="../../specifications/CLanguageBinding/Part3/nodeTypeInterfaces.html" verbose="true" failonerror="false"/>
        <move file="CLanguageBinding.Part3.nodeInterfaces.html"     tofile="../../specifications/CLanguageBinding/Part3/nodeInterfaces.html"     verbose="true" failonerror="false"/>
        <copy file="Web3D_LB.css"      todir="../../specifications/CLanguageBinding/Part3/" verbose="true" failonerror="false"/>
        <copy file="images/cube.gif"   todir="../../specifications/CLanguageBinding/images" verbose="true" failonerror="false"/>
        <copy file="images/x3dbar.png" todir="../../specifications/CLanguageBinding/images" verbose="true" failonerror="false"/>
        <copy file="images/x3d.png"    todir="../../specifications/CLanguageBinding/images" verbose="true" failonerror="false"/>

        <echo message="Update draft C specification annexes"/>
        <echo message="==========================================="/>
        <echo message="BuildSpecificationLanguageBindingC.saxon"/>
        <echo message="==========================================="/>
    <!-- 
    <echo message="Copy open-source license and draft Java specification annexes"/>
    <copy file="license.txt"  todir="${src.org.web3d.x3d.jsail}"/>
        <copy file="license.html" todir="${src.org.web3d.x3d.jsail}"/>
        <copy file="license.txt"  todir="${src.org.web3d.x3d.sai}"/>
        <copy file="license.html" todir="${src.org.web3d.x3d.sai}"/>
        <copy todir="${X3DJSAIL.relative.dir}/draftJavaLanguageBindingAnnexes"><!- verbose="true" failonerror="false" ->
            <fileset dir="../../specifications/JavaLanguageBinding/" defaultexcludes="yes">
                <include name="Part3/**/*"/>
                <include name="Images/*.gif"/>
                <include name="Images/*.png"/>
            </fileset>
        </copy>
        -->
    </target>

    <target name="BuildSpecificationLanguageBindingCPP.saxon" depends="" description="Build X3D specification XML encodings clause 6, Encoding of Nodes" >
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:unused.html" description="output-doc"/>
            <arg value="-s:${specifications.dir}/${X3dSchemaSource3.3}" description="source-doc"/>
            <arg value="-xsl:BuildSpecificationLanguageBindingCPP.xslt" description="style-doc"/>
        </java>
        <echo message="Remove extraneous namespace attributes from result file:"/>
        <replace file="CPPLanguageBinding.Part4.nodeTypeInterfaces.html" token=' xmlns:fn="http://www.w3.org/2005/xpath-functions"' value=""  summary="true" failonnoreplacements="false"/>
        <replace file="CPPLanguageBinding.Part4.nodeInterfaces.html" token=' xmlns:fn="http://www.w3.org/2005/xpath-functions"' value=""  summary="true" failonnoreplacements="false"/>
        <echo message="Produced new X3D CPP SAI Appendix B CPPLanguageBinding.Part4.nodeTypeInterfaces.html and Appendix C CPPLanguageBinding.Part4.nodeInterfaces.html"/>
        <mkdir dir="../../specifications/CPPLanguageBinding/Part4"/>
        <mkdir dir="../../specifications/CPPLanguageBinding/images"/>
        <echo message="move to subdirectory specifications/CSharpLanguageBinding, rename to match specification filenames:"/>
        <move file="CPPLanguageBinding.Part4.nodeTypeInterfaces.html" tofile="../../specifications/CPPLanguageBinding/Part4/nodeTypeInterfaces.html" verbose="true" failonerror="false"/>
        <move file="CPPLanguageBinding.Part4.nodeInterfaces.html"     tofile="../../specifications/CPPLanguageBinding/Part4/nodeInterfaces.html"     verbose="true" failonerror="false"/>
        <copy file="Web3D_LB.css"      todir="../../specifications/CPPLanguageBinding/Part4/" verbose="true" failonerror="false"/>
        <copy file="images/cube.gif"   todir="../../specifications/CPPLanguageBinding/images" verbose="true" failonerror="false"/>
        <copy file="images/x3dbar.png" todir="../../specifications/CPPLanguageBinding/images" verbose="true" failonerror="false"/>
        <copy file="images/x3d.png" todir="../../specifications/CPPLanguageBinding/images" verbose="true" failonerror="false"/>

        <echo message="Update draft CPP specification annexes"/>
        <echo message="==========================================="/>
        <echo message="BuildSpecificationLanguageBindingCPP.saxon"/>
        <echo message="==========================================="/>
        
        <!-- the following techniques are unique to netbeans and display results in the browser -->
        <echo message="file:///../../specifications/CPPLanguageBinding/Part4/nodeTypeInterfaces.html"/>
        <nbbrowse url="file:///../../specifications/CPPLanguageBinding/Part4/nodeTypeInterfaces.html"/>
        <echo message="file:///../../specifications/CPPLanguageBinding/Part4/nodeInterfaces.html"/>
        <nbbrowse url="file:///../../specifications/CPPLanguageBinding/Part4/nodeInterfaces.html"/>
        <echo message="==========================================="/>

    <!-- 
    <echo message="Copy open-source license and draft Java specification annexes"/>
    <copy file="license.txt"  todir="${src.org.web3d.x3d.jsail}"/>
        <copy file="license.html" todir="${src.org.web3d.x3d.jsail}"/>
        <copy file="license.txt"  todir="${src.org.web3d.x3d.sai}"/>
        <copy file="license.html" todir="${src.org.web3d.x3d.sai}"/>
        <copy todir="${X3DJSAIL.relative.dir}/draftJavaLanguageBindingAnnexes"><!- verbose="true" failonerror="false" ->
            <fileset dir="../../specifications/JavaLanguageBinding/" defaultexcludes="yes">
                <include name="Part4/**/*"/>
                <include name="Images/*.gif"/>
                <include name="Images/*.png"/>
            </fileset>
        </copy>
        -->
    </target>
    
    <target name="BuildSpecificationLanguageBindingCSharp.saxon" depends="" description="Build X3D specification XML encodings clause 6, Encoding of Nodes" >
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:unused.html" description="output-doc"/>
            <arg value="-s:${specifications.dir}/${X3dSchemaSource3.3}" description="source-doc"/>
            <arg value="-xsl:BuildSpecificationLanguageBindingCSharp.xslt" description="style-doc"/>
        </java>
        <echo message="Remove extraneous namespace attributes from result file:"/>
        <replace file="CSharpLanguageBinding.Part5.nodeTypeInterfaces.html" token=' xmlns:fn="http://www.w3.org/2005/xpath-functions"' value=""  summary="true" failonnoreplacements="false"/>
        <replace file="CSharpLanguageBinding.Part5.nodeInterfaces.html" token=' xmlns:fn="http://www.w3.org/2005/xpath-functions"' value=""  summary="true" failonnoreplacements="false"/>
        <echo message="Produced new X3D CSharp SAI Appendix B CSharpLanguageBinding.Part5.nodeTypeInterfaces.html and Appendix C CSharpLanguageBinding.Part5.nodeInterfaces.html"/>
        <mkdir dir="../../specifications/CSharpLanguageBinding/Part5"/>
        <mkdir dir="../../specifications/CSharpLanguageBinding/images"/>
        <echo message="move to subdirectory specifications/CSharpLanguageBinding, rename to match specification filenames:"/>
        <move file="CSharpLanguageBinding.Part5.nodeTypeInterfaces.html" tofile="../../specifications/CSharpLanguageBinding/Part5/nodeTypeInterfaces.html" verbose="true" failonerror="false"/>
        <move file="CSharpLanguageBinding.Part5.nodeInterfaces.html"     tofile="../../specifications/CSharpLanguageBinding/Part5/nodeInterfaces.html"     verbose="true" failonerror="false"/>
        <copy file="Web3D_LB.css"      todir="../../specifications/CSharpLanguageBinding/Part5/" verbose="true" failonerror="false"/>
        <copy file="images/cube.gif"   todir="../../specifications/CSharpLanguageBinding/images" verbose="true" failonerror="false"/>
        <copy file="images/x3dbar.png" todir="../../specifications/CSharpLanguageBinding/images" verbose="true" failonerror="false"/>
<copy file="images/x3d.png" todir="../../specifications/CSharpLanguageBinding/images" verbose="true" failonerror="false"/>
       
        <echo message="Update draft CSharp specification annexes"/>
        <echo message="==========================================="/>
        <echo message="BuildSpecificationLanguageBindingCSharp.saxon"/>
        <echo message="==========================================="/>
    <!-- 
    <echo message="Copy open-source license and draft Java specification annexes"/>
    <copy file="license.txt"  todir="${src.org.web3d.x3d.jsail}"/>
        <copy file="license.html" todir="${src.org.web3d.x3d.jsail}"/>
        <copy file="license.txt"  todir="${src.org.web3d.x3d.sai}"/>
        <copy file="license.html" todir="${src.org.web3d.x3d.sai}"/>
        <copy todir="${X3DJSAIL.relative.dir}/draftJavaLanguageBindingAnnexes"><!- verbose="true" failonerror="false" ->
            <fileset dir="../../specifications/JavaLanguageBinding/" defaultexcludes="yes">
                <include name="Part5/**/*"/>
                <include name="Images/*.gif"/>
                <include name="Images/*.png"/>
            </fileset>
        </copy>
        -->
    </target>

    <target name="view.javadoc.local" description="view X3DJSAIL javadoc local">
        <ant dir="java" antfile="build.xml" target="view.javadoc.local"/>
    </target>
    <target name="view.javadoc.online" description="view X3DJSAIL javadoc online">
        <ant dir="java" antfile="build.xml" target="view.javadoc.online"/>
    </target>
    
    <target name="view.BuildSpecificationLanguageBindingJava.local" description="view BuildSpecificationLanguageBindingJava appendices in web browser (Netbeans only)">
        <property name="javadocPath" location="${X3DJSAIL.relative.dir}/javadoc/index.html"/>
        <nbbrowse url="file:///${javadocPath}" />
        <property name="abstractPath" location="../../specifications/JavaLanguageBinding/Part2/nodeTypeInterfaces.html"/>
        <nbbrowse url="file:///${abstractPath}" />
        <property name="concretePath" location="../../specifications/JavaLanguageBinding/Part2/nodeInterfaces.html"/>
        <nbbrowse url="file:///${concretePath}" />
        <!-- TODO implementation-independent approach to browser viewing if possible.  other Ant approachs have to be customized for each OS -->
    </target>

    <target name="view.BuildSpecificationLanguageBindingJava.online" description="view BuildSpecificationLanguageBindingJava appendices in web browser (Netbeans only)">
        <nbbrowse url="https://www.web3D.org/documents/specifications/19777-2/V3.3/Part2/nodeTypeInterfaces.html" />
        <nbbrowse url="https://www.web3D.org/documents/specifications/19777-2/V3.3/Part2/nodeInterfaces.html" />
        <!-- TODO implementation-independent approach to browser viewing, if possible.  other Ant approachs have to be customized for each OS -->
    </target>

    <target name="BuildX3dUnifiedObjectModel.validate" depends="" description="Build  X3D Unified Object Model (X3DUOM) files in XML format, planned for use in API autogeneration">
        <echo message="Check X3DUOM well-formed XML for all X3D versions..."/>
        <xmlvalidate failonerror="false" warn="true" lenient="true">
            <fileset dir=".">
                <include name="${X3dUnifiedObjectModel4.1}"/>
                <include name="${X3dUnifiedObjectModel4.0}"/>
                <include name="${X3dUnifiedObjectModel3.3}"/>
                <include name="${X3dUnifiedObjectModel3.2}"/>
                <include name="${X3dUnifiedObjectModel3.1}"/>
                <include name="${X3dUnifiedObjectModel3.0}"/>
            </fileset>
        </xmlvalidate>
        <echo message="Check X3DUOM schema validation..."/>
        <schemavalidate failonerror="false" warn="true" lenient="false" disableDTD="true"
                        fullchecking="false" noNamespaceFile="../../specifications/X3dUnifiedObjectModel.xsd">
            <fileset dir=".">
                <include name="${X3dUnifiedObjectModel4.1}"/>
                <include name="${X3dUnifiedObjectModel4.0}"/>
                <include name="${X3dUnifiedObjectModel3.3}"/>
                <include name="${X3dUnifiedObjectModel3.2}"/>
                <include name="${X3dUnifiedObjectModel3.1}"/>
                <include name="${X3dUnifiedObjectModel3.0}"/>
            </fileset>
        </schemavalidate>
        <echo message="Check X3DUOM schema validation, strict fullchecking..."/>
        <schemavalidate failonerror="false" warn="true" lenient="false" disableDTD="true"
                        fullchecking="true" noNamespaceFile="../../specifications/X3dUnifiedObjectModel.xsd">
            <fileset dir=".">
                <include name="${X3dUnifiedObjectModel4.1}"/>
                <include name="${X3dUnifiedObjectModel4.0}"/>
                <include name="${X3dUnifiedObjectModel3.3}"/>
                <include name="${X3dUnifiedObjectModel3.2}"/>
                <include name="${X3dUnifiedObjectModel3.1}"/>
                <include name="${X3dUnifiedObjectModel3.0}"/>
            </fileset>
        </schemavalidate>
    </target>

    <target name="BuildX3dUnifiedObjectModel.saxon.all" depends="" description="Build X3D Unified Object Model (X3DUOM) files in XML format, planned for use in API autogeneration">
        <copy file="../../specifications/X3dUnifiedObjectModel.xsd" todir="java/lib/specifications/" verbose="true" failonerror="false"/>
        <echo message="Create all X3DUOM files using BuildX3dUnifiedObjectModelXmlFile.xslt and each XML schema"/>
        <echo message="==========================================="/>
        <antcall target="BuildX3dUnifiedObjectModel.saxon.v4.1"/><!-- version 4.1 -->
        <antcall target="BuildX3dUnifiedObjectModel.saxon.v4.0"/><!-- version 4.0 -->
        <antcall target="BuildSpecificationXmlEncodingFromSchema.saxon"/> <!-- includes BuildAllX3dElementsAttributes.txt -->
        <echo message="==========================================="/>
        <antcall target="BuildX3dUnifiedObjectModel.saxon.v3.3"/><!-- version 3.3 -->
        <echo message="==========================================="/>
        <echo message="Build X3D Unified Object Model (X3DUOM) version 3.2"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}" failonerror="true">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>

            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:unused.html"/> <!-- output-doc file name is created by stylesheet using schema version number -->
            <arg value="-s:${specifications.dir}/${X3dSchemaSource3.2}" description="source-doc"/>
            <arg value="-xsl:BuildX3dUnifiedObjectModelXmlFile.xslt"/> <!-- stylesheet-doc -->
        </java>
        <copy file="${X3dUnifiedObjectModel3.2}"    todir="../../specifications/" verbose="true" failonerror="false"/>
        <copy file="${X3dUnifiedObjectModel3.2}" todir="java/lib/specifications/" verbose="true" failonerror="false"/>
        <echo message="==========================================="/>
        <echo message="Build X3D Unified Object Model (X3DUOM) version 3.1"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}" failonerror="true">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>

            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:unused.html"/> <!-- output-doc file name is created by stylesheet using schema version number -->
            <arg value="-s:${specifications.dir}/${X3dSchemaSource3.1}" description="source-doc"/>
            <arg value="-xsl:BuildX3dUnifiedObjectModelXmlFile.xslt"/> <!-- stylesheet-doc -->
        </java>
        <copy file="${X3dUnifiedObjectModel3.1}"    todir="../../specifications/" verbose="true" failonerror="false"/>
        <copy file="${X3dUnifiedObjectModel3.1}" todir="java/lib/specifications/" verbose="true" failonerror="false"/>
        <echo message="==========================================="/>
        <antcall target="BuildX3dUnifiedObjectModel.saxon.v3.0"/><!-- version 3.0 -->
        <echo message="==========================================="/>
        <antcall target="BuildX3dUnifiedObjectModel.validate"/>
        <echo message="==========================================="/>
    </target>

    <target name="BuildX3dUnifiedObjectModel.saxon.v3.0" depends="" description="Build  X3D v3.0 object model files in XML format, used in API autogeneration">
        <echo message="Build X3D Unified Object Model (X3DUOM) version 3.0"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}" failonerror="true">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>

            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:unused.html"/> <!-- output-doc file name is created by stylesheet using schema version number -->
            <arg value="-s:${specifications.dir}/${X3dSchemaSource3.0}" description="source-doc"/>
            <arg value="-xsl:BuildX3dUnifiedObjectModelXmlFile.xslt"/> <!-- stylesheet-doc -->
        </java>
        <copy file="${X3dUnifiedObjectModel3.0}"    todir="../../specifications/" verbose="true" failonerror="false"/>
        <copy file="${X3dUnifiedObjectModel3.0}" todir="java/lib/specifications/" verbose="true" failonerror="false"/>
    </target>

    <target name="BuildX3dUnifiedObjectModel.saxon.v3.3" depends="" description="Build  X3D v3.3 object model files in XML format, used in API autogeneration">
        <echo message="Build X3D Unified Object Model (X3DUOM) version 3.3"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}" failonerror="true">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>

            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:unused.html"/> <!-- output-doc file name is created by stylesheet using schema version number -->
            <arg value="-s:${specifications.dir}/${X3dSchemaSource3.3}" description="source-doc"/>
            <arg value="-xsl:BuildX3dUnifiedObjectModelXmlFile.xslt"/> <!-- stylesheet-doc -->
        </java>
        <copy file="${X3dUnifiedObjectModel3.3}"    todir="../../specifications/" verbose="true" failonerror="false"/>
        <copy file="${X3dUnifiedObjectModel3.3}" todir="java/lib/specifications/" verbose="true" failonerror="false"/>
    </target>

    <target name="BuildX3duomToHAnimLOA4HierarchyTable" depends="" description="Build Humanoid Animation (HAnim) LOA4 Hierarchy Table">
        <!-- ========================================= -->
        <echo message="stylesheet X3duomToHAnimLOA4HierarchyTable.xslt conversion"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:HAnimLOA4HierarchyTable.txt" description="output-doc"/>
            <arg value="-s:${X3dUnifiedObjectModel4.1}" description="source-doc"/>
            <arg value="-xsl:X3duomToHAnimLOA4HierarchyTable.xslt" description="style-doc"/>
        </java>
        <echo />
        <loadfile property="HAnimLOA4HierarchyTable.txt.contents" srcFile="HAnimLOA4HierarchyTable.txt"/>
        <echo message="${HAnimLOA4HierarchyTable.txt.contents}"/>
        <echo />
        <echo message="stylesheet X3duomToHAnimLOA4HierarchyTable.xslt conversion complete"/>
    </target>

    <target name="BuildX3duomGlossaryToHtml" depends="" description="Build Humanoid Animation (HAnim) LOA4 Hierarchy Table">
        <!-- ========================================= -->
        <echo message="stylesheet X3duomGlossaryToHtml.xslt conversion"/>
        
        <loadfile property="glossary.xml.contents" srcFile="${specifications.dir}/${X3duomGlossary4.0}.xml"/>
        <echo message="input ${specifications.dir}/${X3duomGlossary4.0}.xml"/>
        <echo message="${glossary.xml.contents}"/>
        <echo />
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:${specifications.dir}/glossary.html"  description="output-doc"/>
            <arg value="-s:${specifications.dir}/${X3duomGlossary4.0}.xml" description="source-doc"/>
            <arg value="-xsl:X3duomGlossaryToHtml.xslt" description="style-doc"/>
        </java>
        <echo />
        <nbbrowse url="file:///${specifications.dir}/${X3duomGlossary4.0}.html" /><!-- only works within NetBeans -->
        <echo message="stylesheet BuildX3duomGlossaryToHtml.xslt conversion complete"/>
    </target>

    <target name="BuildX3dUnifiedObjectModel.saxon.v4.0" depends="" description="Build  X3D v4.0 object model files in XML format, used in API autogeneration">
        <echo message="Build X3D Unified Object Model (X3DUOM) version 4.0"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}" failonerror="true">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>

            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:unused.html"/> <!-- output-doc file name is created by stylesheet using schema version number -->
            <arg value="-s:${specifications.dir}/${X3dSchemaSource4.0}" description="source-doc"/>
            <arg value="-xsl:BuildX3dUnifiedObjectModelXmlFile.xslt"/> <!-- stylesheet-doc -->
        </java>
        <copy file="${X3dUnifiedObjectModel4.0}" todir="../../specifications/" verbose="true" failonerror="false"/>
        <copy file="${X3dUnifiedObjectModel4.0}" todir="java/lib/specifications/" verbose="true" failonerror="false"/>
        <antcall target="BuildX3dUnifiedObjectModel.validate"/>
    </target>

    <target name="BuildX3dUnifiedObjectModel.saxon.v4.1" depends="" description="Build  X3D v4.1 object model files in XML format, used in API autogeneration">
        <echo message="Build X3D Unified Object Model (X3DUOM) version 4.1"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}" failonerror="true">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>

            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:unused.html"/> <!-- output-doc file name is created by stylesheet using schema version number -->
            <arg value="-s:${specifications.dir}/${X3dSchemaSource4.1}" description="source-doc"/>
            <arg value="-xsl:BuildX3dUnifiedObjectModelXmlFile.xslt"/> <!-- stylesheet-doc -->
        </java>
        <copy file="${X3dUnifiedObjectModel4.1}" todir="../../specifications/" verbose="true" failonerror="false"/>
        <copy file="${X3dUnifiedObjectModel4.1}" todir="java/lib/specifications/" verbose="true" failonerror="false"/>
        <antcall target="BuildX3dUnifiedObjectModel.validate"/>
        <echo message="Following invocation creates AllX3dElementsAttributes4.1.xml"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:unused.html" description="output-doc"/>
            <arg value="-s:${specifications.dir}/${X3dSchemaSource4.1}" description="source-doc"/>
            <arg value="-xsl:BuildSpecificationXmlEncodingFromSchema.xslt" description="style-doc"/>
        </java>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:unused.html" description="output-doc"/>
            <arg value="-s:${specifications.dir}/${X3dSchemaSource}" description="source-doc"/>
            <arg value="-xsl:BuildSpecificationXmlEncodingFromSchema.xslt" description="style-doc"/>
        </java>
        <echo message="Following invocation creates AllX3dElementsAttributes4.1.txt"/>
        <antcall target="BuildAllX3dElementsAttributes.txt"/>
    </target>

    <target name="BuildX3dOntologyFromX3duom.saxon.v4.0" depends="" description="Build X3D Ontology from X3D Unified Object Model (X3DUOM)" >
        <echo message="Following output is for X3D ontology version 4.0 in Terse Triple Language (Turtle)"/>
        <!-- TODO other versions of X3D -->
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-s:${specifications.dir}/${X3dUnifiedObjectModel4.0}" description="source-doc"/>
            <arg value="-xsl:X3duomToX3dOntology.xslt" description="style-doc"/>
            <arg value="-o:X3dOntology4.0.ttl" description="output-doc"/>
        </java>
        <!-- TODO is there some way to to get ARQ to directly convert .ttl to .xml via command line invocation? apparaently not -->
        <!-- copy to destination directory, where it is in version control -->
        <copy file="X3dOntology4.0.ttl" todir="../../semantics/ontologies" verbose="true" failonerror="false"/>
        <!-- copy to URI directory, where it is also kept on web3d.orgl -->
        <copy file="X3dOntology4.0.ttl" todir="../specifications" verbose="true" failonerror="false"/>
        <echo message="OWL validation performed using Protege"/>
        <!-- TODO automate validation
        <echo message="  http://mowl-power.cs.man.ac.uk:8080/validator (Profile OWL 2, Report syntax: Manchester Owl Syntax)"/> -->
        <echo message="Available at"/>
        <echo message="  https://www.web3d.org/x3d/specifications/X3dOntology4.0.ttl"/>
        <echo message="  https://www.web3d.org/x3d/content/semantics/ontologies/X3dOntology4.0.ttl"/>
        <echo message="TODO: use ROBOT to automatically convert .rdf and .owl versions, otherwise use Protege"/>
        <!-- Converting files to different formats via the command-line using Protege https://github.com/protegeproject/protege/issues/1098 -->
        <echo message="TODO: use Protege to generate owldoc"/>
    </target>

    <target name="BuildX3dOntologyFromX3duom.saxon.v4.1" depends="" description="Build X3D Ontology from X3D Unified Object Model (X3DUOM)" >
        <echo message="Following output is for X3D ontology version 4.1 in Terse Triple Language (Turtle)"/>
        <!-- TODO other versions of X3D -->
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-s:${specifications.dir}/${X3dUnifiedObjectModel4.1}" description="source-doc"/>
            <arg value="-xsl:X3duomToX3dOntology.xslt" description="style-doc"/>
            <arg value="-o:X3dOntology4.1.ttl" description="output-doc"/>
        </java>
        <!-- TODO is there some way to to get ARQ to directly convert .ttl to .xml via command line invocation? apparaently not -->
        <!-- copy to destination directory, where it is in version control -->
        <copy file="X3dOntology4.1.ttl" todir="../../semantics/ontologies" verbose="true" failonerror="false"/>
        <!-- copy to URI directory, where it is also kept on web3d.orgl -->
        <copy file="X3dOntology4.1.ttl" todir="../specifications" verbose="true" failonerror="false"/>
        <echo message="OWL validation performed using Protege"/>
        <!-- TODO automate validation
        <echo message="  http://mowl-power.cs.man.ac.uk:8080/validator (Profile OWL 2, Report syntax: Manchester Owl Syntax)"/> -->
        <echo message="Available at"/>
        <echo message="  https://www.web3d.org/x3d/specifications/X3dOntology4.1.ttl"/>
        <echo message="  https://www.web3d.org/x3d/content/semantics/ontologies/X3dOntology4.1.ttl"/>
        <echo message="TODO: use ROBOT to automatically convert .rdf and .owl versions, otherwise use Protege"/>
        <!-- Converting files to different formats via the command-line using Protege https://github.com/protegeproject/protege/issues/1098 -->
        <echo message="TODO: use Protege to generate owldoc"/>
    </target>

    <!-- note difference values pointing to same directory in parent and child build.xml -->
    <property name="X3dPackageDirectory" value="python"/>

    <target name="BuildX3dPythonPackageFromX3duom.saxon" depends="" description="Build Python X3D Package from X3D Unified Object Model (X3DUOM)" >
        <echo message="Following log is for X3D version 4.0 in X3dPackageDirectory=${X3dPackageDirectory} and also"/>
        <echo message="includes support for X3D version 4.1 development via latest X3dUnifiedObjectModel-4.1.xml"/>
        <ant dir="python" antfile="build.xml" target="view.x3d.py.version" inheritAll="false"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}" failonerror="true">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
                        
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-s:${specifications.dir}/${X3dUnifiedObjectModel4.1}" description="source-doc"/>
            <arg value="-xsl:X3duomToX3dPythonPackage.xslt" description="style-doc"/>
            <arg value="X3dPackageDirectory=${X3dPackageDirectory}"/> <!-- stylesheet parameter -->
            <!-- stylesheet output goes to X3dPackageDirectory -->
            <!-- <arg value="-o:python/temphold.py" description="output-doc"/> -->
        </java>
        <echo message="Result: created files ${stylesheets.dir}/${X3dPackageDirectory}/x3d.py and __init__.py"/>
        <echo message="System environment variable PYTHONPATH=${env.PYTHONPATH}"/>
        <echo message="BuildX3dPythonPackageFromX3duom.saxon complete."/>
    </target>

    <target name="BuildX3duomToX3dDiagnostics.saxon" depends="" description="Build X3D ontology constructs">
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
                        
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:unused.html" description="output-doc"/>
            <arg value="-s:${specifications.dir}/${X3dUnifiedObjectModel}" description="source-doc"/>
            <arg value="-xsl:X3duomToX3dDiagnostics.xslt" description="style-doc"/>
        </java>
        <!-- regular expression (regex) replacement -->
        <replace file="X3dDiagnostics4.0.xml" token='xsl:when xmlns:xsl="http://www.w3.org/1999/XSL/Transform"' value="xsl:when"  summary="true" failOnNoReplacements="false"/>
        
        <copy file="HAnim2NameHanim1AliasTables.txt"            todir="../content/examples/HumanoidAnimation" verbose="true" failonerror="false"/>
        <copy file="HAnim2DefaultValuesJointsFeaturePoints.txt" todir="../content/examples/HumanoidAnimation" verbose="true" failonerror="false"/>
    </target>

    <target name="BuildSpecificationXmlEncodingFromSchema.saxon" depends="" description="Build X3D specification XML encodings clause 6, Encoding of Nodes and clause 7, Encoding of statements" >
        <echo message="Remove extraneous namespace attributes from result files:"/>
        <replace file="EncodingOfNodes.html" token=' xmlns:fn="http://www.w3.org/2005/xpath-functions"'         value=""  summary="true" failonnoreplacements="false"/>
        <replace file="EncodingOfStatements.html" token=' xmlns:fn="http://www.w3.org/2005/xpath-functions"'    value=""  summary="true" failonnoreplacements="false"/>
        <echo message="Produced new X3D XML Encoding Clause 6: EncodingOfNodes.html and clause 7: Encoding of statements"/>
        <mkdir dir="../../specifications/XmlEncoding/Part01"/>
        <mkdir dir="../../specifications/XmlEncoding/images"/>
        <echo message="move to subdirectory XmlEncoding:"/>
        <move file="EncodingOfNodes.html"      todir="../../specifications/XmlEncoding/Part01/" verbose="true" failonerror="false"/>
        <move file="EncodingOfStatements.html" todir="../../specifications/XmlEncoding/Part01/" verbose="true" failonerror="false"/>
        <copy file="X3DEncodings.css"          todir="../../specifications/XmlEncoding/Part01/" verbose="true" failonerror="false"/>
        <copy file="images/x3d.png"            todir="../../specifications/XmlEncoding/Images/" verbose="true" failonerror="false"/>
        <copy file="images/cube.gif"           todir="../../specifications/XmlEncoding/Images/" verbose="true" failonerror="false"/>
        <copy file="images/x3dbar.png"         todir="../../specifications/XmlEncoding/Images/" verbose="true" failonerror="false"/>
    </target>

    <target name="BuildAllX3dElementsAttributes.txt" depends="" description="Exemplar template that builds text version of AllX3dElementsAttributes.xml">
        <!-- TODO add other X3D versions -->
        <!-- ========================================= -->
        <echo message="stylesheet AllX3dElementsAttributesTextTemplate.xslt conversion"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:AllX3dElementsAttributes4.1.txt" description="output-doc"/>
            <arg value="-s:AllX3dElementsAttributes4.1.xml" description="source-doc"/>
            <arg value="-xsl:AllX3dElementsAttributesTextTemplate.xslt" description="style-doc"/>
        </java>
        <copy file="AllX3dElementsAttributes4.1.txt"         todir="../../specifications/"  verbose="true" failonerror="false"/>
        <copy file="AllX3dElementsAttributes4.1.xml"         todir="../../specifications/"  verbose="true" failonerror="false"/>
        <!-- ========================================= -->
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:AllX3dElementsAttributes4.0.txt" description="output-doc"/>
            <arg value="-s:AllX3dElementsAttributes4.0.xml" description="source-doc"/>
            <arg value="-xsl:AllX3dElementsAttributesTextTemplate.xslt" description="style-doc"/>
        </java>
        <copy file="AllX3dElementsAttributes4.0.txt"         todir="../../specifications/"  verbose="true" failonerror="false"/>
        <copy file="AllX3dElementsAttributes4.0.xml"         todir="../../specifications/"  verbose="true" failonerror="false"/>
        <!-- ========================================= -->
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:AllX3dElementsAttributes3.3.txt" description="output-doc"/>
            <arg value="-s:AllX3dElementsAttributes3.3.xml" description="source-doc"/>
            <arg value="-xsl:AllX3dElementsAttributesTextTemplate.xslt" description="style-doc"/>
        </java>
        <copy file="AllX3dElementsAttributes3.3.txt"         todir="../../specifications/"  verbose="true" failonerror="false"/>
        <copy file="AllX3dElementsAttributes3.3.xml"         todir="../../specifications/"  verbose="true" failonerror="false"/>
        <!-- ========================================= -->
        <echo message="stylesheet AllX3dElementsAttributesTextTemplate.xslt conversion complete"/>
    </target>

    <target name="BuildSpecificationVrmlEncodingFromSchema.saxon" depends="" description="Build X3D specification Classic VRML encoding clause 6 Encoding of Nodes" >
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:EncodingOfNodes.html" description="output-doc"/>
            <arg value="-s:${specifications.dir}/${X3dSchemaSource}" description="source-doc"/>
            <arg value="-xsl:BuildSpecificationVrmlEncodingFromSchema.xslt" description="style-doc"/>
        </java>
        <echo message="Remove extraneous namespace attributes from result file:"/>
        <replace file="EncodingOfNodes.html" token=' xmlns:fn="http://www.w3.org/2005/xpath-functions"'    value=""  summary="true" failonnoreplacements="false"/>
        <echo message="Produced new X3D Classic VRML encoding Clause 6: EncodingOfNodes.html"/>
        <mkdir dir="../../specifications/VrmlEncoding/Part02"/>
        <mkdir dir="../../specifications/VrmlEncoding/images"/>
        <!-- TODO rename as EncodingOfNodes.html -->
        <echo message="move to subdirectory specifications/VrmlEncoding:"/>
        <move file="EncodingOfNodes.html"      todir="../../specifications/VrmlEncoding/Part02/" verbose="true" failonerror="false"/>
        <move file="EncodingOfStatements.html" todir="../../specifications/VrmlEncoding/Part02/" verbose="true" failonerror="false"/>
        <copy file="X3DEncodings.css"          todir="../../specifications/VrmlEncoding/Part02/" verbose="true" failonerror="false"/>
        <copy file="images/x3d.png"            todir="../../specifications/VrmlEncoding/Images/" verbose="true" failonerror="false"/>
        <copy file="images/cube.gif"           todir="../../specifications/VrmlEncoding/Images/" verbose="true" failonerror="false"/>
        <copy file="images/x3dbar.png"         todir="../../specifications/VrmlEncoding/Images/" verbose="true" failonerror="false"/>
    </target>

    <target name="view.BuildSpecificationXmlEncodingFromSchema.local" description="view local BuildSpecificationXmlEncodingFromSchema in web browser (Netbeans only)">
        <property name="reportpath" location="../../specifications/XmlEncoding/Part01/EncodingOfNodes.html"/>
        <nbbrowse url="file:///${reportpath}" />
        <!-- TODO implementation-independent approach to browser viewing if possible.  other Ant approachs have to be customized for each OS -->
    </target>

    <target name="view.BuildSpecificationVrmlEncodingFromSchema.local" description="view local BuildSpecificationVrmlEncodingFromSchema in web browser (Netbeans only)">
        <property name="reportpath" location="EncodingOfNodes.html"/>
        <nbbrowse url="file:///${reportpath}" />
        <!-- TODO implementation-independent approach to browser viewing if possible.  other Ant approachs have to be customized for each OS -->
    </target>

    <target name="view.BuildSpecificationXmlEncodingFromSchema.online" description="view online BuildSpecificationXmlEncodingFromSchema in web browser (Netbeans only)">
        <nbbrowse url="https://www.web3D.org/documents/specifications/19776-1/V3.3/Part01/EncodingOfNodes.html" />
        <!-- TODO implementation-independent approach to browser viewing if possible.  other Ant approachs have to be customized for each OS -->
    </target>

    <target name="BuildSpecificationXmlEncodingFromSchema.xslt" depends="" description="Create chapter 6 for X3D specification XML encodings clause" >
        <!-- TODO java doesn't yet support xslt 1.1 or 2.0 ?
             reported error: Unsupported XSL element 'http://www.w3.org/1999/XSL/Transform:result-document'
        -->
        <xslt   in="${specifications.dir}/${X3dSchemaSource}"
                out="EncodingOfNodes.html"
                style="BuildSpecificationXmlEncodingFromSchema.xslt"
                reloadstylesheet="yes" force="yes">
        </xslt>
        <echo message="Remove extraneous namespace attributes from result file:"/>
        <replace file="EncodingOfNodes.html" token=' xmlns:fn="http://www.w3.org/2005/xpath-functions"'    value=""  summary="true" failonnoreplacements="false"/>
        <echo message="Produced new X3D XML Encoding Clause 6: EncodingOfNodes.html"/>
    </target>

    <target name="html5.buildElementsAttributesTable" depends="" description="build element and attribute lower-case capitalization tables for HTML5 recommendation" >

        <!-- xslt fails to find XSLT 2.0 function fn:lower-case()
        <xslt   in="${specifications.dir}/${X3dSchemaSource}"
                out="X3dElementsAttributesLowerCaseTable.txt"
                style="BuildElementAttributeTables.xslt"
                reloadstylesheet="yes" force="yes">
        </xslt>
        -->
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:X3dElementsAttributesLowerCaseTable.txt" description="output-doc"/>
            <arg value="-s:${specifications.dir}/${X3dSchemaSource}" description="source-doc"/>
            <arg value="-xsl:X3dElementsAttributesLowerCaseTableConstruction.xslt" description="style-doc"/>
        </java>
    </target>

    <target name="clean" depends="clean.results" description="clean all" >
        <delete file="TempSaiJava.txt" verbose="true" failonerror="false"/>
        <delete dir="examples"/>
    </target>

    <target name="clean.results" description="Remove autogenerated files, directory" >
        <delete dir="test" verbose="true" failonerror="false"/>
        <delete file="EncodingOfNodes.html" verbose="true" failonerror="false"/>
        <delete file="EncodingOfStatements.html" verbose="true" failonerror="false"/>
        <delete file="JavaLanguageBinding/Part2/nodeTypeInterfaces.html" verbose="true" failonerror="false"/>
        <delete file="JavaLanguageBinding/Part2/nodeInterfaces.html" verbose="true" failonerror="false"/>
        <delete file="VRMLEncodingOfNodes.html" verbose="true" failonerror="false"/>
    </target>

    <target name="clean.X3DJSAIL" description="Remove autogenerated source files, jars" >
        <echo message="clean prior autogenerated component subdirectories, if any..."/>
        <delete includeemptydirs="true" verbose="true" failonerror="false">
            <!-- leave examples alone -->
            <fileset dir="${src.org.web3d.x3d.jsail}" excludes="fields/package.html"/>
            <fileset dir="${src.org.web3d.x3d.sai}"/>
            <fileset dir="${X3DJSAIL.examples.dir}">
                <include name="*.java"/>
                <include name="*.class"/>
                <include name="*.json"/>
                <include name="*.py"/>
                <include name="*.wrl"/>
                <exclude name="SmokeTestProgram.java"/>
            </fileset>
            <fileset dir="${X3DJSAIL.classes.dir}">
                <include name="**/*"/>
                <exclude name="README.classes.txt"/>
                <exclude name="index.html"/>
            </fileset>
            <fileset dir="${src.org.web3d.x3d.util.exi}">
                <exclude name="SerializeEXISchema.java"/>
            </fileset>
            <fileset dir="${src.org.web3d.x3d.util.x3duom}" includes="**/*">
                <exclude name="X3DUnifiedObjectModel40.java"/>
            </fileset>
            <fileset dir="${X3DJSAIL.src.dir}">
                <include name="${src.org.web3d.x3d.tests}"/>
            </fileset>
            <fileset dir="${X3DJSAIL.jars.dir}">
                <include name="*.jar"/>
            </fileset>
        </delete>
    </target>
    
    <target name="test"
            depends="test.X3dToVrml97.saxon,test.X3dToX3dvClassicVrmlEncoding.saxon,test.X3dToXhtml.saxon,test.X3dModelMetaToMarkdown.saxon,test.X3dToJava.xslt" description="Perform stylesheet test tasks" >
        <!-- TODO:  ,
        test.X3dToVrml97.xslt, test.X3dToX3dvClassicVrmlEncoding.xslt, test.X3dToXhtml.xslt -->
        <!-- TODO:  test.X3dExtrusionCrossSectionToSvg.xslt -->
        <!-- TODO:  XmlUnit tests on output files -->
        <echo message="all tests complete"/>
    </target>
    
    <target name="test.mkdir" depends="" description="Make subdirectory for test results" >
        <mkdir dir="test"/>
    </target>

    <target name="validate" depends="" description="validate .xslt stylesheets">
        <!-- XML schema validation of stylesheets is not possible, but Netbeans/X3D-Edit and XML Spy provide good pseudo-validation checks -->
        <xmlvalidate failonerror="true" warn="true" lenient="true">
            <fileset dir="." includes="*.xslt"/>
        </xmlvalidate>
        <echo message="stylesheets validate complete"/>
        <xmlvalidate failonerror="true" warn="true" lenient="true" file="${examples.dir}/HelloWorld.x3d">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <property name="jdk.xml.entityExpansionLimit" value="120000"/>
            <property name="jdk.xml.totalEntitySizeLimit" value="50000000"/>
            <property name="jdk.xml.maxGeneralEntitySizeLimit" value="50000000"/>
        <!-- https://www.saxonica.com/documentation12/index.html#!using-xsl/commandline -->
        </xmlvalidate>
        <xmlvalidate failonerror="true" warn="true" lenient="true" file="${examples.dir}/Basic/course/ExtrusionHeart.x3d">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <property name="jdk.xml.entityExpansionLimit" value="120000"/>
            <property name="jdk.xml.totalEntitySizeLimit" value="50000000"/>
            <property name="jdk.xml.maxGeneralEntitySizeLimit" value="50000000"/>
        <!-- https://www.saxonica.com/documentation12/index.html#!using-xsl/commandline -->
        </xmlvalidate>
        <echo message="HelloWorld.x3d, ExtrusionHeart.x3d validate complete"/>
    </target>
    
    <target name="test.X3dToXhtml.saxon" depends="test.mkdir" description="Test X3dToXhtml.xslt stylesheet using saxon" >
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:test/HelloWorld.saxon.html" description="output-doc"/>
            <arg value="-s:test/HelloWorld.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToXhtml.xslt" description="style-doc"/>
        </java>
        <echo message="expected output: ${examples.dir}/HelloWorld.x3d.saxon.html"/>
    </target>
    
    <target name="test.X3dModelMetaToMarkdown.saxon" depends="test.mkdir" description="Test X3dToXhtml.xslt stylesheet using saxon" >
        <echo message="==========================================="/>
        <echo message="test X3dModelMetaToMarkdown.xslt to test/HelloWorld.meta.md with default parameter includeSubdirectoryPaths=true"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:test/HelloWorld.meta.md" description="output-doc"/>
            <arg value="-s:test/HelloWorld.x3d" description="source-doc"/>
            <arg value="-xsl:X3dModelMetaToMarkdown.xslt" description="style-doc"/>
        </java>
        <echo message="==========================================="/>
        <echo message="test X3dModelMetaToMarkdown.xslt to test/HelloWorld.metaFlattened.md with parameter includeSubdirectoryPaths=false"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:test/HelloWorld.metaFlattened.md" description="output-doc"/>
            <arg value="-s:test/HelloWorld.x3d" description="source-doc"/>
            <arg value="-xsl:X3dModelMetaToMarkdown.xslt" description="style-doc"/>
            <arg value="includeSubdirectoryPaths=false"/> <!-- stylesheet parameter -->
        </java>
        <echo message="==========================================="/>
    </target>
    
    <target name="test.X3dToVrml97.saxon" depends="test.mkdir" description="Test X3dToVrml97.xslt stylesheet using saxon" >
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:test/HelloWorld.saxon.wrl" description="output-doc"/>
            <arg value="-s:${examples.dir}/HelloWorld.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToVrml97.xslt" description="style-doc"/>
        </java>
        <echo message="expected output: test/HelloWorld.saxon.wrl"/>
    </target>
    
    <target name="test.X3dToX3dvClassicVrmlEncoding.saxon" depends="test.mkdir" description="Test X3dToX3dvClassicVrmlEncoding.xslt stylesheet using saxon" >
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:test/HelloWorld.saxon.x3dv" description="output-doc"/>
            <arg value="-s:${examples.dir}/HelloWorld.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToX3dvClassicVrmlEncoding.xslt" description="style-doc"/>
        </java>
        <echo message="expected output: test/HelloWorld.saxon.x3dv"/>
        <echo>ClassicVRML validation: ${castle-model-converter.exe} test/HelloWorld.saxon.x3dv --validate --enable-downloads</echo>
        <exec executable="${castle-model-viewer.dir}/${castle-model-converter.exe}" vmlauncher="false"><!-- vmlauncher switch needed for netbeans invocation -->
            <arg value="test/HelloWorld.saxon.x3dv"/>
            <arg value="--validate"/>        <!-- validate the document reporting all VRML warnings and errors -->
            <arg value="--enable-downloads"/><!-- ExternProtoDeclare and Inline -->
        </exec>
    </target>
    
    <target name="test.X3dToXhtml.xslt" depends="test.mkdir" description="Test X3dToXhtml.xslt stylesheet using default Ant xslt task" >
        <xslt style="X3dToXhtml.xslt" in="${examples.dir}/HelloWorld.x3d" out="test/HelloWorld.xslt.html"/>
    </target>
    
    <target name="test.X3DJSAIL.unitTests" depends="compile.X3DJSAIL.tests" description="Test X3DJSAIL unit tests" >
        <echo message="==========================================="/>
        <echo message="ant antfile=java/build.xml target=test.junit5.directly"/>
        <ant dir="java" antfile="build.xml" target="test.junit5.directly"/>
        <!--
        <echo message="ant antfile=java/build.xml target=test.junit5.ant"/>
        <ant antfile="java/build.xml" target="test.junit5.ant"/>
         -->
    </target>
        
    <target name="test.X3DJSAIL.Schematron">
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -schematron -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutputSchematron.txt"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <jvmarg value="-Djdk.xml.maxGeneralEntitySizeLimit=50000000"/> -->
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d" description="input model"/>
            <arg value="-schematron"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutputSchematron_CommandLine.txt"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -schematron -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutputSchematron.txt"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d" description="input model"/>
            <arg value="-schematron"/>
        </java>
        <loadfile property="schematronResultsSVRL"   srcfile="${X3DJSAIL.examples.dir}/SmokeTestProgramOutputSchematron_CommandLine.txt.svrl" failonerror="false"/>
        <loadfile property="schematronResultsReport" srcfile="${X3DJSAIL.examples.dir}/SmokeTestProgramOutputSchematron_CommandLine.txt" failonerror="false"/>
        <echo message="- - - - - - - - - - - - - - - - - - - - - -"/>
        <echo message="$(schematronResultsSVRL)"/>
        <echo message="- - - - - - - - - - - - - - - - - - - - - -"/>
        <echo message="$(schematronResultsReport)"/>
        <echo message="==========================================="/>

    </target>
        
    <target name="test.X3DJSAIL.Staircase">
        <echo   message="org.web3d.x3d.jsail.CommandLine ${X3DJSAIL.examples.dir}/Staircase.x3d -validate"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/Staircase.x3d" description="input model"/>
            <arg value="-validate" description="output model"/>
        </java>
    </target>
        
    <target name="test.X3DJSAIL.HelloWorldX3D4.draft">
        <echo   message="org.web3d.x3d.jsail.CommandLine ${X3DJSAIL.examples.dir}/HelloWorldX3D4.x3d -validate"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/HelloWorldX3D4.x3d" description="input model"/>
            <arg value="-validate" description="output model"/>
        </java>
    </target>
        
    <target name="test.X3DJSAIL.FontStyleObjectTest" 
            description="Unit testing org.web3d.x3d.tests.FontStyleObjectTest">
        <echo   message="Unit testing org.web3d.x3d.tests.FontStyleObjectTest"/>
        <java classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}" 
             sourcefile="${src.org.web3d.x3d.tests}/org/web3d/x3d/tests/FontStyleObjectTest.java">
        </java>
    </target>
        
    <target name="test.X3DJSAIL.help" description="Test X3DJSAIL -help message" >
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -version -help"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}">
            <arg value="-version"/>
            <arg value="-help"/>
        </java>
    </target>
        
    <target name="test.X3DJSAIL.clean" description="Test MeshlabLauncher capabilities" >
        <echo message="==========================================="/>
        <echo message="Preliminary cleanups"/>
        <delete file="${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncher.MeshLab.log.txt" verbose="true" failonerror="false"/>
        <delete file="${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncher.stl" verbose="true" failonerror="false"/>
        <delete file="${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncher.x3d" verbose="true" failonerror="false"/>
        <delete file="${X3DJSAIL.examples.dir}/CleatClamp_MeshLabRoundTrip.log.txt" verbose="true" failonerror="false"/>
        <delete file="${X3DJSAIL.examples.dir}/CleatClamp_RoundTrip.stl" verbose="true" failonerror="false"/>
        <delete file="${X3DJSAIL.examples.dir}/CleatClamp_RoundTrip.MeshLab.log.txt" verbose="true" failonerror="false"/>
        <delete verbose="true" failonerror="false">
            <fileset dir="${X3DJSAIL.examples.dir}">
                <include name="*.java"/>
                <exclude name="SmokeTestProgram.java"/><!-- really important! this is master version, do not delete it! -->
            </fileset>
            <fileset dir="test">
                <include name="*.java"/>
            </fileset>
        </delete>
    </target>
    
    <target name="test.X3DJSAIL.BlenderLauncher" description="Test BlenderLauncher capabilities" >
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.BlenderLauncher -version"/>
        <java classname="org.web3d.x3d.jsail.BlenderLauncher" classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-version"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.BlenderLauncher -help"/>
        <java classname="org.web3d.x3d.jsail.BlenderLauncher" classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-help"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.BlenderLauncher -properties ${X3DJSAIL.examples.dir}/X3DJSAIL.properties"/>
        <java classname="org.web3d.x3d.jsail.BlenderLauncher" classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-properties"/>
            <arg value="${X3DJSAIL.examples.dir}/X3DJSAIL.properties"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="System environment variable env.BLENDER_PATH=${env.BLENDER_PATH}"/>
        <echo   message="org.web3d.x3d.jsail.BlenderLauncher -BLENDER_PATH ${env.BLENDER_PATH}"/>
        <java classname="org.web3d.x3d.jsail.BlenderLauncher" classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-BLENDER_PATH"/>
            <arg value="${env.BLENDER_PATH}"/>
        </java>
        <echo message="==========================================="/><!-- TODO -toFile ${X3DJSAIL.examples.dir}/CleatClamp.stl.blender.png -->
        <echo   message="org.web3d.x3d.jsail.BlenderLauncher ${X3DJSAIL.examples.dir}/CleatClamp.x3d -toImage"/>
        <java classname="org.web3d.x3d.jsail.BlenderLauncher" classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp.x3d"/>
            <arg value="-toImage"/>
            <!-- let python script determine output image file names
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp.x3d.blender.png"/> -->
        </java>
        <echo message="==========================================="/>
        <echo message="now test .stl to image (not yet supported):"/><!-- TODO -toFile ${X3DJSAIL.examples.dir}/CleatClamp.x3d.blender.png -->
        <echo   message="org.web3d.x3d.jsail.BlenderLauncher ${X3DJSAIL.examples.dir}/CleatClamp.stl -toImage"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp.stl"/>
            <arg value="-toImage"/>
            <!-- TODO fix; let python script determine output image file names
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp.stl.blender.png"/> -->
        </java>
    </target>

    <target name="test.X3DJSAIL.pages" description="Test CommandLine page launching via Java Desktop" >
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -home -version"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-home"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -javadoc"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-javadoc"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -resources"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-resources"/>
        </java>
        <echo   message="org.web3d.x3d.jsail.CommandLine -X3dResources Feedback"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-X3dResources"/>
            <arg value="Feedback"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -hints"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-hints"/>
        </java>
        <echo   message="org.web3d.x3d.jsail.CommandLine -SceneAuthoringHints Images"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-hints"/>
            <arg value="Images"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -tooltips"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-tooltips"/>
        </java>
        <echo   message="org.web3d.x3d.jsail.CommandLine -X3dTooltips accessType"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-X3dTooltips"/>
            <arg value="accessType"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -regexes"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-regexes"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -X3DUOM"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-X3DUOM"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.BlenderLauncher -home"/>
        <java classname="org.web3d.x3d.jsail.BlenderLauncher" classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-home"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.MeshLabLauncher -home"/>
        <java classname="org.web3d.x3d.jsail.MeshLabLauncher" classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-home"/>
        </java>
        <echo message="==========================================="/>
    </target>

    <target name="test.X3DJSAIL.MeshlabLauncher" description="Test MeshlabLauncher capabilities" >
        <delete verbose="true" failonerror="false">
            <fileset dir="${X3DJSAIL.examples.dir}">
                <include name="*.MeshLab.log.txt"/>
            </fileset>
        </delete>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.MeshLabLauncher -version"/>
        <java classname="org.web3d.x3d.jsail.MeshLabLauncher" classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-version"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.MeshLabLauncher -help"/>
        <java classname="org.web3d.x3d.jsail.MeshLabLauncher" classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-help"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.MeshLabLauncher -properties ${X3DJSAIL.examples.dir}/X3DJSAIL.properties"/>
        <java classname="org.web3d.x3d.jsail.MeshLabLauncher" classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-properties"/>
            <arg value="${X3DJSAIL.examples.dir}/X3DJSAIL.properties"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="System environment variable env.MESHLAB_PATH=${env.MESHLAB_PATH}"/>
        <echo   message="org.web3d.x3d.jsail.MeshLabLauncher -MESHLAB_PATH ${env.MESHLAB_PATH}"/>
        <java classname="org.web3d.x3d.jsail.MeshLabLauncher" classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-MESHLAB_PATH"/>
            <arg value="${env.MESHLAB_PATH}"/>
        </java>
        <echo message="==========================================="/>
        <echo message="Convert CleatClamp.stl to .x3d version ..."/>
        <echo   message="org.web3d.x3d.jsail.MeshLabLauncher ${X3DJSAIL.examples.dir}/CleatClamp.stl ${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncher.x3d"/>
        <java classname="org.web3d.x3d.jsail.MeshLabLauncher" classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp.stl" description="input model"/>
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncher.x3d" description="output model"/>
        </java>
        <echo message="and then canonicalize ..."/>
        <echo   message="org.web3d.x3d.jsail.CommandLine ${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncher.x3d -canonicalize ${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncherCanonicalize.x3d"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncher.x3d" description="input model"/>
            <arg value="-canonicalize"/> <!-- output model has matching name if not defined -->
            <arg value="-toFile"/> <!-- output model has matching name if not defined -->
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncherCanonicalize.x3d" description="output model"/>
        </java>
        <echo message="and then tidy ..."/>
        <echo   message="org.web3d.x3d.jsail.CommandLine ${X3DJSAIL.examples.dir}/CleatClamp.x3d ${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncherTidy.x3d"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncher.x3d" description="input model"/>
            <arg value="-tidy"/> <!-- output model has matching name if not defined -->
            <arg value="-toFile"/> <!-- output model has matching name if not tdefined -->
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncherTidy.x3d" description="output model"/>
        </java>
        <echo message="and then .java version ..."/>
        <echo   message="org.web3d.x3d.jsail.CommandLine ${X3DJSAIL.examples.dir}/CleatClamp.x3d ${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncher.x3d"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp.x3d" description="input model"/>
            <arg value="-toJava"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp.java" description="output model"/>
        </java>
        <echo message="==========================================="/>
        <echo message="... and then back to .stl for visual comparison"/>
        <echo   message="org.web3d.x3d.jsail.MeshLabLauncher ${X3DJSAIL.examples.dir}/CleatClamp.stl ${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncher.stl"/>
        <java classname="org.web3d.x3d.jsail.MeshLabLauncher" classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp.stl" description="input model"/>
            <arg value="${X3DJSAIL.examples.dir}/CleatClamp_MeshLabLauncher.stl" description="output model"/>
        </java>
    </target>

    <target name="test.examples.java" description="Test examples in java"
         depends="compile.examples.java,test.SmokeTestProgram.java"><!-- ,test.NewX3dModel.java -->
    </target>

    <target name="test.SmokeTestProgram.java" depends="compile.examples.java" description="Test SmokeTestProgram">
        <java classname="SmokeTestProgram" 
              dir="${X3DJSAIL.examples.dir}"
              classpath="${X3DJSAIL.examples.dir};${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};" fork="${fork}">
        </java>
    </target>

    <target name="test.NewX3dModel.java" depends="compile.examples.java" description="Test NewX3dModel">
        <java classname="NewX3dModel" 
              dir="${X3DJSAIL.examples.dir}"
              classpath="${X3DJSAIL.examples.dir};${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};" fork="${fork}">
        </java>
    </target>

    <target name="test.X3DJSAIL.FieldObjectTests" depends="compile.X3DJSAIL.tests" 
            description="Unit testing org.web3d.x3d.tests.FieldObjectTests">
        <echo   message="Unit testing org.web3d.x3d.tests.FieldObjectTests"/>
        <java classname="org.web3d.x3d.tests.FieldObjectTests" fork="${fork}">
            <classpath>
                <pathelement path="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}"/>
            </classpath>
            <classpath refid="junit5.classpath"/><!-- includes jupiter subdirectory -->
        </java>
    </target>

    <target name="test.X3DUnifiedObjectModelJaxbTests" depends="compile.X3DJSAIL.tests" 
            description="Test X3DUnifiedObjectModelJaxbTests">
        <echo   message="Unit testing org.web3d.x3d.tests.X3DUnifiedObjectModelJaxbTests"/>
        <property name="java.classes.dir" location="java/classes"/>
        <echo   message="$java.classes.dir=${java.classes.dir}"/>
        <java classname="org.web3d.x3d.tests.X3DUnifiedObjectModelJaxbTests" fork="${fork}">
            <classpath>
                <pathelement location="${java.classes.dir}" />
                <pathelement path="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}"/>
            </classpath>
            <classpath refid="junit5.classpath"/><!-- includes jupiter subdirectory -->
        </java>
    </target>
    
    <target name="test.X3DPSAIL" description="Test x3d.py X3DPSAIL">
        <ant dir="python" target="test.x3d.py" inheritAll="false"/>
        <echo message="==========================================="/>
        <ant dir="python" target="examples" inheritAll="false"/>
        <echo message="results saved as python/build.test.X3DPSAIL.log.txt"/>
        <echo message="==========================================="/>
    </target>
    
    <target name="test.X3DJSAIL" depends="versions,test.X3DJSAIL.clean,test.mkdir,compile.examples.java" description="Test X3DJSAIL">
        <echo message="==========================================="/>
        <echo message="helpful invocations for CommandLine debugging"/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -version -help"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-help"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -properties ${X3DJSAIL.examples.dir}/X3DJSAIL.properties"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="-properties"/>
            <arg value="${X3DJSAIL.examples.dir}/X3DJSAIL.properties"/>
        </java>
        <echo message="==========================================="/>
        <antcall target="test.X3DJSAIL.FieldObjectTests"/>
        <echo message="==========================================="/>
        <antcall target="compile.examples.java"/>
        <echo message="==========================================="/>
        <!-- self-validation test -->
        <echo message="test execution and self-validation of SmokeTestProgram and other examples:"/>
        <antcall target="test.examples.java"/>
        <echo message="==========================================="/>
        <echo message="compile SmokeTestProgramOutput.java source..."/>
        <echo message="     (i.e. new source program which was just produced by SmokeTestProgram execution)"/>
        <!-- avoid warning by using -release rather than -source and -target, https://ant.apache.org/manual/Tasks/javac.html -->
        <javac   srcdir="${X3DJSAIL.examples.dir}"
                destdir="${X3DJSAIL.examples.dir}"
              classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};"
                  debug="on"
               encoding="UTF-8"
                release="${java.source}"
                verbose="${javac.verbose}"
                includeantruntime="false" fork="${fork}">
            <include name="SmokeTestProgramOutput.java"/>
        <!--<exclude name="SmokeTestProgram.java"/>-->
            <compilerarg value="-Xlint:all"/>
            <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap -->
            <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac -->
            <!-- https://stackoverflow.com/questions/20174355/how-class-loading-is-done-by-using-xbootclasspath-ppath -->
            <!-- https://stackoverflow.com/questions/48148607/how-to-add-a-jar-to-the-boot-classpath-in-java-9 -->
            <!-- -Xbootclasspath/p became -Xbootclasspath/a in jdk 9 -->
            <!-- <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> not allowed with target 15 -->
        </javac>
        <!-- self-validation test -->
        <echo message="test SmokeTestProgramOutput.java execution and self-validation:"/>
        <java classname="SmokeTestProgramOutput" 
                      dir="${X3DJSAIL.examples.dir}"
                      classpath="${X3DJSAIL.examples.dir};${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};" fork="${fork}">
        </java>
        <delete file="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.class" verbose="true" failonerror="false"/>
        <echo message="==========================================="/>
        <!-- .json jslint and schema validation -->
        <!-- convert SmokeTestProgramOutput.x3d to SmokeTestProgramOutput.json -->
        <!-- example: antcall target="test.X3dToJson.xslt"/ -->
        <echo message="translation input: ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d"/>
        <echo message="..expected output: ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.json"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-o:${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.json" description="output-doc"/>
            <arg value="-s:${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d"  description="source-doc"/>
            <arg value="-xsl:X3dToJson.xslt" description="style-doc"/>
        </java>
        <echo>Error checking with jslint: ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.json</echo>
        <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.json"/>
        </java>
        <echo>Error checking with json-schema-validator: ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.json</echo>
        <java jar="${json-schema-validator.jar}" fork="${fork}">
            <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.json"/>
        </java>
        <echo message="==========================================="/>
        <echo message="SmokeTestProgramOutput.x3d"/>
        <xmlvalidate lenient="yes" warn="yes" file="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <property name="jdk.xml.entityExpansionLimit" value="120000"/>
            <property name="jdk.xml.totalEntitySizeLimit" value="50000000"/>
            <property name="jdk.xml.maxGeneralEntitySizeLimit" value="50000000"/>
        <!-- https://www.saxonica.com/documentation12/index.html#!using-xsl/commandline -->
        </xmlvalidate>
        <xmlvalidate lenient="no"  warn="yes" file="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <property name="jdk.xml.entityExpansionLimit" value="120000"/>
            <property name="jdk.xml.totalEntitySizeLimit" value="50000000"/>
            <property name="jdk.xml.maxGeneralEntitySizeLimit" value="50000000"/>
        <!-- https://www.saxonica.com/documentation12/index.html#!using-xsl/commandline -->
        </xmlvalidate>
        <echo message="==========================================="/>
        <echo>ClassicVRML validation: ${castle-model-converter.exe} ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3dv --validate --enable-downloads</echo>
        <exec executable="${castle-model-viewer.dir}/${castle-model-converter.exe}" vmlauncher="false"><!-- vmlauncher switch needed for netbeans invocation -->
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3dv"/>
            <arg value="--validate"/>        <!-- validate the document reporting all VRML warnings and errors -->
            <arg value="--enable-downloads"/><!-- ExternProtoDeclare and Inline -->
        </exec>
        <echo message="==========================================="/>
        <echo message="SmokeTestProgramOutput_CommandLine.x3d"/>
        <xmlvalidate lenient="yes" warn="yes" file="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_CommandLine.x3d">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <property name="jdk.xml.entityExpansionLimit" value="120000"/>
            <property name="jdk.xml.totalEntitySizeLimit" value="50000000"/>
            <property name="jdk.xml.maxGeneralEntitySizeLimit" value="50000000"/>
        <!-- https://www.saxonica.com/documentation12/index.html#!using-xsl/commandline -->
        </xmlvalidate>
        <xmlvalidate lenient="no"  warn="yes" file="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_CommandLine.x3d">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <property name="jdk.xml.entityExpansionLimit" value="120000"/>
            <property name="jdk.xml.totalEntitySizeLimit" value="50000000"/>
            <property name="jdk.xml.maxGeneralEntitySizeLimit" value="50000000"/>
        <!-- https://www.saxonica.com/documentation12/index.html#!using-xsl/commandline -->
        <!-- https://stackoverflow.com/questions/6282542/ant-how-to-compare-contents-of-two-files -->
        </xmlvalidate>
        <condition property="CommandLine.match" value="true">
            <filesmatch file1="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d"
                                file2="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_CommandLine.x3d"/>
        </condition>
        <!-- otherwise -->
        <property name="CommandLine.match" value="false"/>
        <echo message="matches SmokeTestProgramOutput.x3d: ${CommandLine.match}"/>
        <echo message="==========================================="/>
        <echo message="SmokeTestProgramOutput.xml"/>
        <xmlvalidate lenient="yes" warn="yes" file="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.xml"/>
        <xmlvalidate lenient="no"  warn="yes" file="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.xml"/>
        <condition property="X3DXML.match" value="true">
            <filesmatch file1="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d"
                                file2="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.xml"/>
        </condition>
        <!-- otherwise -->
        <property name="X3DXML.match" value="false"/>
        <echo message="matches SmokeTestProgramOutput.x3d: ${X3DXML.match}"/>
        <echo message="==========================================="/>
        <echo message="SmokeTestProgramOutput_ReloadedDOM.x3d"/>
        <xmlvalidate lenient="yes" warn="yes" file="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_ReloadedDOM.x3d">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <property name="jdk.xml.entityExpansionLimit" value="120000"/>
            <property name="jdk.xml.totalEntitySizeLimit" value="50000000"/>
            <property name="jdk.xml.maxGeneralEntitySizeLimit" value="50000000"/>
        <!-- https://www.saxonica.com/documentation12/index.html#!using-xsl/commandline -->
        </xmlvalidate>
        <xmlvalidate lenient="no"  warn="yes" file="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_ReloadedDOM.x3d">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <property name="jdk.xml.entityExpansionLimit" value="120000"/>
            <property name="jdk.xml.totalEntitySizeLimit" value="50000000"/>
            <property name="jdk.xml.maxGeneralEntitySizeLimit" value="50000000"/>
        <!-- https://www.saxonica.com/documentation12/index.html#!using-xsl/commandline -->
        </xmlvalidate>
        <condition property="ReloadedDOM.match" value="true">
            <filesmatch file1="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d"
                                file2="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_ReloadedDOM.x3d"/>
        </condition>
        <!-- otherwise -->
        <property name="ReloadedDOM.match" value="false"/>
        <echo message="matches SmokeTestProgramOutput.x3d: ${ReloadedDOM.match}"/>
        <echo>ClassicVRML validation: ${castle-model-converter.exe} ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3dv --validate --enable-downloads</echo>
        <exec executable="${castle-model-viewer.dir}/${castle-model-converter.exe}" vmlauncher="false"><!-- vmlauncher switch needed for netbeans invocation -->
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3dv"/>
            <arg value="--validate"/>        <!-- validate the document reporting all VRML warnings and errors -->
            <arg value="--enable-downloads"/><!-- ExternProtoDeclare and Inline -->
        </exec>
        <echo message="==========================================="/>
        <antcall target="test.X3DJSAIL.unitTests"/>
        <echo message="==========================================="/>
        <antcall target="test.EXI"/>
        <echo message="==========================================="/>
        <antcall target="test.X3dToJava.xslt"/>
        <echo message="==========================================="/>
        <antcall target="test.X3DJSAIL.BlenderLauncher"/>
        <echo message="==========================================="/>
        <antcall target="test.X3DJSAIL.MeshlabLauncher"/>
        <echo message="==========================================="/>
        <echo message="Continuing with individual tests"/>
        <echo   message="org.web3d.x3d.jsail.CommandLine ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d -toZIP -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.ant.zip"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d" description="input model"/>
            <arg value="-toZIP"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.ant.zip" description="output model"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine ${X3DJSAIL.examples.dir}/flowers7.x3d -toJava -toFile ${X3DJSAIL.examples.dir}/flowers7.java"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/flowers7.x3d" description="input model"/>
            <arg value="-toJava"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/flowers7.java"/>
        </java>
        <echo message="compile flowers7.java source..."/>
        <!-- avoid warning by using -release rather than -source and -target, https://ant.apache.org/manual/Tasks/javac.html -->
        <javac   srcdir="${X3DJSAIL.examples.dir}"
                destdir="${X3DJSAIL.examples.dir}"
              classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};"
                  debug="on"
               encoding="UTF-8"
                release="${java.source}"
                verbose="false"
                includeantruntime="false" fork="${fork}">
            <!-- -Xlint reports problem with direct object invocation of .isNode() or isStatement()
            <compilerarg value="-Xlint:all"/>
            -->
            <compilerarg value="-proc:only" /><!-- silence annotations warning -->
            <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap -->
            <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac -->
            <!-- https://stackoverflow.com/questions/20174355/how-class-loading-is-done-by-using-xbootclasspath-ppath -->
            <!-- https://stackoverflow.com/questions/48148607/how-to-add-a-jar-to-the-boot-classpath-in-java-9 -->
            <!-- -Xbootclasspath/p became -Xbootclasspath/a in jdk 9 -->
            <!-- <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> not allowed with target 15 -->
        </javac>
        <!-- self-validation test -->
        <echo message="test flowers7.java execution and self-validation:"/>
        <java classname="flowers7" 
              dir="${X3DJSAIL.examples.dir}"
              classpath="${X3DJSAIL.examples.dir};${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};" fork="${fork}">
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine flowers7.x3d -toJSON -toFile /flowers7.json"/>
        <echo   message="    in directory ${X3DJSAIL.examples.dir}"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/flowers7.x3d" description="input model"/>
            <arg value="-toJSON"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/flowers7.json"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -toGZIP -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.ant.gz"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d" description="input model"/>
            <arg value="-toGZIP"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.ant.gz"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -toGZIP -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.ant.gz"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d" description="input model"/>
            <arg value="-toX3D"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_CommandLine.x3d"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -toXML -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_CommandLine.xml"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d" description="input model"/>
            <arg value="-toXML"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_CommandLine.xml"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -toHTML -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_CommandLine.html (pretty print)"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d" description="input model"/>
            <arg value="-toHTML"/><!-- pretty print documentation -->
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_CommandLine.html"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -markdown -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_CommandLine.md"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d" description="input model"/>
            <arg value="-markdown"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_CommandLine.md"/>
        </java>
        <concat>
            <fileset file="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput_CommandLine.md"/>
        </concat>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -schematron -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutputSchematron.txt"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d" description="input model"/>
            <arg value="-schematron"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutputSchematron_CommandLine.txt"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -schematron -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutputSchematron.txt"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d" description="input model"/>
            <arg value="-schematron"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine -tidy -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutputTidy.CommandLine.x3d"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d" description="input model"/>
            <arg value="-tidy"/><!-- cleaned-up version -->
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutputTidy_CommandLine.x3d"/>
        </java>
        <!-- <echo message="==========================================="/>
             hide jjs tests, no longer supported in latest OpenJDK 15
        <echo message="ant antfile=java/nashorn/build.xml target=test.nashorn (direct invocation)"/>
        <ant antfile="java/nashorn/build.xml" target="test.nashorn" inheritAll="false"/>
        inheritAll="false" to ensure that properties do not interfere with each other -->
        <echo message="==========================================="/>
        <echo message="test X3DUnifiedObjectModel JAXB invocations"/>
        <antcall target="test.X3DUnifiedObjectModelJaxbTests"/>
        <echo message="==========================================="/>
        <echo message="build.test.X3DJSAIL.txt holds output results"/>
        <echo message="==========================================="/>
    </target>
    
    <target name="test.EXI" description="Test both Exificient and OpenEXI implementations">
        <echo   message="org.web3d.x3d.jsail.CommandLine ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d -EXIFICIENT -toEXI -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.exificient.exi"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d" description="input model"/>
            <arg value="-EXIFICIENT"/>
            <arg value="-toEXI"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.exificient.exi"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.exificient.exi -EXIFICIENT -fromEXI -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.ExificientRoundTrip.x3d"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.exificient.exi" description="input model"/>
            <arg value="-EXIFICIENT"/>
            <arg value="-fromEXI"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.ExificientRoundTrip.x3d"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d -OpenEXI -toEXI -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.openexi.exi"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.x3d" description="input model"/>
            <arg value="-OpenEXI"/>
            <arg value="-toEXI"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.openexi.exi"/>
        </java>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.openexi.exi -OpenEXI -fromEXI -toFile ${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.OpenExiRoundTrip.x3d"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.openexi.exi" description="input model"/>
            <arg value="-OpenEXI"/>
            <arg value="-fromEXI"/>
            <arg value="-toFile"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.OpenExiRoundTrip.x3d"/>
        </java>
        <echo message="==========================================="/>
        <!-- TODO cross-wise interoperability testing -->
    </target>
    
    <target name="test.X3dHAnimHumanoidReport" depends="test.mkdir" description="Test X3dToXhtml.xslt stylesheet using saxon" >
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:test/HAnimSpecificationLOA3Invisible.xslt.html" description="output-doc"/>
            <arg value="-s:${examples.dir}/HumanoidAnimation/HAnimSpecificationLOA3Invisible.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToXhtml.xslt" description="style-doc"/>
        </java>
        <echo message="expected output: test/HAnimSpecificationLOA3Invisible.xslt.html"/>
        
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-o:test/BoxMan.xslt.html" description="output-doc"/>
            <arg value="-s:${examples.dir}/HumanoidAnimation/BoxMan.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToXhtml.xslt" description="style-doc"/>
        </java>
        <echo message="expected output: test/BoxMan.xslt.html"/>
    </target>

    <target name="view.test.X3dToX3domX_ITE" description="view X3dHAnimHumanoidReport in web browser (Netbeans only)">
        <nbbrowse url="file:///${basedir}/test/HelloWorld.xhtml" />
        <nbbrowse url="file:///${basedir}/test/HAnimSpecificationLOA3Illustrated.xhtml" />
        <nbbrowse url="file:///${basedir}/test/MetadataExamples.xhtml" />
        <!--
        <nbbrowse url="file:///${basedir}/HelloWorld.xhtml" />
        <nbbrowse url="file:///${basedir}/test/CadDesignPatternExampleBushing.xhtml" />
        <nbbrowse url="file:///${basedir}/test/CadTeapot.xhtml" />
        <nbbrowse url="file:///${basedir}/test/IndexedQuadSetExample.xhtml" />
        <nbbrowse url="file:///${basedir}/test/QuadSetColor.xhtml" />
        <nbbrowse url="file:///${basedir}/test/IndexedQuadSetTexture.xhtml" />
        -->
    </target>

    <target name="view.X3dHAnimHumanoidReport" description="view X3dHAnimHumanoidReport in web browser (Netbeans only)">
        <property name="reportpath" location="test/HAnimSpecificationLOA3Invisible.xslt.html#humanoidHAnimHumanoidReport"/>
        <nbbrowse url="file:///${reportpath}" />
        <!-- TODO implementation-independent approach to browser viewing if possible.  other Ant approachs have to be customized for each OS -->
    </target>

    <target name="view.X3DJSAIL.online" description="view X3DJSAIL in web browser (Netbeans only)">
        <nbbrowse url="https://www.web3D.org/specifications/java/X3DJSAIL.html" />
        <!-- TODO implementation-independent approach to browser viewing if possible.  other Ant approachs have to be customized for each OS -->
    </target>

    <target name="view.X3DPSAIL.online" description="view X3DPSAIL in web browser (Netbeans only)">
        <nbbrowse url="https://www.web3D.org/x3d/stylesheets/python/python.html" />
        <!-- TODO implementation-independent approach to browser viewing if possible.  other Ant approachs have to be customized for each OS -->
    </target>

    <target name="view.stylesheets.sourceforge" description="view online version control in web browser (Netbeans only)">
        <nbbrowse url="https://sourceforge.net/p/x3d/code/HEAD/tree/www.web3d.org/x3d/stylesheets" />
    </target>
    
    <!-- TODO fix broken conversion, add saxon version -->
    <target name="test.X3dExtrusionCrossSectionToSvg.xslt" depends="test.mkdir" description="Test X3dExtrusionCrossSectionToSvg.xslt stylesheet using default Ant xslt task" >
        <xslt style="X3dExtrusionCrossSectionToSvg.xslt" in="${examples.dir}/Basic/course/ExtrusionHeart.x3d" out="test/ExtrusionHeart.svg"/>
        <echo message="validate test/ExtrusionHeart.svg:"/>
        <xmlvalidate failonerror="true" warn="true" lenient="true" file="test/ExtrusionHeart.svg"/>
    </target>
    
    <!-- TODO fix broken conversion, add saxon version -->
    <target name="test.X3dExtrusionToSvgViaXslt2.0.xslt" depends="test.mkdir" description="Test X3dExtrusionToSvgViaXslt2.0.xslt stylesheet using default Ant xslt task" >
        <xslt style="X3dExtrusionToSvgViaXslt2.0.xslt" in="${examples.dir}/Basic/course/ExtrusionHeart.x3d" out="test/ExtrusionHeart.svg"/>
        <echo message="validate test/ExtrusionHeart.svg:"/>
        <xmlvalidate failonerror="true" warn="true" lenient="true" file="test/ExtrusionHeart.svg"/>
    </target>
	
    <macrodef name="JsonConversion" description="Invoke XSLT transformation on passed scene using passed stylesheet">
        <attribute name="pathScene"/>
        <sequential>
            <echo message="translation input: @{pathScene}.x3d"/>
            <echo message="..expected output: @{pathScene}.fixed.json"/>
            <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
                <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
                <!-- https://ant.apache.org/manual/Tasks/java.html -->
                <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
                <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
                <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
                <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
                <!-- <arg value="-t" description="timing information"/> -->
                <arg value="-warnings:recover" description="recover after writing a warning message"/>
                <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
                <arg value="-o:@{pathScene}.fixed.json" description="output-doc"/>
                <arg value="-s:@{pathScene}.x3d" description="source-doc"/>
                <arg value="-xsl:X3dToJson.xslt" description="style-doc"/>
            </java>
            <echo>..error checking with jslint</echo>
            <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
                <arg value="@{pathScene}.fixed.json"/>
            </java>
            <echo>..error checking with json-schema-validator</echo>
            <java jar="${json-schema-validator.jar}" fork="${fork}">
                <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
                <arg value="@{pathScene}.fixed.json"/>
            </java>
            <echo message="==========================================="/>
        </sequential>
    </macrodef>

    <target name="test.X3dToJson.text" depends="test.mkdir" description="Test X3dToJson.xslt stylesheet using Saxon" >
        <echo message="==========================================="/>
        <echo message="translation input: test/text.x3d"/>
        <echo message="..expected output: test/text.json"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-o:test/text.json" description="output-doc"/>
            <arg value="-s:test/text.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToJson.xslt" description="style-doc"/>
        </java>
        <echo>..error checking with jslint</echo>
        <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
            <arg value="test/HelloWorld.json"/>
        </java>
        <echo>..error checking with json-schema-validator</echo>
        <java jar="${json-schema-validator.jar}" fork="${fork}">
            <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
            <arg value="test/HelloWorld.json"/>
        </java>
    </target>
    
    <target name="test.X3dToJson.CobwebExamples.xslt" depends="test.mkdir" description="Test X3dToJson.xslt stylesheet using default Ant xslt task" >
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/ICTS/stage/index__2"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/Appartment/index"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/BIC/index"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/BIC/building"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/BIC/buero"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/Chomp/canyonv"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/DLMF/21.4.F1a"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/DLMF/5.3.F4"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/DLMF/6.3.F3"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/Dolphin/index"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/ICTS/stage/index__4"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/ICTS/stage/index__5"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/ICTS/stage/level1"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/Pong/index"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/Schacht/index"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/Terrain/index"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/TikiWorld/index"/>
        <JsonConversion  pathScene="test/BadJsonFromCobweb/Examples/Vattenfall/index"/>
        <!--
        -->
    </target>
    
    <target name="test.X3dToJava.xslt.one" depends="test.mkdir" description="Test X3dToJava.xslt stylesheet using Saxon" >
        <property name="oneFileName" value="HelloWorld"/><!-- no file extension -->
        <delete verbose="true" failonerror="false">
            <fileset file="test/${oneFileName}.java"/>
        </delete>
        <echo message="==========================================="/>
        <echo   message="org.web3d.x3d.jsail.CommandLine test/${oneFileName}.x3d -toJava -toFile test/${oneFileName}.java"/>
        <!--
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="test/${oneFileName}.x3d" description="input model"/>
            <arg value="-toJava"/>
            <arg value="-toFile"/>
            <arg value="test/${oneFileName}.java"/>
        </java>
        -->
        <!-- prefer testing stylesheet directlly to support debugging -->
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-s:test/${oneFileName}.x3d" description="source-doc"/>
            <arg value="-o:test/${oneFileName}.java" description="output-doc"/>
            <arg value="-xsl:X3dToJava.xslt" description="style-doc"/>
            <arg value="className=${oneFileName}"/> <!-- parameter -->
            <!-- <arg value="-catalog:needFileName" description="style-doc"/> -->
            <!-- <arg value="className=CameraExamples"/> parameter -->
        </java>
        <echo message="compile ${oneFileName}.java source..."/>
        <!-- avoid warning by using -release rather than -source and -target, https://ant.apache.org/manual/Tasks/javac.html -->
        <javac   srcdir="test"
                destdir="test"
              classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};"
                  debug="on"
               encoding="UTF-8"
                release="${java.source}"
                verbose="false"
                includeantruntime="false" fork="${fork}">
            <!-- -Xlint reports problem with direct object invocation of .isNode() or isStatement()
            <compilerarg value="-Xlint:all"/>
            -->
            <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap -->
            <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac -->
            <!-- https://stackoverflow.com/questions/20174355/how-class-loading-is-done-by-using-xbootclasspath-ppath -->
            <!-- https://stackoverflow.com/questions/48148607/how-to-add-a-jar-to-the-boot-classpath-in-java-9 -->
            <!-- -Xbootclasspath/p became -Xbootclasspath/a in jdk 9 -->
            <!-- <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> not allowed with target 15 -->
        </javac>
        <!-- self-validation test -->
        <echo message="test ${oneFileName}.java execution and self-validation:"/>
        <java classname="${oneFileName}" 
                      dir="test"
                      classpath="test;${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};" fork="${fork}">
        </java>
        <echo message="==========================================="/>
    </target>
    
    <target name="test.X3dToPython.xslt.one" depends="test.mkdir" description="Test X3dToPython.xslt stylesheet using Saxon" >
        <property name="oneFileName" value="HelloWorld"/><!-- no file extension -->
        <echo message="==========================================="/>
        <delete verbose="true" failonerror="false">
            <fileset file="python/examples/${oneFileName}.py"/>
        </delete>
        <echo message="==========================================="/>
        <!-- TODO Saxon XML Catalogs https://www.saxonica.com/html/documentation/sourcedocs/xml-catalogs.html 
             XML Entity and URI Resolvers http://xerces.apache.org/xml-commons/components/resolver/resolver-article.html
            <xmlcatalog refid="X3dCatalog"/> -->
            
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-s:python/examples/${oneFileName}.x3d" description="source-doc"/>
            <arg value="-o:python/examples/${oneFileName}.py" description="output-doc"/>
            <arg value="-xsl:X3dToPython.xslt" description="style-doc"/>
            <arg value="insertPackagePrefix=false"/> <!-- parameter -->
            <!-- <arg value="-catalog:needFileName" description="style-doc"/> -->
            <!-- <arg value="className=CameraExamples"/> parameter -->
        </java>
        <echo message="test.X3dToPython.xslt.one conversion of ${oneFileName}.x3d to ${oneFileName}.py complete."/>
        <loadfile property="pythonFileContents" srcFile="python/examples/${oneFileName}.py" />
        <echo message="${pythonFileContents}" />
        <echo message="==========================================="/>
        <!-- self-validation test -->
        <echo message="Loading local x3d.py package in python to check for correctness..."/>
        <echo message="  then test ${oneFileName}.py execution and self-validation:"/>
        <exec executable="python"  dir="." vmlauncher="false">
        <!--<arg value="python/x3d.py"/> -->
            <arg value="python/examples/${oneFileName}.py" description="output-doc"/>
            <arg value="-v"/><!-- verbose -->
        </exec>
        <echo message="test.X3dToPython.xslt.one conversion of ${oneFileName}.x3d to ${oneFileName}.py complete."/>
        <echo message="==========================================="/>
    </target>
    
    <target name="test.X3dToTurtle.xslt.one" depends="test.mkdir" description="Test X3dToTurtle.xslt stylesheet using Saxon" >
        <!-- semantics build.xml/build.HelloWorld depends on correct setting of default file HelloWorld.x3d in target -->
        <property name="oneFileName" value="HelloWorld"/><!-- no file extension -->
        <echo message="oneFileName=${oneFileName}"/>
        <echo message="==========================================="/>
        <delete verbose="true" failonerror="false">
            <fileset file="${semantics.dir}/examples/${oneFileName}.ttl"/>
        </delete>
        <echo message="==========================================="/>
        <!-- TODO Saxon XML Catalogs https://www.saxonica.com/html/documentation/sourcedocs/xml-catalogs.html 
             XML Entity and URI Resolvers http://xerces.apache.org/xml-commons/components/resolver/resolver-article.html
            <xmlcatalog refid="X3dCatalog"/> -->
            
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-s:${semantics.dir}/examples/${oneFileName}.x3d" description="source-doc"/>
            <arg value="-o:${semantics.dir}/examples/${oneFileName}.ttl" description="output-doc"/>
            <arg value="-xsl:X3dToTurtle.xslt" description="style-doc"/>
            <arg value="insertPackagePrefix=false"/> <!-- parameter -->
            <!-- <arg value="-catalog:needFileName" description="style-doc"/> -->
            <!-- <arg value="className=CameraExamples"/> parameter -->
        </java>
        <echo message="test.X3dToTurtle.xslt.one conversion of ${oneFileName}.x3d to ${oneFileName}.ttl complete."/>
        <echo />
        <loadfile property="turtleFileContents" srcFile="${semantics.dir}/examples/${oneFileName}.ttl" />
        <echo message="${turtleFileContents}" />
        <echo message="==========================================="/>
    </target>
    
    <target name="test.X3dToJava.xslt" depends="test.mkdir,test.X3dToJava.xslt.one" description="Test X3dToJava.xslt stylesheet using Saxon and then X3DJSAIL" >
        <echo message="translation input: test/CameraExamples.x3d"/>
        <echo message="..expected output: test/CameraExamples.java"/>
        <delete file="test/CameraExamples.java" failonerror="false"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-s:test/CameraExamples.x3d" description="source-doc"/>
            <arg value="-o:test/CameraExamples.java" description="output-doc"/>
            <arg value="-xsl:X3dToJava.xslt" description="style-doc"/>
            <arg value="className=CameraExamples" description="parameter"/>
        </java>
        <echo message="compile..."/>
        <!-- avoid warning by using -release rather than -source and -target, https://ant.apache.org/manual/Tasks/javac.html -->
        <javac includes="CameraExamples.java" 
                 srcdir="test"
                destdir="test"
              classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};"
                  debug="on"
               encoding="UTF-8"
                release="${java.source}"
                verbose="false"
            failonerror="false"
               includeantruntime="false" fork="${fork}">
            <!-- -Xlint reports problem with direct object invocation of .isNode() or isStatement()
            <compilerarg value="-Xlint:all"/>
            -->
            <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap -->
            <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac -->
            <!-- https://stackoverflow.com/questions/20174355/how-class-loading-is-done-by-using-xbootclasspath-ppath -->
            <!-- https://stackoverflow.com/questions/48148607/how-to-add-a-jar-to-the-boot-classpath-in-java-9 -->
            <!-- -Xbootclasspath/p became -Xbootclasspath/a in jdk 9 -->
            <!-- <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> not allowed with target 15 -->
        </javac>
        <!-- self-validation test -->
        <echo message="test CameraExamples.java execution and self-validation:"/>
        <java classname="CameraExamples" 
                      dir="test"
                      classpath="test;${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};" fork="${fork}">
        </java>
        <echo message="==========================================="/>
        <echo message="org.web3d.x3d.jsail.CommandLine test/arc.x3d -toJava -toFile test/arc.java"/>
        <delete file="test/arc.java" failonerror="false"/>
        <java jar="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name}" fork="${fork}">
            <arg value="test/arc.x3d" description="input model"/>
            <arg value="-toJava"/>
            <arg value="-toFile"/>
            <arg value="test/arc.java"/>
        </java>
        <echo message="compile arc.java source..."/>
        <!-- avoid warning by using -release rather than -source and -target, https://ant.apache.org/manual/Tasks/javac.html -->
        <javac   srcdir="test"
                destdir="test"
              classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};"
                  debug="on"
               encoding="UTF-8"
                release="${java.source}"
                verbose="false"
            failonerror="false"
                includeantruntime="false" fork="${fork}">
            <!-- -Xlint reports problem with direct object invocation of .isNode() or isStatement()
            <compilerarg value="-Xlint:all"/>
            -->
            <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap -->
            <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac -->
            <!-- https://stackoverflow.com/questions/20174355/how-class-loading-is-done-by-using-xbootclasspath-ppath -->
            <!-- https://stackoverflow.com/questions/48148607/how-to-add-a-jar-to-the-boot-classpath-in-java-9 -->
            <!-- -Xbootclasspath/p became -Xbootclasspath/a in jdk 9 -->
            <!-- <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> not allowed with target 15 -->
        </javac>
        <!-- self-validation test -->
        <echo message="test arc.java execution and self-validation:"/>
        <java classname="arc" 
                      dir="test"
                      classpath="test;${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};" fork="${fork}">
        </java>
        <echo message="==========================================="/>
    </target>
    
    <target name="test.TestSurface" >
        <echo message="==========================================="/>
        <echo message="translation input: test/TestSurface.x3d"/>
        <echo message="..expected output: test/TestSurface.java"/>
        <delete file="test/TestSurface.java" failonerror="false"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-s:test/TestSurface.x3d" description="source-doc"/>
            <arg value="-o:test/TestSurface.java" description="output-doc"/>
            <arg value="-xsl:X3dToJava.xslt" description="style-doc"/>
            <arg value="className=TestSurface" description="parameter"/>
        </java>
        <echo message="compile..."/>
        <!-- avoid warning by using -release rather than -source and -target, https://ant.apache.org/manual/Tasks/javac.html -->
        <javac includes="TestSurface.java" 
                 srcdir="test"
                destdir="test"
              classpath="${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};"
                  debug="on"
               encoding="UTF-8"
                release="${java.source}"
                verbose="false"
               includeantruntime="false" fork="${fork}">
            <!-- -Xlint reports problem with direct object invocation of .isNode() or isStatement()
            <compilerarg value="-Xlint:all"/>
            -->
            <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap -->
            <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac -->
            <!-- https://stackoverflow.com/questions/20174355/how-class-loading-is-done-by-using-xbootclasspath-ppath -->
            <!-- https://stackoverflow.com/questions/48148607/how-to-add-a-jar-to-the-boot-classpath-in-java-9 -->
            <!-- -Xbootclasspath/p became -Xbootclasspath/a in jdk 9 -->
            <!-- <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> not allowed with target 15 -->
        </javac>
        <!-- self-validation test -->
        <echo message="test TestSurface.java execution and self-validation:"/>
        <java classname="TestSurface" 
                      dir="test"
                      classpath="test;${X3DJSAIL.jars.dir}/${jsail.full.archive.jar.name};" fork="${fork}">
        </java>
        <echo message="==========================================="/>
    </target>
    
    <target name="test.X3dToJson.xslt" depends="test.mkdir" description="Test X3dToJson.xslt stylesheet using Saxon" >
        <echo message="==========================================="/>
        <echo message="translation input: test/SmokeTestProgramOutput.x3d"/>
        <echo message="..expected output: test/SmokeTestProgramOutput.json"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-o:test/SmokeTestProgramOutput.json" description="output-doc"/>
            <arg value="-s:test/SmokeTestProgramOutput.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToJson.xslt" description="style-doc"/>
        </java>
        <echo>..error checking with jslint</echo>
        <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.json"/>
        </java>
        <echo>..error checking with json-schema-validator</echo>
        <java jar="${json-schema-validator.jar}" fork="${fork}">
            <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
            <arg value="${X3DJSAIL.examples.dir}/SmokeTestProgramOutput.json"/>
        </java>
        <echo message="==========================================="/>
        <echo>First check X3D JSON Schema:</echo>
        <echo>..error checking with jslint</echo>
        <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
            <!-- arg value="- -white"/ -->
            <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
        </java>
        <echo>..error checking with json-schema-validator</echo>
        <java jar="${json-schema-validator.jar}" fork="${fork}">
            <arg value="--syntax"/>
            <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
        </java>
        <echo message="==========================================="/>
        <echo message="translation input: AllX3dElementsAttributes3.3.xml"/>
        <echo message="..expected output: test/AllX3dElementsAttributes3.3.json"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-o:test/AllX3dElementsAttributes3.3.json" description="output-doc"/>
            <arg value="-s:AllX3dElementsAttributes3.3.xml" description="source-doc"/>
            <arg value="-xsl:X3dToJson.xslt" description="style-doc"/>
        </java>
        <echo>..error checking with jslint</echo>
        <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
            <arg value="test/AllX3dElementsAttributes3.3.json"/>
        </java>
        <echo>..no error checking with json-schema-validator since this is a special file</echo>
        <echo message="==========================================="/>
        <echo message="translation input: test/HelloWorld.x3d"/>
        <echo message="..expected output: test/HelloWorld.json"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-o:test/HelloWorld.json" description="output-doc"/>
            <arg value="-s:test/HelloWorld.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToJson.xslt" description="style-doc"/>
        </java>
        <echo>..error checking with jslint</echo>
        <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
            <arg value="test/HelloWorld.json"/>
        </java>
        <echo>..error checking with json-schema-validator</echo>
        <java jar="${json-schema-validator.jar}" fork="${fork}">
            <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
            <arg value="test/HelloWorld.json"/>
        </java>
        <echo message="==========================================="/>
        <echo message="translation input: ${examples.dir}/Basic/development/TestJsonEncoding.x3d"/>
        <echo message="..expected output: test/TestJsonEncoding.json"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-o:test/TestJsonEncoding.json" description="output-doc"/>
            <arg value="-s:${examples.dir}/Basic/development/TestJsonEncoding.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToJson.xslt" description="style-doc"/>
        </java>
        <echo>..error checking with jslint</echo>
        <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
            <arg value="test/TestJsonEncoding.json"/>
        </java>
        <echo>..error checking with json-schema-validator</echo>
        <java jar="${json-schema-validator.jar}" fork="${fork}">
            <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
            <arg value="test/TestJsonEncoding.json"/>
        </java>
        <echo message="==========================================="/>
        <echo message="translation input: ${examples.dir}/X3dForAdvancedModeling/Animation/OrigamiCranes.x3d"/>
        <echo message="..expected output: test/OrigamiCranes.json"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-o:test/OrigamiCranes.json" description="output-doc"/>
            <arg value="-s:${examples.dir}/X3dForAdvancedModeling/Animation/OrigamiCranes.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToJson.xslt" description="style-doc"/>
        </java>
        <echo>..error checking with jslint</echo>
        <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
            <arg value="test/OrigamiCranes.json"/>
        </java>
        <echo>..error checking with json-schema-validator</echo>
        <java jar="${json-schema-validator.jar}" fork="${fork}">
            <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
            <arg value="test/OrigamiCranes.json"/>
        </java>
        <echo message="==========================================="/>
        <echo message="translation input: ${examples.dir}/X3dForAdvancedModeling/Animation/CubeWithLabeledSidesViewpointSequencer.x3d"/>
        <echo message="..expected output: test/CubeWithLabeledSidesViewpointSequencer.json"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-o:test/CubeWithLabeledSidesViewpointSequencer.json" description="output-doc"/>
            <arg value="-s:${examples.dir}/X3dForAdvancedModeling/Animation/CubeWithLabeledSidesViewpointSequencer.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToJson.xslt" description="style-doc"/>
        </java>
        <echo>..error checking with jslint</echo>
        <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
            <arg value="test/CubeWithLabeledSidesViewpointSequencer.json"/>
        </java>
        <echo>..error checking with json-schema-validator</echo>
        <java jar="${json-schema-validator.jar}" fork="${fork}">
            <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
            <arg value="test/CubeWithLabeledSidesViewpointSequencer.json"/>
        </java>
        <echo message="==========================================="/>
        <echo message="translation input: ${examples.dir}/Basic/CAD/CadGeometryExternPrototypes.x3d"/>
        <echo message="..expected output: test/CadGeometryExternPrototypes.json"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-o:test/CadGeometryExternPrototypes.json" description="output-doc"/>
            <arg value="-s:${examples.dir}/Basic/CAD/CadGeometryExternPrototypes.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToJson.xslt" description="style-doc"/>
        </java>
        <echo>..error checking with jslint</echo>
        <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
            <arg value="test/CadGeometryExternPrototypes.json"/>
        </java>
        <echo>..error checking with json-schema-validator</echo>
        <java jar="${json-schema-validator.jar}" fork="${fork}">
            <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
            <arg value="test/CadGeometryExternPrototypes.json"/>
        </java>
        <echo message="==========================================="/>
        <echo message="translation input: ${examples.dir}/Basic/CAD/CadGeometryPrototypes.x3d"/>
        <echo message="..expected output: test/CadGeometryPrototypes.json"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-o:test/CadGeometryPrototypes.json" description="output-doc"/>
            <arg value="-s:${examples.dir}/Basic/CAD/CadGeometryPrototypes.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToJson.xslt" description="style-doc"/>
        </java>
        <echo>..error checking with jslint</echo>
        <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
            <arg value="test/CadGeometryPrototypes.json"/>
        </java>
        <echo>..error checking with json-schema-validator</echo>
        <java jar="${json-schema-validator.jar}" fork="${fork}">
            <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
            <arg value="test/CadGeometryPrototypes.json"/>
        </java>
        <echo message="==========================================="/>
        <echo message="translation input: ${X3DJSAIL.examples.dir}/flowers7.x3d"/>
        <echo message="..expected output: ${X3DJSAIL.examples.dir}/flowers7.json"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-o:${X3DJSAIL.examples.dir}/flowers7.json" description="output-doc"/>
            <arg value="-s:${X3DJSAIL.examples.dir}/flowers7.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToJson.xslt" description="style-doc"/>
        </java>
        <echo>..error checking with jslint</echo>
        <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
            <arg value="${X3DJSAIL.examples.dir}/flowers7.json"/>
        </java>
        <echo>..error checking with json-schema-validator</echo>
        <java jar="${json-schema-validator.jar}" fork="${fork}">
            <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
            <arg value="${X3DJSAIL.examples.dir}/flowers7.json"/>
        </java>
        <echo message="==========================================="/>
        <echo message="translation input: test/arc.x3d"/>
        <echo message="..expected output: test/arc.json"/>
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- <arg value="-t" description="timing information"/> -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-expand:on" description="force insertion of default attribute values found in DTD"/>
            <arg value="-o:test/arc.json" description="output-doc"/>
            <arg value="-s:test/arc.x3d" description="source-doc"/>
            <arg value="-xsl:X3dToJson.xslt" description="style-doc"/>
        </java>
        <echo>..error checking with jslint</echo>
        <java classname="com.googlecode.jslint4java.cli.Main" classpath="${jslint.jar}" fork="${fork}">
            <arg value="test/arc.json"/>
        </java>
        <echo>..error checking with json-schema-validator</echo>
        <java jar="${json-schema-validator.jar}" fork="${fork}">
            <arg value="../../specifications/x3d-3.3-JSONSchema.json"/>
            <arg value="test/arc.json"/>
        </java>
        <echo message="==========================================="/>
    </target>
    
    <target name="test.X3dTidy.HAnim.xslt" depends="test.mkdir" description="Test X3dTidy.xslt stylesheet for HAnim xslt tasks" >
        <delete file="test/HAnimSpecificationLOA3-TestSkeletonIllustrateTidy.x3d" failonerror="false"/>
        <xslt style="X3dTidy.xslt" in="test/HAnimSpecificationLOA3Invisible.x3d" out="test/HAnimSpecificationLOA3-TestSkeletonIllustrateTidy.x3d">
            <param name="HAnimGeometryRemove"         expression="false"/>
            <param name="HAnimSkeletonIllustrate"     expression="true"/>
            <param name="HAnimSiteIllustrate"         expression="false"/>
            <param name="HAnimViewpointIllustrate"    expression="false"/>
            <param name="HAnimAddBoneSegments"        expression="false"/>
        </xslt>
        <echo message="expected output: test/HAnimSpecificationLOA3-TestSkeletonIllustrateTidy.x3d"/>
        
        <delete file="test/HAnimSpecificationLOA3-TestSiteIllustrateTidy.x3d" failonerror="false"/>
        <xslt style="X3dTidy.xslt" in="test/HAnimSpecificationLOA3Invisible.x3d" out="test/HAnimSpecificationLOA3-TestSiteIllustrateTidy.x3d">
            <param name="HAnimGeometryRemove"         expression="false"/>
            <param name="HAnimSkeletonIllustrate"     expression="false"/>
            <param name="HAnimSiteIllustrate"         expression="true"/>
            <param name="HAnimViewpointIllustrate"    expression="false"/>
            <param name="HAnimAddBoneSegments"        expression="false"/>
        </xslt>
        <echo message="expected output: test/HAnimSpecificationLOA3-TestIllustratedTidy.x3d"/>
        
        <delete file="test/HAnimSpecificationLOA3-TestViewpointIllustrateTidy.x3d" failonerror="false"/>
        <xslt style="X3dTidy.xslt" in="test/HAnimSpecificationLOA3Invisible.x3d" out="test/HAnimSpecificationLOA3-TestViewpointIllustrateTidy.x3d">
            <param name="HAnimGeometryRemove"         expression="false"/>
            <param name="HAnimSkeletonIllustrate"     expression="false"/>
            <param name="HAnimSiteIllustrate"         expression="false"/>
            <param name="HAnimViewpointIllustrate"    expression="true"/>
            <param name="HAnimAddBoneSegments"        expression="false"/>
        </xslt>
        <echo message="expected output: test/HAnimSpecificationLOA3-TestViewpointIllustrateTidy.x3d"/>

        <delete file="test/HAnimSpecificationLOA3-TestGeometryRemoveTidy.x3d" failonerror="false"/>
        <xslt style="X3dTidy.xslt" in="test/HAnimSpecificationLOA3Illustrated.x3d" out="test/HAnimSpecificationLOA3-TestGeometryRemoveTidy.x3d">
            <param name="HAnimGeometryRemove"         expression="true"/>
            <param name="HAnimSkeletonIllustrate"     expression="false"/>
            <param name="HAnimSiteIllustrate"         expression="false"/>
            <param name="HAnimViewpointIllustrate"    expression="false"/>
            <param name="HAnimAddBoneSegments"        expression="false"/>
        </xslt>
        <echo message="expected output: test/HAnimSpecificationLOA3-TestGeometryRemoveTidy.x3d"/>
        <!-- TODO diff with HAnimSpecificationLOA3Invisible.x3d -->
    </target>
    
    <target name="test.X3dTidy.xslt" depends="test.mkdir" description="Test X3dTidy.xslt stylesheet using default Ant xslt task" >
        <!-- Specially prepared HelloWorldSimpleUrl.x3d is found in test/ subdirectory, refresh of other scenes handled by get-test-scenes target -->
        <delete file="test/HelloWorldSimpleUrlTidy.x3d" failonerror="false"/>
        <!-- Ant xslt task:  http://ant.apache.org/manual/Tasks/style.html -->
        <xslt style="X3dTidy.xslt" in="test/HelloWorldSimpleUrl.x3d" out="test/HelloWorldSimpleUrlTidy.x3d" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." >
            <factory name="net.sf.saxon.TransformerFactoryImpl"/>
            <param name="title"                       expression="HelloWorldSimpleUrl.x3d"/>
            <param name="conversionRequired"          expression="true"/>
            <param name="fixMFStringQuotes"           expression="true"/>
            <param name="fixUrlAdditionHttpAddresses" expression="true"/>
            <param name="modifyX3dVersion"            expression="true"/>
            <param name="revisedX3dVersion"           expression="3.0"/>
            <param name="appendMissingMetaLicense"    expression="true"/>
            <param name="licenseLink"                 expression="../../license.html"/>
            <!--<param name="defaultUrlAddress"           expression="http://X3dGraphics.com/examples/X3dForWebAuthors"/> -->
        </xslt>
        <echo message="expected output: test/HelloWorldSimpleUrlTidy.x3d"/>
        
        <delete file="test/TestScriptInitializationTidy.x3d" failonerror="false"/>
        <xslt style="X3dTidy.xslt"  in="test/TestScriptInitialization.x3d" out="test/TestScriptInitializationTidy.x3d" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};.">
            <factory name="net.sf.saxon.TransformerFactoryImpl"/>
        </xslt>
        <echo message="expected output: test/TestScriptInitialization.x3d"/>

        <delete file="test/arcTidy.x3d" failonerror="false"/>
        <xslt style="X3dTidy.xslt"  in="test/arc.x3d" out="test/arcTidy.x3d" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};.">
            <factory name="net.sf.saxon.TransformerFactoryImpl"/>
        </xslt>
        <echo message="expected output: test/arc.x3d"/>
		
        <delete file="test/TextSpecialCharactersTidy.x3d" failonerror="false"/>
        <xslt style="X3dTidy.xslt"  in="test/TextSpecialCharacters.x3d" out="test/TextSpecialCharactersTidy.x3d" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};.">
            <factory name="net.sf.saxon.TransformerFactoryImpl"/>
        </xslt>
        <echo message="expected output: test/TextSpecialCharacters.x3d"/>
        
        <delete file="test/HelloWorldTidy.x3d" failonerror="false"/>
        <xslt style="X3dTidy.xslt"  in="test/HelloWorld.x3d"              out="test/HelloWorldTidy.x3d" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};.">
            <factory name="net.sf.saxon.TransformerFactoryImpl"/>
        </xslt>
        <echo message="expected output: test/HelloWorld.x3d"/>
        
        <delete file="test/HelloWorldSignedTidy.x3d" failonerror="false"/>
        <xslt style="X3dTidy.xslt"  in="test/HelloWorldSigned.x3d"      out="test/HelloWorldSignedTidy.x3d" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};.">
            <factory name="net.sf.saxon.TransformerFactoryImpl"/>
        </xslt>
        <echo message="expected output: test/HelloWorldSigned.x3d"/>
        
        <delete file="test/Background2Tidy.x3d" failonerror="false"/>
        <xslt style="X3dTidy.xslt"  in="test/Background2.x3d"      out="test/Background2Tidy.x3d" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};.">
            <factory name="net.sf.saxon.TransformerFactoryImpl"/>
        </xslt>
        <echo message="expected output: test/Background2.x3d"/>
    </target>
    
    <target name="test.X3dToX3domX_ITE.xslt" depends="test.mkdir" description="Test X3dToVrml97.xslt stylesheet using default Ant xslt task" >
        <echo message="TODO upgrade these targets to Saxon conversion"/>
        <xslt style="X3dToX3domX_ITE.xslt" in="${examples.dir}/HelloWorld.x3d"                               out="test/HelloWorld.xhtml"/>
        <!-- HAnim -->
        <xslt style="X3dToX3domX_ITE.xslt" in="${examples.dir}/HumanoidAnimation/Characters/JinLOA1.x3d"  out="test/HAnimSpecificationLOA3Illustrated.xhtml"/>
        <xslt style="X3dToX3domX_ITE.xslt" in="${examples.dir}/X3dForWebAuthors/Chapter15Metadata/WorldInfoExample.x3d"  out="test/WorldInfoExample.xhtml"/>
        
        <!-- CAD
       <xslt style="X3dToX3domX_ITE.xslt" in="${examples.dir}/Basic/CAD/CadTeapot.x3d"                      out="test/CadTeapot.xhtml"/>
       <xslt style="X3dToX3domX_ITE.xslt" in="${examples.dir}/Basic/CAD/IndexedQuadSetExample.x3d"          out="test/IndexedQuadSetExample.xhtml"/>
       <xslt style="X3dToX3domX_ITE.xslt" in="${examples.dir}/Basic/CAD/QuadSetColor.x3d"                   out="test/QuadSetColor.xhtml"/>
       <xslt style="X3dToX3domX_ITE.xslt" in="${examples.dir}/Basic/CAD/IndexedQuadSetTexture.x3d"          out="test/IndexedQuadSetTexture.xhtml"/>
       <xslt style="X3dToX3domX_ITE.xslt" in="${examples.dir}/Basic/CAD/CadDesignPatternExampleBushing.x3d" out="test/CadDesignPatternExampleBushing.xhtml"/>
        -->
    </target>
    
    <target name="test.X3dToVrml97.xslt" depends="test.mkdir" description="Test X3dToVrml97.xslt stylesheet using default Ant xslt task" >
        <xslt style="X3dToVrml97.xslt" in="${examples.dir}/HelloWorld.x3d" out="test/HelloWorld.xslt.wrl"/>
        <!-- test escaping of quote marks inside a script -->
        <xslt style="X3dToVrml97.xslt" in="${examples.dir}/Basic/CAD/CadGeometryPrototypes.x3d" out="test/CadGeometryPrototypes.xslt.wrl"/>
        <echo message="expected output: test/CadGeometryPrototypes.xslt.wrl"/>
    </target>
    
    <target name="test.X3dToX3dvClassicVrmlEncoding.xslt" depends="test.mkdir" description="Test X3dToX3dvClassicVrmlEncoding.xslt stylesheet using default Ant xslt task" >
        <xslt style="X3dToX3dvClassicVrmlEncoding.xslt" in="${examples.dir}/HelloWorld.x3d" out="test/HelloWorld.xslt.x3dv"/>
        <echo message="expected output: test/HelloWorld.xslt.x3dv"/>
    </target>

    <target name="scp.askUsernamePassword.web3d"
            description="If needed, ask for username, password">
        <if>
            <not>
                <and>
                    <isset property="username.web3d"/>
                    <isset property="password.web3d"/>
                </and>
            </not>
            <then>
                <echo  message="username.web3d, password.web3d not obtained via file ${access.properties.filename}"/>
                <input message="username.web3d:"
                       addproperty="username.web3d" />
                <input message="password.web3d:"
                       addproperty="password.web3d" />
                <echo  message="username.web3d=${username.web3d}"/>
                <echo  message="password.web3d=################"/>
                <!--<echo  message="password.web3d=${password.web3d}"/> debug -->
            </then>
            <else>
                <echo  message="hostname.web3d, username.web3d, password.web3d obtained from file ${access.properties.filename}"/>
            </else>
        </if>
    </target>

    <target name="upload"                        depends="scp.upload.stylesheets.web3d"/>

    <target name="upload.X3DJSAIL" depends="scp.upload.X3DJSAIL.web3d" description="rebuild and upload full X3DJSAIL release">
        <!-- updates usually handled by create.X3DJSAIL.jars
        <ant antfile="../content/examples/build.xml" target="copy.X3DJSAIL.update.local"/> -->
        <antcall                      target="view.X3DJSAIL.online"/>
        <ant antfile="java/build.xml" target="view.javadoc.online"/>
    </target>

    <target name="upload.X3DPSAIL" depends="">
        <ant antfile="python/build.xml" target="upload.web3d" inheritall="false"/>
    </target>

    <target name="upload.SpecificationInterfaces" depends="scp.upload.XmlEncodingSpecificationInterfaces.web3d"/>

    <!-- ensure that you have already connected to this host via ssh and saved the server key -->
    <target name="scp.upload.stylesheets.web3d" depends="scp.askUsernamePassword.web3d"
            description="scp sftp upload of updated X3D archive files">
        <echo  message="scp (sftp) upload stylesheets to ${sftpServer.web3d}${sftpDirectory.web3d.stylesheets}"/>
        <!-- upload stylesheets -->
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.stylesheets}" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir=".">
                <include name="*.xml"/>
                <include name="*.xslt"/>
                <!--<include name="*.sxx"/> .sxx is saxon-compiled stylesheet, no longer used -->
                <include name="*.bat"/>
                <include name="*.html"/>
                <include name="*.gif"/>
                <include name="*.png"/>
                <include name="*.txt"/>
                <include name="images/*"/>
                <include name="X3dToXhtmlStylesheetExamples.zip"/>
                <exclude name="EncodingOfNodes.html"/>
                <exclude name="EncodingOfStatements.html"/>
            </fileset>
        </scp>
        <!-- TODO isn't this part of specifications/schema updates? -->
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.stylesheets}" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir=".">
                <include name="EncodingOfNodes.html"/>
            </fileset>
        </scp>
        <echo  message="results online at ${sftpServer.web3d}/x3d/stylesheets"/><!-- https://www.web3D.org/x3d/stylesheets -->
        <echo  message="scp.upload.stylesheets.web3d ssh-sftp task complete"/>
    </target>

    <target name="scp.upload.X3DJSAIL.web3d" depends="create.X3DJSAIL,scp.askUsernamePassword.web3d"
            description="scp sftp upload of autogenerated X3D Java Scene Authoring Interface Library (X3DJSAIL)">

        <echo  message="scp (sftp) upload CreateX3dSceneAccessInterfaceJava.xslt stylesheets to ${sftpServer.web3d}${sftpDirectory.web3d.stylesheets}"/>
        <echo  message="  https://www.web3D.org/x3d/stylesheets/CreateX3dSceneAccessInterfaceJava.xslt"/>
        <!-- upload stylesheet and build script -->
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.stylesheets}" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir=".">
                <include name="CreateX3dSceneAccessInterfaceJava.xslt"/>
                <include name="build.xml"/>
            </fileset>
        </scp>
        <echo  message="scp (sftp) upload autogenerated Java Scene Authoring Interface (SAI) to ${sftpServer.web3d}${sftpDirectory.web3d.specifications}"/>
        <!-- upload products and .jar files first for rapid deployment -->
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.specifications}/" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir=".">
                <include name="${X3DJSAIL.relative.dir}/.htaccess"/>
                <include name="${X3DJSAIL.relative.dir}/*.*"/>
                <include name="${X3DJSAIL.relative.dir}/images/*.*"/>
                <include name="${X3DJSAIL.relative.dir}/examples/**/*.*"/>
                <include name="${X3DJSAIL.relative.dir}/references/**/*"/>
                <exclude name="**nbproject/*"/>
            </fileset>
        </scp>
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.specifications}/java/jars" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir="${X3DJSAIL.jars.dir}">
                <include name="*.jar"/>
            </fileset>
        </scp>
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.specifications}/" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir=".">
                <include name="test.bat"/>
                <include name="${X3DJSAIL.relative.dir}/.htaccess"/>
                <include name="${X3DJSAIL.relative.dir}/README.txt"/>
                <include name="${X3DJSAIL.relative.dir}/javadoc/*"/><!-- not dist! -->
                <include name="${X3DJSAIL.relative.dir}/**/*"/>
                <include name="${X3DJSAIL.lib.dir}/*"/>
                <include name="${X3DJSAIL.src.dir}/*"/>
                <include name="${X3DJSAIL.relative.dir}/${nashorn.dir}/*"/>
                <exclude name="${X3DJSAIL.jars.dir}/*.jar"/>
            </fileset>
        </scp>
        <echo  message="results online at https://www.web3D.org/specifications/java"/>
		
        <echo  message="scp.upload.X3DJSAIL.web3d ssh-sftp task complete"/>
    </target>

    <target name="scp.upload.semantics.web3d" depends="scp.askUsernamePassword.web3d"
            description="scp sftp upload of X3D Ontology semantics project">
        <echo message="scp sftp upload of X3D Ontology master copies to ${sftpDirectory.web3d.specifications}"/>
        <!-- copy of master ontology goes in specifications directory so that URI matches URL -->
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.specifications}" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir="../../semantics/ontologies">
                <include name="X3dOntology*.*"/>
            </fileset>
        </scp>
        <echo message="scp sftp upload of X3D Ontology semantics project to ${sftpDirectory.web3d.semantics}"/>
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.semantics}" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir="../../semantics">
                <include name="*.html"/>
                <include name="build.xml"/>
                <include name="build.*.txt"/>
                <include name="license.*"/>
                <include name="examples/**/*"/>
                <include name="images/**/*"/>
                <include name="ontologies/**/*"/>
                <include name="queries/**/*"/>
                <include name="nbproject/project.xml"/>
                <exclude name="**/archive/*"/>
                <exclude name="**/*.pdf"/>
                <exclude name="**/*.pptx"/>
                <exclude name="**/*.mp4"/>
            </fileset>
        </scp>
        <!-- zip is large so do it after refreshed assets -->
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.semantics}" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir="../../semantics">
                <include name="X3dSemanticWebDevelopmentArchive.zip"/>
            </fileset>
        </scp>
        <!-- documentation (especially owldoc) is voluminous so do it last -->
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.semantics}" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir="../../semantics">
                <include name="documentation/**/*.*"/>
                <exclude name="**/archive/*"/>
            </fileset>
        </scp>
        <echo  message="scp.upload.semantics.web3d ssh-sftp task complete"/>
    </target>

    <target name="scp.upload.semantics.web3d.large" depends="scp.askUsernamePassword.web3d"
            description="scp sftp upload of X3D Ontology semantics project, large files">
        <echo message="scp sftp upload of large files to X3D Ontology master copies to ${sftpDirectory.web3d.specifications}"/>
        <echo message="scp sftp upload of large files to X3D Ontology semantics project to ${sftpDirectory.web3d.semantics}"/>
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.semantics}" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir="../../semantics">
                <include name="**/*.pdf"/>
                <include name="**/*.pptx"/>
                <include name="**/*.mp4"/>
            </fileset>
        </scp>
        <echo  message="scp.upload.semantics.web3d.large ssh-sftp task complete"/>
    </target>

    <target name="scp.upload.python.web3d" depends="scp.askUsernamePassword.web3d"
            description="scp sftp upload of x3d.py Python package project">
        
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.stylesheets}/python" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir="python">
                <include name=".pylintrc"/>
                <include name="python.html"/>
                <include name="build.xml"/>
                <include name="build.*.txt"/>
                <include name="README.md"/>
                <include name="license.*"/>
                <include name="setup.py"/>
                <include name="__init__.py"/>
                <include name="x3d.py"/>
                <include name="x3d.html"/><!-- pydoc -->
                <include name="examples/*"/>
                <include name="images/*"/>
                <include name="jupyter/*"/>
                <include name="documents/*"/>
            </fileset>
        </scp>
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.stylesheets}/python" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir="python">
                <include name="PythonX3dDevelopmentArchive.zip"/>
            </fileset>
        </scp>
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.stylesheets}/python/documents" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir="python/documents">
                <include name="*.*"/>
            </fileset>
        </scp>
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.stylesheets}/python/examples" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir="python/examples">
                <include name="*.py"/>
                <include name="README.md"/>
                <include name="__init__.py"/>
                <exclude name="x3d.py"/>
            </fileset>
        </scp>
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.stylesheets}/python/images" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir="python/images">
                <include name="X3dPythonPackageDesign2019July3.1600x839.jpg"/>
            </fileset>
        </scp>
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.stylesheets}/python/jupyter" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset dir="python/jupyter">
                <include name="*.*"/>
            </fileset>
        </scp>

        <echo  message="scp.upload.python.web3d ssh-sftp task complete"/>
    </target>

    <target name="scp.upload.XmlEncodingSpecificationInterfaces.web3d" depends="scp.askUsernamePassword.web3d"
            description="scp sftp upload of updated X3D archive files">
        <echo  message="copy stylesheets to local specifications/stylesheets directory"/>
        <mkdir  dir="../../specifications/JavaLanguageBinding"/>
        <copy todir="../../specifications/JavaLanguageBinding" verbose="true" failonerror="false">
            <fileset dir="." id="stylesheetGenerationProducts">
                <include name="**/*"/>
                <!--
                <include name="build.xml"/>
                <include name="EncodingOfNodes.html"/>
                <include name="JavaLanguageBinding.Part2.nodeTypeInterfaces.html"/>
                <include name="JavaLanguageBinding.Part2.nodeInterfaces.html"/>
                <include name="X3DEncodings.css"/>
                <include name="cube.gif"/>
                <include name="x3d.png"/>
                <include name="x3dbar.png"/>
                <include name="BuildSpecificationXmlEncodingFromSchema.xslt"/>
                <include name="BuildSpecificationLanguageBindingJava.xslt"/>
                -->
            </fileset>
        </copy>
        <echo  message="scp (sftp) upload stylesheets to ${sftpServer.web3d}${sftpDirectory.web3d.stylesheets}"/>
        <!-- upload stylesheets -->
        <!-- if connection fails due to "reject HostKey" then need to separately connect via ssh in order accept and cache digital signature.  watch out for multiple keystores! -->
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.specifications}/stylesheets" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset refid="stylesheetGenerationProducts"/>
        </scp>
        <echo  message="results online at https://www.web3D.org/specifications/stylesheets/EncodingOfNodes.html"/>
        <echo  message="           and at https://www.web3D.org/specifications/stylesheets/EncodingOfStatements.html"/>
        <echo  message="           and at https://www.web3D.org/specifications/stylesheets/JavaLanguageBinding/Part2/nodeTypeInterfaces.html"/>
        <echo  message="           and at https://www.web3D.org/specifications/stylesheets/JavaLanguageBinding/Part2/nodeInterfaces.html"/>
        <scp remotetodir="${username.web3d}@${sftpServer.web3d}:${sftpDirectory.web3d.stylesheets}" password="${password.web3d}"
               trust="yes"
             verbose="true" failonerror="false">
            <fileset refid="stylesheetGenerationProducts"/>
        </scp>
        <echo  message="results online at https://www.web3D.org/x3d/stylesheets/EncodingOfNodes.html"/>
        <echo  message="               at https://www.web3D.org/x3d/stylesheets/JavaLanguageBinding/Part2/nodeTypeInterfaces.html"/>
        <echo  message="           and at https://www.web3D.org/x3d/stylesheets/JavaLanguageBinding/Part2/nodeInterfaces.html"/>
        <echo  message="scp.upload.stylesheets.web3d ssh-sftp task complete"/>
    </target>

    <target name="zip.X3dToXhtmlStylesheetExamples" depends="" description="zip X3D to XHTML stylesheet conversion examples" >
        <zip destfile="X3dToXhtmlStylesheetExamples.zip">
            <zipfileset dir="." prefix="www.web3d.org/x3d/stylesheets/">
                <include name="X3dToXhtml.xslt"/>
                <include name="X3dToXhtml-1.xslt"/>
                <include name="X3dToXhtml-2.xslt"/>
                <include name="X3dToXhtml-3.xslt"/>
                <include name="X3dToXhtml-4.xslt"/>
                <include name="X3dToXhtml-5.xslt"/>
                <include name="X3dToXhtml.bat"/>
                <include name="README.txt"/>
                <include name="license.*"/>
                <include name="*.html"/>
            </zipfileset>
            <zipfileset dir="${examples.dir}" prefix="www.web3d.org/x3d/stylesheets/">
                <include name="HelloWorld.x3d"/>
            </zipfileset>
        </zip>
    </target>

    <!-- subversion checkout address to download latest x3d configuration files -->
    <property name="x3d.sourceforge.site" value="https://svn.code.sf.net/p/x3d/code/www.web3d.org"/>

    <target name="hudson" description="nightly build" depends="hudson.prepare,build">
        <!-- hudson project description
    <p>
    Build and test <a href="https://www.web3D.org/x3d/content/examples/X3dResources.html#Stylesheets" target="_blank">X3D Stylesheets</a> that convert X3D scenes to produce corresponding encodings in ClassicVRML .x3dv, VRML97 .wrl, and also pretty-print documentation .html versions.
    </p>
    
    <p>
      This project also builds
      X3D specification XML encodings clause 6, 
      <a href="ws/stylesheets/EncodingOfNodes.html">Encoding of Nodes</a>.
    </p>
        -->
    </target>

    <target name="hudson.prepare" description="setup hudson server-side build" depends="">
        <!-- hudson configuration needs to reset Ant property values to match subdirectories below:
        examples.dir=hudson/examples
        saxon.dir=hudson/lib
        specifications.dir=hudson/specifications
        ignoreSetupDownloadErrors=true-->
        <echo message="Build settings:        fork=${fork}"/>
        <echo message="  ignoreSetupDownloadErrors=${ignoreSetupDownloadErrors}"/>
        <echo message="get local copies of dependency files in order to independently prepare hudson server-side build"/>
        <mkdir dir="hudson/examples/Basic/course"/>
        <get src="${x3d.sourceforge.site}/x3d/content/examples/HelloWorld.x3d"
             dest="hudson/examples/HelloWorld.x3d" verbose="true" failonerror="false" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <get src="${x3d.sourceforge.site}/x3d/content/examples/Basic/course/ExtrusionHeart.x3d"
             dest="hudson/examples/Basic/course/ExtrusionHeart.x3d" verbose="true" failonerror="false" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <mkdir dir="hudson/specifications"/>
        <get src="${x3d.sourceforge.site}/specifications/OasisXmlCatalogX3D.xml"
             dest="hudson/specifications/OasisXmlCatalogX3D.xml" verbose="true" failonerror="false" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <get src="${x3d.sourceforge.site}/specifications/x3d-3.0.xsd"
             dest="hudson/specifications/x3d-3.0.xsd" verbose="true" failonerror="false" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <get src="${x3d.sourceforge.site}/specifications/x3d-3.1.xsd"
             dest="hudson/specifications/x3d-3.1.xsd" verbose="true" failonerror="false" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <get src="${x3d.sourceforge.site}/specifications/x3d-3.2.xsd"
             dest="hudson/specifications/x3d-3.2.xsd" verbose="true" failonerror="false" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <get src="${x3d.sourceforge.site}/specifications/x3d-3.3.xsd"
             dest="hudson/specifications/x3d-3.3.xsd" verbose="true" failonerror="false" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <get src="${x3d.sourceforge.site}/specifications/x3d-4.0.xsd"
             dest="hudson/specifications/x3d-4.0.xsd" verbose="true" failonerror="false" ignoreerrors="${ignoreSetupDownloadErrors}"/>
        <!-- note destination is lib (vice bin) for consistency -->
        <mkdir dir="hudson/lib"/>
        <get src="${x3d.sourceforge.site}/x3d/tools/schematron/bin/${saxon.jar}"
             dest="hudson/lib/${saxon.jar}" verbose="true" failonerror="false" ignoreerrors="${ignoreSetupDownloadErrors}"/>
    </target>

    <target name="get-test-scenes" description="Retrieve test files, which are also maintained locally in subversion so that any test changes are noticed">
        <mkdir dir="test"/>
        <get src="${x3d.sourceforge.site}/x3d/content/examples/HelloWorld.x3d"
             dest="test/HelloWorld.x3d"/>
        <get src="${x3d.sourceforge.site}/x3d/content/examples/Basic/development/SpinGroupInternalSubsetDeclaration.x3d"
             dest="test/SpinGroupInternalSubsetDeclaration.x3d"/>
        <get src="${x3d.sourceforge.site}/x3d/content/examples/HumanoidAnimation/HAnimSpecificationLOA3Invisible.x3d"
             dest="test/HAnimSpecificationLOA3Invisible.x3d"/>
        <get src="${x3d.sourceforge.site}/x3d/content/examples/HumanoidAnimation/HAnimSpecificationLOA3Illustrated.x3d"
             dest="test/HAnimSpecificationLOA3Illustrated.x3d"/>
        <get src="${x3d.sourceforge.site}/x3d/content/examples/Basic/Security/HelloWorldSigned.x3d"
             dest="test/HelloWorldSigned.x3d"/>
        <get src="${x3d.sourceforge.site}/x3d/content/examples/Vrml2.0Sourcebook/Siggraph98Course/Background2.x3d"
             dest="test/Background2.x3d"/>
        <get src="${x3d.sourceforge.site}/x3d/content/examples/X3dForWebAuthors/Chapter02GeometryPrimitives/TextSpecialCharacters.x3d"
             dest="test/TextSpecialCharacters.x3d"/>
        <get src="${x3d.sourceforge.site}/x3d/content/examples/X3dForWebAuthors/Chapter09EventUtilitiesScripting/TestScriptInitialization.x3d"
             dest="test/TestScriptInitialization.x3d"/>
    </target>

    <target name="get-test-scenes-local" description="developmental support">
        <copy file="${examples.dir}/HelloWorld.x3d"                                                                 todir="test/" verbose="true" failonerror="false" force="true"/>
        <copy file="${examples.dir}/Basic/development/SpinGroupInternalSubsetDeclaration.x3d"                       todir="test/" verbose="true" failonerror="false" force="true"/>
        <copy file="${examples.dir}/HumanoidAnimation/HAnimSpecificationLOA3Invisible.x3d"                          todir="test/" verbose="true" failonerror="false" force="true"/>
        <copy file="${examples.dir}/HumanoidAnimation/HAnimSpecificationLOA3Illustrated.x3d"                        todir="test/" verbose="true" failonerror="false" force="true"/>
        <copy file="${examples.dir}/Basic/Security/HelloWorldSigned.x3d"                                            todir="test/" verbose="true" failonerror="false" force="true"/>
        <copy file="${examples.dir}/Vrml2.0Sourcebook/Siggraph98Course/Background2.x3d"                             todir="test/" verbose="true" failonerror="false" force="true"/>
        <copy file="${examples.dir}/X3dForWebAuthors/Chapter02GeometryPrimitives/TextSpecialCharacters.x3d"         todir="test/" verbose="true" failonerror="false" force="true"/>
        <copy file="${examples.dir}/X3dForWebAuthors/Chapter09EventUtilitiesScripting/TestScriptInitialization.x3d" todir="test/" verbose="true" failonerror="false" force="true"/>
    </target>
    
    <!-- JAXB 2.3.1 (pre-Eclipse) https://javaee.github.io/jaxb-v2 -->
    <!-- https://javaee.github.io/jaxb-v2/doc/user-guide/ch04.html#tools-xjc-ant-task -->
    <!-- https://javaee.github.io/jaxb-v2 -->
    <!-- https://dzone.com/articles/using-jaxb-for-xml-with-java -->
    <taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask">
        <classpath>
            <fileset dir="${jaxb.dir}" includes="*.jar"/>
        </classpath>
    </taskdef>

    <target name="create.X3DUOM.JAXB.schema" description="build X3DUOM JAXB bindings">
        <echo message="Netbeans 11+ (Java 12+) prerequisite is to include following in your netbeans.conf file:"/>
        <echo message="  -J-Djavax.xml.bind.context.factory=com.sun.xml.bind.v2.ContextFactory"/>
        <echo message="  see https://www.web3d.org/x3d/content/examples/X3dDevelopersGuide.html#NetBeans"/>
        <echo message="  see https://github.com/javaee/jaxb-v2"/>
        
        <echo message="  $jaxb.dir=${jaxb.dir}"/>
        <fileset id="jaxb.contents" dir="${jaxb.dir}" includes="*"/> 
        <property   name="property.jaxb.contents" refid="jaxb.contents"/>
        <echo message="  $property.jaxb.contents=${property.jaxb.contents}"/>

        <delete failonerror="false" verbose="true">
            <fileset dir="${src.org.web3d.x3d.util.x3duom}" includes="**/*"/><!-- includes JAXB-generated files -->
        </delete>
        <mkdir dir="${src.org.web3d.x3d.util.x3duom}"/>
        
        <!-- TODO problem: directory becomes readonly, has to be reset manually, following tasks are not working -->
        <echo message="Ant chmod g+w $jaxb.dir=${jaxb.dir}"/>
        <chmod dir="${jaxb.dir}" perm="g+w" includes="**/*" type="both" verbose="true"/>
        <echo message="Ant chmod g+w $src.org.web3d.x3d.util.x3duom=${src.org.web3d.x3d.util.x3duom}"/>
        <chmod dir="${src.org.web3d.x3d.util.x3duom}" perm="g+w" includes="**/*" type="both" verbose="true"/>
        <echo message="if permissions fail, set the following directory to writeable:"/>
        <echo message="  C:\x3d-code\www.web3d.org\x3d\stylesheets\java\src\org\web3d\x3d\util\x3duom"/>
        
        <echo message="Ant xjc with classpath=${jaxb.dir}/*.jar"/>
        <xjc schema="../../specifications/X3dUnifiedObjectModel.xsd" package="org.web3d.x3d.util.x3duom"
             destdir="java/src" header="true" readonly="true"> <!-- no verbose attribute provided -->
            <classpath>
                <fileset dir="${jaxb.dir}" includes="*.jar"/>
            </classpath>
        </xjc>
        <echo message="Compiling org.web3d.x3d.x3duom JAXB classes"/>
        <!-- avoid warning by using -release rather than -source and -target, https://ant.apache.org/manual/Tasks/javac.html -->
        <javac   srcdir="${src.org.web3d.x3d.util.x3duom}"
                destdir="${X3DJSAIL.classes.dir}"
                  debug="on"
               encoding="UTF-8"
                release="${java.source}"
                verbose="${javac.verbose}"
      includeantruntime="false">
            <classpath>
                <fileset dir="${jaxb.dir}" includes="*.jar"/>
            </classpath>
            <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap -->
            <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac -->
            <!-- https://stackoverflow.com/questions/20174355/how-class-loading-is-done-by-using-xbootclasspath-ppath -->
            <!-- https://stackoverflow.com/questions/48148607/how-to-add-a-jar-to-the-boot-classpath-in-java-9 -->
            <!-- -Xbootclasspath/p became -Xbootclasspath/a in jdk 9 -->
            <!-- <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> not allowed with target 15 -->
        </javac>
    </target>

    <target name="BuildConfigurationNotepad++" depends="" description="Exemplar template that builds text version of AllX3dElementsAttributes.xml">
        <!-- TODO add other X3D versions -->
        <!-- ========================================= -->
        <java classname="net.sf.saxon.Transform" classpath="${saxon.dir}/${saxon.jar};${saxon.dir}/${xmlresolver.jar};." fork="${fork}">
            <!-- https://stackoverflow.com/questions/19322484/java-entityexpansionlimit-where-do-i-set-this -->
            <!-- https://ant.apache.org/manual/Tasks/java.html -->
            <!-- https://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html -->
            <!-- also needs to be set in netbeans.conf and NetBeans Tools Options Java Ant Properties entityExpansionLimit=120000 -->
            <jvmarg value="-Djdk.xml.entityExpansionLimit=120000"/>
            <jvmarg value="-Djdk.xml.totalEntitySizeLimit=50000000"/>
            <!-- arg value="-t" description="timing information"/ -->
            <arg value="-warnings:recover" description="recover after writing a warning message"/>
            <arg value="-s:AllX3dElementsAttributes4.0.xml"          description="source-doc"/><!-- produced from X3DUOM  -->
            <arg value="-xsl:ConfigurationFilesNotepadPlusPlus.xslt" description="style-doc"/> <!-- conversion stylesheet -->
            <arg value="-o:X3DV.xml"                                 description="output-doc"/>
            <!-- <arg value="outputFilePrefix=ConfigurationFileNotepad"/> parameter -->
        </java>
        <copy file="X3DV.xml"         todir="../tools/Npp/Syntax/"  verbose="true" failonerror="false"/>
        <!-- three more file outputs to follow... -->
        <!-- ========================================= -->
      </target>

</project>
