<?xml version="1.0" encoding="UTF-8"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<project name="Tomcat 10.1" default="deploy" basedir="."
  xmlns:if="ant:if"
  xmlns:unless="ant:unless"
  xmlns:jacoco="antlib:org.jacoco.ant"
  >

  <!-- ===================== Initialize Property Values ==================== -->

  <!-- We read customizable properties from "build.properties.default"       -->
  <!-- and also from "build.properties" if it exists.                        -->
  <!-- The values in "build.properties" have stronger preference.            -->
  <!-- If you want to customize your build, you can either change the values -->
  <!-- directly in the default file, or create a new build.properties and    -->
  <!-- set the values there. This way you don't have to change a file which  -->
  <!-- is part of the original project source code.                          -->
  <!-- See "build.properties.default" in the top level directory for some    -->
  <!-- property values you may customize.                                    -->
  <property file="${user.home}/build.properties"/>
  <property file="build.properties"/>
  <property file="build.properties.release"/>
  <property file="build.properties.default"/>

  <!-- Check Ant Version -->
  <fail message="Ant version ${ant.version.required} or newer is required (${ant.version} is installed)">
    <condition>
      <not><antversion atleast="${ant.version.required}" /></not>
    </condition>
  </fail>

  <!-- Project Name -->
  <property name="project"               value="apache-tomcat" />

  <!-- Version numbers -->
  <!-- Keep in sync with webapps/docs/tomcat-docs.xsl -->
  <property name="version"               value="${version.major}.${version.minor}.${version.build}${version.suffix}${version.dev}" />
  <property name="version.number"        value="${version.major}.${version.minor}.${version.build}.${version.patch}" />
  <property name="version.major.minor"   value="${version.major}.${version.minor}" />

  <!-- constant to declare a file binary for md5sum -->
  <property name="md5sum.binary-prefix"  value=" *" />

  <!-- Exact spec versions (for the manifests etc.) -->
  <property name="servlet.spec.version"    value="6.0" />
  <property name="servlet.revision"        value="" />
  <property name="jsp.spec.version"        value="3.1" />
  <property name="jsp.revision"            value="" />
  <property name="el.spec.version"         value="5.0" />
  <property name="el.revision"             value="" />
  <property name="websocket.spec.version"  value="2.1" />
  <property name="websocket.revision"      value="" />
  <property name="jaspic.spec.version"     value="3.0" />
  <property name="jaspic.revision"         value="" />
  <property name="annotation.spec.version" value="2.1" />
  <property name="annotation.revision"     value=".1" />

  <!-- Release artifact base names -->
  <property name="final.name"            value="${project}-${version}" />
  <property name="final-src.name"        value="${project}-${version}-src" />

  <!-- Locations to create build artifacts -->
  <property name="tomcat.home"           value="${basedir}"/>
  <property name="tomcat-nb.home"        value="${basedir}/nbproject" />
  <property name="tomcat.output"         value="${basedir}/output"/>
  <property name="tomcat.bnd"            value="${basedir}/res/bnd"/>
  <property name="tomcat.build"          value="${tomcat.output}/build"/>
  <property name="tomcat.classes"        value="${tomcat.output}/classes"/>
  <property name="tomcat.deployer"       value="${tomcat.output}/deployer"/>
  <property name="tomcat.dist"           value="${tomcat.output}/dist"/>
  <property name="tomcat.embed"          value="${tomcat.output}/embed"/>
  <property name="tomcat.embed.sources"  value="${tomcat.output}/embed-src-jars"/>
  <property name="tomcat.graal"          value="${tomcat.output}/graal"/>
  <property name="tomcat.i18n"           value="${tomcat.output}/i18n"/>
  <property name="tomcat.manifests"      value="${tomcat.output}/manifests"/>
  <property name="tomcat.release"        value="${tomcat.output}/release"/>
  <property name="tomcat.release.verify" value="${tomcat.output}/verify" />
  <property name="tomcat.src.jars"       value="${tomcat.output}/src-jars"/>
  <property name="test.classes"          value="${tomcat.output}/testclasses"/>
  <property name="test.run.classes"      value="${tomcat.output}/classes"/>
  <property name="test.temp"             value="${tomcat.output}/test-tmp"/>
  <property name="test.basedir"          value="${tomcat.build}"/>
  <property name="test.reports"          value="${test.basedir}/logs"/>
  <property name="test.apr.loc"          value="${test.basedir}/bin"/>
  <!-- base directory for jdbc-pool -->
  <property name="tomcat.jdbc.dir"       value="${basedir}/modules/jdbc-pool"/>
  <!-- build output directory for jdbc-pool -->
  <property name="tomcat.pool"           value="${tomcat.output}/jdbc-pool"/>
  <!-- build output directory for generated reflectionless code -->
  <property name="tomcat.xreflect"       value="${tomcat.output}/xreflect"/>

  <!-- Jakarta EE 10 platform requires Java 11+ -->
  <!-- Keep in sync with webapps/docs/tomcat-docs.xsl -->
  <property name="compile.release" value="11"/>
  <property name="min.java.version" value="11"/>
  <property name="build.java.version" value="17"/>
  <property name="release.java.version" value="22"/>

  <!-- Check Java Build Version -->
  <fail message="Java version ${build.java.version} or newer is required (${java.version} is installed)">
    <condition>
      <and>
        <not><javaversion atleast="${build.java.version}"/></not>
        <not><istrue value="${skip.build.java.version}"/></not>
      </and>
    </condition>
  </fail>

  <!-- Locations to create the JAR artifacts -->
  <!-- Standard JARs -->
  <property name="bootstrap.jar" value="${tomcat.build}/bin/bootstrap.jar"/>
  <property name="tomcat-juli.jar" value="${tomcat.build}/bin/tomcat-juli.jar"/>

  <property name="annotations-api.jar" value="${tomcat.build}/lib/annotations-api.jar"/>
  <property name="servlet-api.jar" value="${tomcat.build}/lib/servlet-api.jar"/>
  <property name="jsp-api.jar" value="${tomcat.build}/lib/jsp-api.jar"/>
  <property name="el-api.jar" value="${tomcat.build}/lib/el-api.jar"/>
  <property name="websocket-api.jar" value="${tomcat.build}/lib/websocket-api.jar"/>
  <property name="websocket-client-api.jar" value="${tomcat.build}/lib/websocket-client-api.jar"/>
  <property name="jaspic-api.jar" value="${tomcat.build}/lib/jaspic-api.jar"/>
  <property name="tomcat-websocket.jar" value="${tomcat.build}/lib/tomcat-websocket.jar"/>
  <property name="catalina.jar" value="${tomcat.build}/lib/catalina.jar"/>
  <property name="catalina-tribes.jar" value="${tomcat.build}/lib/catalina-tribes.jar"/>
  <property name="catalina-ssi.jar" value="${tomcat.build}/lib/catalina-ssi.jar"/>
  <property name="catalina-ha.jar" value="${tomcat.build}/lib/catalina-ha.jar"/>
  <property name="catalina-ant.jar" value="${tomcat.build}/lib/catalina-ant.jar"/>
  <property name="catalina-storeconfig.jar" value="${tomcat.build}/lib/catalina-storeconfig.jar"/>
  <property name="tomcat-coyote.jar" value="${tomcat.build}/lib/tomcat-coyote.jar"/>
  <property name="tomcat-coyote-ffm.jar" value="${tomcat.build}/lib/tomcat-coyote-ffm.jar"/>
  <property name="tomcat-dbcp.jar" value="${tomcat.build}/lib/tomcat-dbcp.jar"/>
  <property name="tomcat-jni.jar" value="${tomcat.build}/lib/tomcat-jni.jar"/>
  <property name="tomcat-api.jar" value="${tomcat.build}/lib/tomcat-api.jar"/>
  <property name="tomcat-util.jar" value="${tomcat.build}/lib/tomcat-util.jar"/>
  <property name="tomcat-util-scan.jar" value="${tomcat.build}/lib/tomcat-util-scan.jar"/>

  <property name="jasper.jar" value="${tomcat.build}/lib/jasper.jar"/>
  <property name="jasper-el.jar" value="${tomcat.build}/lib/jasper-el.jar"/>

  <!-- Standard Source JARs -->
  <property name="bootstrap-src.jar" value="${tomcat.src.jars}/bootstrap-src.jar"/>
  <property name="tomcat-juli-src.jar" value="${tomcat.src.jars}/tomcat-juli-src.jar"/>

  <property name="annotations-api-src.jar" value="${tomcat.src.jars}/annotations-api-src.jar"/>
  <property name="servlet-api-src.jar" value="${tomcat.src.jars}/servlet-api-src.jar"/>
  <property name="jsp-api-src.jar" value="${tomcat.src.jars}/jsp-api-src.jar"/>
  <property name="el-api-src.jar" value="${tomcat.src.jars}/el-api-src.jar"/>
  <property name="websocket-api-src.jar" value="${tomcat.src.jars}/websocket-api-src.jar"/>
  <property name="websocket-client-api-src.jar" value="${tomcat.src.jars}/websocket-client-api-src.jar"/>
  <property name="jaspic-api-src.jar" value="${tomcat.src.jars}/jaspic-api-src.jar"/>
  <property name="tomcat-websocket-src.jar" value="${tomcat.src.jars}/tomcat-websocket-src.jar"/>
  <property name="catalina-src.jar" value="${tomcat.src.jars}/catalina-src.jar"/>
  <property name="catalina-tribes-src.jar" value="${tomcat.src.jars}/catalina-tribes-src.jar"/>
  <property name="catalina-ssi-src.jar" value="${tomcat.src.jars}/catalina-ssi-src.jar"/>
  <property name="catalina-ha-src.jar" value="${tomcat.src.jars}/catalina-ha-src.jar"/>
  <property name="catalina-ant-src.jar" value="${tomcat.src.jars}/catalina-ant-src.jar"/>
  <property name="catalina-storeconfig-src.jar" value="${tomcat.src.jars}/catalina-storeconfig-src.jar"/>
  <property name="tomcat-jni-src.jar" value="${tomcat.src.jars}/tomcat-jni-src.jar"/>
  <property name="tomcat-coyote-src.jar" value="${tomcat.src.jars}/tomcat-coyote-src.jar"/>
  <property name="tomcat-coyote-ffm-src.jar" value="${tomcat.src.jars}/tomcat-coyote-ffm-src.jar"/>
  <property name="tomcat-dbcp-src.jar" value="${tomcat.src.jars}/tomcat-dbcp-src.jar"/>
  <property name="tomcat-api-src.jar" value="${tomcat.src.jars}/tomcat-api-src.jar"/>
  <property name="tomcat-util-src.jar" value="${tomcat.src.jars}/tomcat-util-src.jar"/>
  <property name="tomcat-util-scan-src.jar" value="${tomcat.src.jars}/tomcat-util-scan-src.jar"/>

  <property name="jasper-src.jar" value="${tomcat.src.jars}/jasper-src.jar"/>
  <property name="jasper-el-src.jar" value="${tomcat.src.jars}/jasper-el-src.jar"/>

  <!-- Embedded JARs & source JARs -->
  <property name="tomcat-embed-core.jar" value="${tomcat.embed}/tomcat-embed-core.jar"/>
  <property name="tomcat-embed-programmatic.jar" value="${tomcat.embed}/tomcat-embed-programmatic.jar"/>
  <property name="tomcat-embed-jasper.jar" value="${tomcat.embed}/tomcat-embed-jasper.jar"/>
  <property name="tomcat-embed-el.jar" value="${tomcat.embed}/tomcat-embed-el.jar"/>
  <property name="tomcat-embed-websocket.jar" value="${tomcat.embed}/tomcat-embed-websocket.jar"/>

  <property name="tomcat-embed-core-sources.jar" value="${tomcat.embed.sources}/tomcat-embed-core-src.jar"/>
  <property name="tomcat-embed-programmatic-sources.jar" value="${tomcat.embed.sources}/tomcat-embed-programmatic-src.jar"/>
  <property name="tomcat-embed-jasper-sources.jar" value="${tomcat.embed.sources}/tomcat-embed-jasper-src.jar"/>
  <property name="tomcat-embed-el-sources.jar" value="${tomcat.embed.sources}/tomcat-embed-el-src.jar"/>
  <property name="tomcat-embed-websocket-sources.jar" value="${tomcat.embed.sources}/tomcat-embed-websocket-src.jar"/>

  <!-- jdbc-pool JARs & source JARs -->
  <property name="tomcat-jdbc.jar" value="${tomcat.pool}/tomcat-jdbc.jar"/>
  <property name="tomcat-jdbc-src.jar" value="${tomcat.pool}/tomcat-jdbc-src.jar"/>

  <!-- Tests To Run -->
  <property name="test.name" value="**/Test*.java"/>
  <property name="test.formatter" value="-Dorg.apache.juli.formatter=java.util.logging.SimpleFormatter"/>
  <property name="test.relaxTiming" value="false"/>

  <!-- Code coverage settings -->
  <property name="coverage.out" value="${tomcat.output}/coverage"/>
  <property name="coverage.datafile" value="${coverage.out}/jacoco.exec"/>

  <!-- SpotBugs settings -->
  <property name="spotbugs.out" value="${tomcat.output}/spotbugs"/>
  <property name="spotbugs.report.format" value="html"/>
  <property name="spotbugs.report.level" value="low"/>

  <!-- Workaround against http://bugs.sun.com/view_bug.do?bug_id=6202721 -->
  <available file="/dev/urandom" property="test.jvmarg.egd" value="-Djava.security.egd=file:/dev/./urandom"/>
  <!-- JREs may fail to start with an empty argument so provide a dummy      -->
  <!-- value here for those cases, such as Windows, where no value will be   -->
  <!-- set above.                                                            -->
  <property name="test.jvmarg.egd" value="-Dignore" />

  <!-- Location of OpenSSL binary (file name, not directory) -->
  <!-- The OpenSSL tests cases be disabled by specifying an invalid path here -->
  <property name="test.openssl.path" value="" />

  <!-- Include .gitignore in src distributions. -->
  <!-- .git and .gitignore are in defaultexcludes since Ant 1.8.2 -->
  <defaultexcludes add="**/.git" />
  <defaultexcludes add="**/.git/**" />
  <defaultexcludes remove="**/.gitignore" />
  <!--<defaultexcludes echo="true" />-->

  <!-- Classpaths -->
  <path id="compile.classpath">
    <pathelement location="${bnd.jar}"/>
    <pathelement location="${jdt.jar}"/>
    <pathelement location="${jaxrpc-lib.jar}"/>
    <pathelement location="${wsdl4j-lib.jar}"/>
    <pathelement location="${migration-lib.jar}"/>
  </path>

  <path id="tomcat.classpath">
    <pathelement path="${test.run.classes}"/>
  </path>

  <path id="tomcat.test.classpath">
    <pathelement location="${test.basedir}/webapps/examples/WEB-INF/classes"/>
    <pathelement location="${test.classes}"/>
    <pathelement location="${tomcat.i18n}"/>
    <pathelement location="${junit.jar}"/>
    <pathelement location="${hamcrest.jar}"/>
    <pathelement location="${easymock.jar}"/>
    <pathelement location="${objenesis.jar}"/>
    <pathelement location="${bytebuddy.jar}"/>
    <pathelement location="${unboundid.jar}"/>
    <pathelement location="${derby.jar}"/>
    <pathelement location="${derby-shared.jar}"/>
    <pathelement location="${derby-tools.jar}"/>
    <path refid="compile.classpath" />
    <path refid="tomcat.classpath" />
  </path>

  <!-- Classpath filter set -->
  <filterset id="classpath.filters">
    <filter token="JAXRPC_JAR" value="${jaxrpc-lib.jar}"/>
    <filter token="WSDL4J_JAR" value="${wsdl4j-lib.jar}"/>
    <filter token="ANT_JAR" value="${ant.home}/lib/ant.jar"/>
    <filter token="JDT_JAR" value="${jdt.jar}"/>
    <filter token="EASYMOCK_JAR" value="${easymock.jar}"/>
    <filter token="HAMCREST_JAR" value="${hamcrest.jar}"/>
    <filter token="OBJENESIS_JAR" value="${objenesis.jar}"/>
    <filter token="BYTEBUDDY_JAR" value="${bytebuddy.jar}"/>
    <filter token="BND_JAR" value="${bnd.jar}"/>
    <filter token="MIGRATION_JAR" value="${migration-lib.jar}"/>
    <filter token="UNBOUNDID_JAR" value="${unboundid.jar}"/>
    <filter token="JUNIT_JAR" value="${junit.jar}"/>
    <filter token="OUTPUT_DIR" value="${tomcat.output}"/>
  </filterset>

  <!-- Version info filter set -->
  <tstamp>
    <format property="year" pattern="yyyy" locale="en" timezone="UTC"/>
    <format property="today" pattern="MMM d yyyy" locale="en" timezone="UTC"/>
    <format property="today-iso-8601" pattern="yyyy-MM-dd" locale="en" timezone="UTC"/>
    <format property="tstamp" pattern="HH:mm:ss" locale="en" timezone="UTC"/>
    <format property="tstamp.file" pattern="yyyy-MM-dd HH:mm:ss" timezone="UTC"/>
    <format property="tstamp.iso.release" pattern="yyyy-MM-dd'T'HH:mm:ssX" timezone="UTC"/>
  </tstamp>
  <filterset id="version.filters">
    <filter token="YEAR" value="${year}"/>
    <filter token="VERSION" value="${version}"/>
    <filter token="VERSION_NUMBER" value="${version.number}"/>
    <filter token="VERSION_MAJOR" value="${version.major}"/>
    <filter token="VERSION_MAJOR_MINOR" value="${version.major.minor}"/>
    <filter token="VERSION_BUILT" value="${today} ${tstamp} UTC"/>
    <filter token="VERSION_BUILT_ISO" value="${today-iso-8601}"/>
    <filter token="JDT_VERSION" value="${jdt.version}"/>
    <filter token="GIT_BRANCH" value="${git.branch}"/>
    <filter token="MIN_JAVA_VERSION" value="${min.java.version}"/>
    <filter token="BUILD_JAVA_VERSION" value="${build.java.version}"/>
    <filter token="ANT_VERSION_REQUIRED" value="${ant.version.required}"/>
    <filter token="SERVLET_SPEC_VERSION" value="${servlet.spec.version}"/>
    <filter token="JSP_SPEC_VERSION" value="${jsp.spec.version}"/>
    <filter token="EL_SPEC_VERSION" value="${el.spec.version}"/>
    <filter token="WEBSOCKET_SPEC_VERSION" value="${websocket.spec.version}"/>
    <filter token="JASPIC_SPEC_VERSION" value="${jaspic.spec.version}"/>
  </filterset>

  <!-- Files to change line endings for depending on target platform -->
  <patternset id="text.files" >
    <include name="**/INSTALLLICENSE"/>
    <include name="**/KEYS"/>
    <include name="**/LICENSE"/>
    <include name="**/NOTICE"/>
    <include name="**/RELEASE-NOTES"/>
    <include name="**/jakarta.el.ExpressionFactory"/>
    <include name="**/jakarta.servlet.ServletContainerInitializer"/>
    <include name="**/jakarta.websocket.ContainerProvider"/>
    <include name="**/jakarta.websocket.server.ServerEndpointConfig$Configurator"/>
    <include name="**/.gitignore"/>
    <include name="**/*.bnd"/>
    <include name="**/*.classpath"/>
    <include name="**/*.conf"/>
    <include name="**/*.css"/>
    <include name="**/*.dtd"/>
    <include name="**/*.editorconfig"/>
    <include name="**/*.h"/>
    <include name="**/*.header"/>
    <include name="**/*.htm"/>
    <include name="**/*.html"/>
    <include name="**/*.iml"/>
    <include name="**/*.ini"/>
    <include name="**/*.java"/>
    <include name="**/*.jj"/>
    <include name="**/*.jjt"/>
    <include name="**/*.json"/>
    <include name="**/*.jsp"/>
    <include name="**/*.jspf"/>
    <include name="**/*.jspx"/>
    <include name="**/*.launch"/>
    <include name="**/*.license"/>
    <include name="**/*.manifest"/>
    <include name="**/*.md"/>
    <include name="**/*.mdl"/>
    <include name="**/*.MF"/>
    <include name="**/*.notice"/>
    <include name="**/*.nsi"/>
    <include name="**/*.pem"/>
    <include name="**/*.pl"/>
    <include name="**/*.plantuml"/>
    <include name="**/*.policy"/>
    <include name="**/*.pom"/>
    <include name="**/*.project"/>
    <include name="**/*.properties"/>
    <include name="**/*.properties.default"/>
    <include name="**/*.properties.release"/>
    <include name="**/*.shtml"/>
    <include name="**/*.svg"/>
    <include name="**/*.tag"/>
    <include name="**/*.tagf"/>
    <include name="**/*.tagx"/>
    <include name="**/*.tasks"/>
    <include name="**/*.tld"/>
    <include name="**/*.txt"/>
    <include name="**/*.xhtml"/>
    <include name="**/*.xml"/>
    <include name="**/*.xsd"/>
    <include name="**/*.xsl"/>
    <include name="**/*.xslt"/>
    <include name="**/*.yaml"/>
    <include name="**/*.yml"/>
    <include name="**/Dockerfile"/>
    <!-- Exclude files that use 16-bit encodings. -->
    <!-- This prevents fixcrlf corrupting them during a release -->
    <exclude name="**/bom-none-prolog-utf16?e.jspx"/>
    <exclude name="**/bom-utf16?e-prolog-*.jsp*"/>
  </patternset>


  <!-- ========= Pattern sets used to control content of JAR files ========= -->
  <!-- Pattern sets for jar files in standard distributions -->
  <patternset id="files.annotations-api">
    <include name="jakarta/annotation/**" />
  </patternset>

  <patternset id="files.servlet-api">
    <include name="jakarta/servlet/*" />
    <include name="jakarta/servlet/annotation/**" />
    <include name="jakarta/servlet/descriptor/**" />
    <include name="jakarta/servlet/http/**" />
    <include name="jakarta/servlet/resources/**" />
    <exclude name="jakarta/servlet/jsp"/>
  </patternset>

  <patternset id="files.jsp-api">
    <include name="jakarta/servlet/jsp/**" />
  </patternset>

  <patternset id="files.el-api">
    <include name="jakarta/el/**" />
  </patternset>

  <patternset id="files.websocket-api">
    <include name="jakarta/websocket/server/*" />
  </patternset>

  <patternset id="files.websocket-client-api">
    <include name="jakarta/websocket/*" />
  </patternset>

  <patternset id="files.jaspic-api">
    <include name="jakarta/security/auth/message/**" />
  </patternset>

  <patternset id="files.tomcat-websocket">
    <include name="org/apache/tomcat/websocket/**" />
  </patternset>

  <!-- This duplicates some classes in files.catalina                        -->
  <!-- Duplicating a few classes in bootstrap.jar is simpler than excluding  -->
  <!-- them from files.catalina and having to manually add them to           -->
  <!-- files.tomcat-embed-core because of an include/exclude conflict        -->
  <!-- between files.catalina and files.bootstrap.                           -->
  <patternset id="files.bootstrap">
    <include name="org/apache/catalina/startup/Bootstrap.*" />
    <include name="org/apache/catalina/startup/catalina.properties" />
    <include name="org/apache/catalina/startup/CatalinaProperties.*" />
    <include name="org/apache/catalina/startup/ClassLoaderFactory.*" />
    <include name="org/apache/catalina/startup/ClassLoaderFactory$*.*" />
    <include name="org/apache/catalina/startup/Constants.*" />
    <include name="org/apache/catalina/startup/SafeForkJoinWorkerThreadFactory.*" />
    <include name="org/apache/catalina/startup/SafeForkJoinWorkerThreadFactory$*.*" />
    <include name="org/apache/catalina/startup/Tool.*" />
    <include name="org/apache/catalina/security/SecurityClassLoad.*" />
    <include name="org/apache/catalina/webresources/war/**" />
    <include name="org/apache/tomcat/util/buf/UriUtil.*" />
  </patternset>

  <patternset id="files.tomcat-juli">
    <include name="org/apache/juli/**" />
  </patternset>

  <patternset id="files.tomcat-api">
    <include name="org/apache/tomcat/*" />
    <exclude name="org/apache/tomcat/buildutil" />
    <exclude name="org/apache/tomcat/dbcp" />
    <exclude name="org/apache/tomcat/jni" />
    <exclude name="org/apache/tomcat/util" />
    <exclude name="org/apache/tomcat/websocket" />
  </patternset>

  <patternset id="files.tomcat-util">
    <include name="org/apache/tomcat/util/buf/**" />
    <include name="org/apache/tomcat/util/codec/**" />
    <include name="org/apache/tomcat/util/collections/**" />
    <include name="org/apache/tomcat/util/compat/**" />
    <include name="org/apache/tomcat/util/file/**" />
    <include name="org/apache/tomcat/util/res/**" />
    <include name="org/apache/tomcat/util/security/**" />
    <include name="org/apache/tomcat/util/threads/**" />
    <include name="org/apache/tomcat/util/json/**" />
    <include name="org/apache/tomcat/util/*" />
    <exclude name="org/apache/tomcat/util/bcel" />
    <exclude name="org/apache/tomcat/util/descriptor" />
    <exclude name="org/apache/tomcat/util/digester" />
    <exclude name="org/apache/tomcat/util/http" />
    <exclude name="org/apache/tomcat/util/log" />
    <exclude name="org/apache/tomcat/util/modeler" />
    <exclude name="org/apache/tomcat/util/net" />
    <exclude name="org/apache/tomcat/util/openssl"/>
    <exclude name="org/apache/tomcat/util/scan" />
  </patternset>

  <patternset id="files.tomcat-util-scan">
    <include name="org/apache/tomcat/util/descriptor/**" />
    <include name="org/apache/tomcat/util/digester/**" />
    <include name="org/apache/tomcat/util/scan/**" />
  </patternset>

  <patternset id="files.catalina">
    <include name="org/apache/catalina/**" />
    <include name="org/apache/naming/**" />
    <!-- Modules -->
    <exclude name="org/apache/catalina/ant/**" />
    <exclude name="org/apache/catalina/ha/**" />
    <exclude name="org/apache/catalina/tribes/**" />
    <exclude name="org/apache/catalina/storeconfig/**" />
    <exclude name="org/apache/catalina/ssi/**" />
  </patternset>

  <patternset id="files.tomcat-embed-programmatic">
    <patternset refid="files.jaspic-api" />
    <patternset refid="files.tomcat-juli" />

    <!-- Servlet -->
    <include name="jakarta/servlet/**" />
    <include name="jakarta/servlet/annotation/**" />
    <include name="jakarta/servlet/http/**" />
    <exclude name="jakarta/servlet/descriptor/**" />
    <exclude name="jakarta/servlet/jsp/**"/>
    <exclude name="jakarta/servlet/resources/**" />

    <!-- AprLifecycleListener is configured by default -->
    <include name="**/AprLifecycleListener.*"/>
    <include name="**/AprStatus.*"/>

    <!-- Remove dynamic mbean descriptors -->
    <exclude name="**/mbeans-descriptors.xml"/>
    <exclude name="**/mbeans-descriptors.dtd"/>
    <!-- No JMX Support - But we can't remove the classes -->
    <include name="org/apache/tomcat/util/modeler/LocalStrings.properties" />
    <include name="org/apache/tomcat/util/modeler/AttributeInfo*" />
    <include name="org/apache/tomcat/util/modeler/BaseModelMBean*" />
    <include name="org/apache/tomcat/util/modeler/FeatureInfo*" />
    <include name="org/apache/tomcat/util/modeler/ManagedBean*" />
    <include name="org/apache/tomcat/util/modeler/NoDescriptorRegistry*" />
    <include name="org/apache/tomcat/util/modeler/NotificationInfo*" />
    <include name="org/apache/tomcat/util/modeler/Registry*" />
    <include name="org/apache/tomcat/util/modeler/RegistryMBean*" />
    <include name="org/apache/tomcat/util/modeler/Util*" />
    <include name="org/apache/tomcat/util/modeler/modules/ModelerSource*" />

    <!-- Apache Tomcat Core Code -->
    <include name="org/apache/catalina/*"/>
    <include name="org/apache/catalina/authenticator/**"/>
    <include name="org/apache/catalina/connector/**"/>
    <include name="org/apache/catalina/core/**"/>
    <include name="org/apache/catalina/deploy/**"/>
    <include name="org/apache/catalina/filters/**"/>
    <include name="org/apache/catalina/loader/**"/>
    <include name="org/apache/catalina/mapper/**"/>
    <include name="org/apache/catalina/mbeans/**"/>
    <include name="org/apache/catalina/realm/**"/>
    <include name="org/apache/catalina/security/**"/>
    <include name="org/apache/catalina/session/**"/>
    <include name="org/apache/catalina/startup/**"/>
    <include name="org/apache/catalina/util/**"/>
    <include name="org/apache/catalina/valves/*"/>
    <include name="org/apache/catalina/webresources/**"/>
    <include name="org/apache/coyote/**" />
    <include name="org/apache/naming/**" />
    <include name="org/apache/tomcat/*" />
    <include name="org/apache/tomcat/util/*" />
    <include name="org/apache/tomcat/util/bcel/**" />
    <include name="org/apache/tomcat/util/buf/**" />
    <include name="org/apache/tomcat/util/codec/**" />
    <include name="org/apache/tomcat/util/collections/**" />
    <include name="org/apache/tomcat/util/compat/**" />
    <include name="org/apache/tomcat/util/descriptor/**" />
    <include name="org/apache/tomcat/util/file/**" />
    <include name="org/apache/tomcat/util/http/**" />
    <include name="org/apache/tomcat/util/json/**" />
    <include name="org/apache/tomcat/util/log/**" />
    <include name="org/apache/tomcat/util/net/**" />
    <include name="org/apache/tomcat/util/res/**" />
    <include name="org/apache/tomcat/util/security/**" />
    <include name="org/apache/tomcat/util/threads/**" />

    <!-- Some of the core code depends on the jar scanner -->
    <include name="org/apache/tomcat/util/scan/StandardJarScan*" />
    <include name="org/apache/tomcat/util/scan/LocalStrings.properties" />

    <!-- Minimize JNI to what doesn't throw an error -->
    <include name="org/apache/tomcat/jni/Library.class" />
    <include name="org/apache/tomcat/jni/LibraryNotFoundError*" />
    <exclude name="org/apache/tomcat/jni" />

    <!-- Remove connectors that are not default -->
    <exclude name="**/AbstractAjpProtocol.class"/>
    <exclude name="**/Ajp*.class"/>
    <exclude name="**/Http11Nio2*.class"/>
    <exclude name="**/JniLifecycleListener.class"/>
    <exclude name="org/apache/tomcat/**/*Nio2*.class"/>

    <!-- Minimize bundles to the default set -->
    <exclude name="org/apache/**/LocalStrings_*.properties"/>

    <!-- Remove digester support -->
    <exclude name="org/apache/catalina/**/*Rule.class" />
    <exclude name="org/apache/catalina/**/*RuleSet*.class" />
    <exclude name="org/apache/tomcat/**/*RuleSet*.class" />

    <!-- Remove various Apache Tomcat modules not used by default in an embedded setting -->
    <exclude name="org/apache/catalina/ant/**" />
    <exclude name="org/apache/catalina/ha/**" />
    <exclude name="org/apache/catalina/manager/**" />
    <exclude name="org/apache/catalina/ssi/**" />
    <exclude name="org/apache/catalina/storeconfig/**" />
    <exclude name="org/apache/catalina/tribes/**" />
    <exclude name="org/apache/catalina/valves/rewrite/**" />
    <exclude name="org/apache/tomcat/buildutil" />
    <exclude name="org/apache/tomcat/dbcp" />

    <!-- Remove authenticator classes -->
    <exclude name="org/apache/catalina/authenticator/BasicAuthenticator*" />
    <exclude name="org/apache/catalina/authenticator/DigestAuthenticator*" />
    <exclude name="org/apache/catalina/authenticator/FormAuthenticator*" />
    <exclude name="org/apache/catalina/authenticator/SingleSignOnE*" />
    <exclude name="org/apache/catalina/authenticator/SingleSignOnL*" />
    <exclude name="org/apache/catalina/authenticator/SingleSignOnS*" />
    <exclude name="org/apache/catalina/authenticator/Spnego*" />
    <exclude name="org/apache/catalina/authenticator/SSLAuthenticator*" />
    <exclude name="org/apache/catalina/authenticator/jaspcic/Simple*" />

    <!-- Remove optional filter classes -->
    <exclude name="org/apache/catalina/filters/**" />

    <!-- Remove Realm classes -->
    <exclude name="org/apache/catalina/realm/AuthenticatedUserRealm.class" />
    <exclude name="org/apache/catalina/realm/CombinedRealm.class" />
    <exclude name="org/apache/catalina/realm/DataSourceRealm.class" />
    <exclude name="org/apache/catalina/realm/JAASCallbackHandler.class" />
    <exclude name="org/apache/catalina/realm/JAASMemoryLoginModule.class" />
    <exclude name="org/apache/catalina/realm/JAASRealm.class" />
    <exclude name="org/apache/catalina/realm/JNDIRealm$User.class" />
    <exclude name="org/apache/catalina/realm/JNDIRealm.class" />
    <exclude name="org/apache/catalina/realm/LockOutRealm*" />
    <exclude name="org/apache/catalina/realm/MemoryRealm.class" />
    <exclude name="org/apache/catalina/realm/NestedCredentialHandler.class" />
    <exclude name="org/apache/catalina/realm/UserDatabaseRealm.class" />

    <!-- Remove optional servlets -->
    <exclude name="org/apache/catalina/servlets/**" />

    <!-- Remove all but the standard session management -->
    <exclude name="org/apache/catalina/session/JDBC*" />
    <exclude name="org/apache/catalina/session/File*" />
    <exclude name="org/apache/catalina/session/Persistent*" />
    <exclude name="org/apache/catalina/session/StoreBase*" />

    <!-- Remove users -->
    <exclude name="org/apache/catalina/users/**" />

    <!-- Remove optional valves -->
    <exclude name="org/apache/catalina/valves/Crawler*" />
    <exclude name="org/apache/catalina/valves/ExtendedAccessLogValve*" />
    <exclude name="org/apache/catalina/valves/ExtendedAccessLogValve*" />
    <exclude name="org/apache/catalina/valves/HealthCheckValve*" />
    <exclude name="org/apache/catalina/valves/JDBCAccessLogValve*" />
    <exclude name="org/apache/catalina/valves/LoadBalancerDrainingValve*" />
    <exclude name="org/apache/catalina/valves/PersistentValve*" />

    <!-- Remove most JNDI stuff -->
    <exclude name="org/apache/naming/EjbRef*" />
    <exclude name="org/apache/naming/factory/BeanFactory*" />
    <exclude name="org/apache/naming/factory/DataSourceLinkFactory*" />
    <exclude name="org/apache/naming/factory/EjbFactory*" />
    <exclude name="org/apache/naming/factory/LookupFactory*" />
    <exclude name="org/apache/naming/factory/MailSessionFactory*" />
    <exclude name="org/apache/naming/factory/OpenEjbFactory*" />
    <exclude name="org/apache/naming/factory/ResourceEnvFactory*" />
    <exclude name="org/apache/naming/factory/ResourceFactory*" />
    <exclude name="org/apache/naming/factory/ResourceLinkFactory*" />
    <exclude name="org/apache/naming/factory/SendMailFactory*" />
    <exclude name="org/apache/naming/factory/TransactionFactory*" />
    <exclude name="org/apache/naming/factory/webservices/*" />
    <exclude name="org/apache/naming/LookupRef*" />
    <exclude name="org/apache/naming/NameParserImpl*" />
    <exclude name="org/apache/naming/NamingContextBindingsEnumeration*" />
    <exclude name="org/apache/naming/NamingContext*" />
    <exclude name="org/apache/naming/NamingContextEnumeration*" />
    <exclude name="org/apache/naming/NamingEntry*" />
    <exclude name="org/apache/naming/ResourceEnvRef*" />
    <exclude name="org/apache/naming/ResourceLinkRef*" />
    <exclude name="org/apache/naming/ResourceRef*" />
    <exclude name="org/apache/naming/SelectorContext*" />
    <exclude name="org/apache/naming/ServiceRef*" />
    <exclude name="org/apache/naming/TransactionRef*" />

    <!-- remove BCEL support -->
    <exclude name="org/apache/tomcat/util/bcel/**" />

    <!-- remove web descriptor elements -->
    <exclude name="org/apache/tomcat/util/descriptor/DigesterFactory*" />
    <exclude name="org/apache/tomcat/util/descriptor/InputSourceUtil*" />
    <exclude name="org/apache/tomcat/util/descriptor/LocalResolver*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/AbsoluteOrderingRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/CallMethodMultiRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/CallParamMultiRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/ContextHandler*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/ContextResourceLink*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/ContextTransaction*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/FragmentJarScannerCallback*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/IgnoreAnnotationsRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/InjectionTarget*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/JspConfigDescriptorImpl*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/JspPropertyGroup*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/JspPropertyGroupDescriptorImpl*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/LifecycleCallbackRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/MappedNameRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/MultipartDef*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/NameRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/RelativeOrderingRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/SecurityCollection*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/SecurityRoleRef*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/ServiceQnameRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/ServletDef*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/ServletDefCreateRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/SessionConfig*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/SetAuthConstraintRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/SetDenyUncoveredHttpMethodsRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/SetDistributableRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/SetJspConfig*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/SetLoginConfig*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/SetOverrideRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/SetPublicIdRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/SetSessionConfig*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/SoapHeaderRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/TaglibDescriptorImpl*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/TaglibLocationRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/VersionRule*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/WebXml*" />
    <exclude name="org/apache/tomcat/util/descriptor/web/WebXmlParser*" />
    <exclude name="org/apache/tomcat/util/descriptor/XmlErrorHandler*" />
    <exclude name="org/apache/tomcat/util/descriptor/XmlIdentifiers*" />

    <!-- remove taglibrary support -->
    <exclude name="org/apache/tomcat/util/descriptor/tagplugin/**"/>
    <exclude name="org/apache/tomcat/util/descriptor/tld/**"/>

    <!-- Remove Digester Support -->
    <exclude name="org/apache/tomcat/util/digester/**"/>

    <!-- TODO - For now, remove SSL until we have an example -->
    <exclude name="org/apache/tomcat/util/net/jsse/**"/>
    <exclude name="org/apache/tomcat/util/net/openssl/**"/>

    <!-- Remove without-reflection code generator -->
    <exclude name="org/apache/tomcat/util/xreflection/**" />

    <!-- Remove DefaultServlet -->
    <exclude name="org/apache/catalina/servlets/DefaultServlet*.*" />
  </patternset>

  <patternset id="files.catalina-tribes">
    <include name="org/apache/catalina/tribes/**" />
  </patternset>

  <patternset id="files.catalina-ssi">
    <include name="org/apache/catalina/ssi/**" />
  </patternset>

  <patternset id="files.catalina-ha">
    <include name="org/apache/catalina/ha/**" />
  </patternset>

  <patternset id="files.catalina-ant">
    <include name="org/apache/catalina/ant/**" />
  </patternset>

  <patternset id="files.catalina-storeconfig">
    <include name="org/apache/catalina/storeconfig/**" />
  </patternset>

  <patternset id="files.tomcat-jni">
    <include name="org/apache/tomcat/jni/**" />
  </patternset>

  <patternset id="files.tomcat-coyote">
    <include name="org/apache/coyote/**" />
    <!-- Remaining tomcat-util packages -->
    <include name="org/apache/tomcat/util/bcel/**" />
    <include name="org/apache/tomcat/util/http/**" />
    <include name="org/apache/tomcat/util/log/**" />
    <include name="org/apache/tomcat/util/modeler/**" />
    <include name="org/apache/tomcat/util/net/**" />
    <exclude name="org/apache/tomcat/util/net/openssl/panama/**"/>
  </patternset>

  <patternset id="files.tomcat-coyote-ffm">
    <include name="org/apache/tomcat/util/net/openssl/panama/**"/>
    <include name="org/apache/tomcat/util/openssl/**"/>
  </patternset>

  <patternset id="files.jasper">
    <include name="org/apache/jasper/**" />
  </patternset>

  <patternset id="files.jasper-el">
    <include name="org/apache/el/**" />
  </patternset>

  <patternset id="files.tomcat-dbcp">
    <include name="org/apache/tomcat/dbcp/**"/>
  </patternset>

  <!-- Pattern sets for embedded JARs -->
  <!-- Every standard pattern set above should be included in an embedded JAR -->
  <patternset id="files.tomcat-embed-core" >
    <patternset refid="files.catalina" />
    <patternset refid="files.servlet-api" />
    <patternset refid="files.jaspic-api" />
    <patternset refid="files.tomcat-api" />
    <patternset refid="files.tomcat-juli" />
    <!-- These pattern sets conflict so include files directly
      <patternset refid="files.tomcat-coyote" />
      <patternset refid="files.tomcat-util" />
      <patternset refid="files.tomcat-util-scan" />
    -->
    <include name="org/apache/coyote/**" />
    <include name="org/apache/tomcat/jni/**" />
    <include name="org/apache/tomcat/util/**" />
    <exclude name="org/apache/tomcat/util/descriptor/tld/**" />
  </patternset>

  <patternset id="files.tomcat-embed-jasper" >
    <patternset refid="files.jasper" />
    <patternset refid="files.jsp-api" />
    <include name="org/apache/tomcat/util/descriptor/tld/**" />
  </patternset>

  <patternset id="files.tomcat-embed-el" >
    <patternset refid="files.el-api" />
    <patternset refid="files.jasper-el" />
  </patternset>

  <patternset id="files.tomcat-embed-websocket" >
    <patternset refid="files.websocket-api" />
    <patternset refid="files.websocket-client-api" />
    <patternset refid="files.tomcat-websocket" />
  </patternset>

  <!-- Pattern sets not included in embedded -->
    <!-- Cluster support not included in embedded -->
    <!--<patternset refid="files.catalina-tribes" />-->
    <!--<patternset refid="files.catalina-ha" />-->
    <!-- Ant tasks not included in embedded -->
    <!--<patternset refid="files.catalina-ant" />-->
    <!-- Annotations API is a separate dependency to avoid JRE 9 issues -->
    <!-- See BZ 61439 -->
    <!--<patternset refid="files.annotations-api" />-->

  <!-- =========================== Build targets =========================== -->

  <!-- Output the merged properties for the current Ant environment -->
  <target name="echoproperties">
    <echoproperties/>
  </target>

  <target name="build-prepare">

    <!-- Required so we can compile -->
    <mkdir dir="${tomcat.classes}"/>

    <!-- Ensure these directories are removed every time we re-build -->
    <delete dir="${tomcat.build}/temp" />
    <delete dir="${tomcat.build}/work" />

    <!-- Minimum dirs needed for a working Tomcat instance -->
    <mkdir dir="${tomcat.build}"/>
    <mkdir dir="${tomcat.build}/bin"/>
    <mkdir dir="${tomcat.build}/conf"/>
    <mkdir dir="${tomcat.build}/lib"/>
    <mkdir dir="${tomcat.build}/logs"/>
    <mkdir dir="${tomcat.build}/temp"/>
    <mkdir dir="${tomcat.build}/webapps"/>
    <mkdir dir="${tomcat.build}/webapps-javaee"/>

    <!-- Property that determines if manifests need updating -->
    <uptodate property="manifests.uptodate"
        targetfile="${tomcat.manifests}/default.manifest" >
      <srcfiles file="${user.home}/build.properties" />
      <srcfiles file="${basedir}/build.properties" />
      <srcfiles file="${basedir}/build.properties.default" />
      <srcfiles file="${basedir}/build.xml" />
      <srcfiles dir="${tomcat.home}/res/META-INF" >
        <include name="*.manifest" />
        <include name="*.license" />
        <include name="*.notice" />
      </srcfiles>
    </uptodate>

  </target>

  <target name="validate" if="${execute.validate}"
    depends="build-prepare,compile-prepare,download-validate"
    description="Uses Checkstyle tool to perform style check for the source code">
    <!-- Required so we can cache checkstyle results -->
    <mkdir dir="${tomcat.output}/res/checkstyle"/>
    <available property="checkstyletask.properties" resource="checkstyletask.properties"
       classpath="${checkstyle.jar}" value="checkstyletask.properties"/>
    <available property="checkstyletask.properties" resource="com/puppycrawl/tools/checkstyle/ant/checkstyle-ant-task.properties"
       classpath="${checkstyle.jar}" value="com/puppycrawl/tools/checkstyle/ant/checkstyle-ant-task.properties"/>

    <taskdef resource="${checkstyletask.properties}"
             classpath="${checkstyle.jar}" />
    <!-- Main checks -->
    <checkstyle config="${basedir}/res/checkstyle/checkstyle.xml">
      <fileset dir="." >
        <patternset refid="text.files" />
        <include name="**/*.bat"/>
        <include name="**/*.sh"/>
        <exclude name="bin/setenv.*"/>
        <exclude name=".*/**"/>
        <exclude name="nbproject/**"/>
        <exclude name="output/**"/>
        <exclude name="modules/**"/>
        <exclude name="test/webapp-fragments/WEB-INF/classes/*.txt"/>
        <exclude name="test/webapp/bug49nnn/*.txt"/>
        <exclude name="test/webapp/bug53257/**/*.txt"/>
        <exclude name="test/webapp/bug66609/*.txt"/>
        <exclude name="test/webresources/**/*.txt"/>
        <exclude name="**/*.mdl"/>
        <exclude name="**/*.pem"/>
        <exclude name="**/*.svg"/>
        <exclude name="**/*_2.xml"/>
        <exclude name="res/checkstyle/header-al2.txt"/>
        <!-- Exclude auto-generated files -->
        <exclude name="java/org/apache/el/parser/ELParser*.java" />
        <exclude name="java/org/apache/el/parser/Node.java" />
        <exclude name="java/org/apache/tomcat/util/json/JSONParser*.java" />
        <exclude name="java/org/apache/tomcat/util/openssl/*.java" />
        <exclude name="**/*.jj" />
        <exclude name="java/org/apache/**/JJT*ParserState.java" />
        <exclude name="java/org/apache/**/ParseException.java" />
        <exclude name="java/org/apache/**/JavaCharStream.java" />
        <exclude name="java/org/apache/**/SimpleCharStream.java" />
        <exclude name="java/org/apache/**/Token.java" />
        <exclude name="java/org/apache/**/TokenMgrError.java" />
        <!-- Exclude developer specific local files -->
        <exclude name="build.properties" />
        <exclude name="res/maven/mvn.properties" />
      </fileset>
      <fileset dir="modules/jdbc-pool" >
        <exclude name=".*/**"/>
        <exclude name="**/MANIFEST.MF"/>
        <patternset refid="text.files" />
        <!-- Exclude developer specific local files -->
        <exclude name="build.properties" />
      </fileset>
    </checkstyle>
    <!-- jakarta package checks -->
    <checkstyle config="${basedir}/res/checkstyle/jakarta-checkstyle.xml">
      <fileset dir="java/jakarta" >
        <include name="**/*.java"/>
      </fileset>
    </checkstyle>
    <!-- org package checks -->
    <checkstyle config="${basedir}/res/checkstyle/org-checkstyle.xml">
      <fileset dir="java/org" >
        <include name="**/*.java"/>
      </fileset>
    </checkstyle>
    <!-- Tests checks -->
    <checkstyle config="${basedir}/res/checkstyle/test-checkstyle.xml">
      <fileset dir="test" >
        <patternset refid="text.files" />
        <exclude name=".*/**"/>
        <exclude name="**/*.pem"/>
        <!-- Exclude simple test files -->
        <exclude name="webapp/bug49nnn/bug49464*"/>
        <exclude name="webapp/bug53257/**/*.txt"/>
        <exclude name="webapp/bug66609/*.txt"/>
        <exclude name="webapp-fragments/WEB-INF/classes/*.txt"/>
        <exclude name="webresources/**"/>
        <!-- Exclude test files with unusual encodings -->
        <exclude name="webapp/jsp/encoding/**"/>
      </fileset>
    </checkstyle>
  </target>

  <target name="validate-eoln" depends="build-prepare,compile-prepare"
    description="Validate that the source files have correct line ends">
    <!-- Compile the CheckEol class only. Note that the class depends on
    Ant only. There is no need to download additional dependencies nor
    add them to the class path. The rest should be the same as in "compile"
    target.-->
    <javac srcdir="java" destdir="${tomcat.classes}"
           debug="${compile.debug}"
           deprecation="${compile.deprecation}"
           release="${compile.release}"
           encoding="ISO-8859-1"
           includeAntRuntime="true" >
      <!-- Uncomment this to show unchecked warnings:
      <compilerarg value="-Xlint:unchecked"/>
      -->
      <include name="org/apache/tomcat/buildutil/CheckEol*" />
    </javac>

    <taskdef name="checkeol"
             classname="org.apache.tomcat.buildutil.CheckEol"
             classpath="${tomcat.classes}" />

    <checkeol mode="LF">
      <fileset dir="." >
        <patternset refid="text.files" />
        <include name="**/*.bat"/>
        <include name="**/*.sh"/>
        <exclude name=".*/**"/>
        <exclude name="nbproject/**"/>
        <exclude name="output/**"/>
        <exclude name="modules/**"/>
        <!-- Exclude these since some svn clients do not seem able to handle
             UTF-16 line-ending conversion -->
        <exclude name="test/webapp/jsp/encoding/bom-utf16*"/>
        <exclude name="test/webapp/jsp/encoding/bom-none-prolog-utf16*"/>
      </fileset>
      <fileset dir="modules/jdbc-pool" >
        <patternset refid="text.files" />
      </fileset>
    </checkeol>
  </target>

  <target name="compile-prepare">
    <!-- Add the builtin catalina.properties -->
    <copy todir="java/org/apache/catalina/startup"
          file="conf/catalina.properties" encoding="ISO-8859-1">
      <filterset refid="version.filters"/>
    </copy>
    <!-- Copy jdbc-pool documentation -->
    <copy tofile="webapps/docs/jdbc-pool.xml"
          file="${tomcat.jdbc.dir}/doc/jdbc-pool.xml" encoding="UTF-8">
      <filterset>
        <filter token="TOMCAT_PROJECT_DEST" value="project.xml"/>
      </filterset>
    </copy>
  </target>

  <target name="compile" depends="download-compile,validate">
    <!-- Compile internal server components -->
    <javac srcdir="java" destdir="${tomcat.classes}"
           debug="${compile.debug}"
           deprecation="${compile.deprecation}"
           release="${compile.release}"
           encoding="ISO-8859-1"
           includeAntRuntime="true" >
      <!-- Uncomment this to show unchecked warnings:
      <compilerarg value="-Xlint:unchecked"/>
      -->
      <classpath refid="compile.classpath" />
      <exclude name="org/apache/tomcat/util/net/openssl/panama/**"/>
      <exclude name="org/apache/tomcat/util/openssl/**"/>
    </javac>
    <!-- Compile internal server components that use FFM -->
    <condition property="has-ffm">
      <javaversion atleast="${release.java.version}" />
    </condition>
    <javac srcdir="java" destdir="${tomcat.classes}"
           debug="${compile.debug}"
           deprecation="${compile.deprecation}"
           release="${release.java.version}"
           encoding="ISO-8859-1"
           includeAntRuntime="true"
           if:set="has-ffm" >
      <!-- Uncomment this to show unchecked warnings:
      <compilerarg value="-Xlint:unchecked"/>
      -->
      <classpath refid="compile.classpath" />
      <include name="org/apache/tomcat/util/net/openssl/panama/**"/>
      <include name="org/apache/tomcat/util/openssl/**"/>
    </javac>
    <!-- Copy static resource files -->
    <copy todir="${tomcat.classes}" encoding="UTF-8">
      <filterset refid="version.filters"/>
      <fileset dir="java">
        <include name="**/*.properties"/>
        <exclude name="**/LocalStrings*.properties"/>
        <exclude name="**/Messages*.properties"/>
        <include name="**/*.dtd"/>
        <include name="**/*.tasks"/>
        <include name="**/*.xsd"/>
        <include name="**/*.xml"/>
      </fileset>
    </copy>

    <!-- Convert the message files from UTF-8 to ASCII. This can be removed
    after upgrading to Java 9+ as the minimum JRE and specifying the encoding
    when loading the ResourceBundles -->
    <native2ascii src="java" dest="${tomcat.classes}" includes="**/LocalStrings.properties" encoding="UTF-8"/>
    <native2ascii src="java" dest="${tomcat.i18n}" includes="**/LocalStrings_*.properties" encoding="UTF-8"/>

    <!-- Ensure consistent line-endings for reproducible builds -->
    <fixcrlf srcdir="${tomcat.classes}" eol="lf"
        encoding="UTF-8" fixlast="false" >
      <patternset refid="text.files" />
    </fixcrlf>
    <fixcrlf srcdir="${tomcat.i18n}" eol="lf"
        encoding="UTF-8" fixlast="false" >
      <patternset refid="text.files" />
    </fixcrlf>
  </target>

  <target name="build-manifests" unless="manifests.uptodate"
          depends="build-prepare">
    <!-- Filtering tokens for JAR manifests-->
    <filter token="source.jdk" value="${compile.release}"/>
    <filter token="target.jdk" value="${compile.release}"/>
    <filter token="servlet.spec.version" value="${servlet.spec.version}"/>
    <filter token="servlet.revision" value="${servlet.revision}"/>
    <filter token="jsp.spec.version" value="${jsp.spec.version}"/>
    <filter token="jsp.revision" value="${jsp.revision}"/>
    <filter token="el.spec.version" value="${el.spec.version}"/>
    <filter token="el.revision" value="${el.revision}"/>
    <filter token="websocket.spec.version" value="${websocket.spec.version}"/>
    <filter token="websocket.revision" value="${websocket.revision}"/>
    <filter token="jaspic.spec.version" value="${jaspic.spec.version}"/>
    <filter token="jaspic.revision" value="${jaspic.revision}"/>
    <filter token="annotation.spec.version" value="${annotation.spec.version}"/>
    <filter token="annotation.revision" value="${annotation.revision}"/>

    <mkdir dir="${tomcat.manifests}" />
    <copy todir="${tomcat.manifests}" overwrite="yes" filtering="yes" encoding="ISO-8859-1">
      <filterset refid="version.filters"/>
      <fileset dir="${tomcat.home}/res/META-INF" />
    </copy>

    <!-- Ensure text files in JARs have consistent line endings. Required for
    reproducible builds. -->
    <fixcrlf srcdir="${tomcat.manifests}" eol="lf" encoding="ISO-8859-1" fixlast="false" >
      <patternset refid="text.files" />
    </fixcrlf>
  </target>

  <target name="package" depends="compile,build-manifests" >
    <!--
    #### ORDER IS IMPORTANT ####
    Bnd will use the built jars to resolve import package versions and
    JPMS module names.
      -->

    <!-- Common Annotations JAR File -->
    <jarIt jarfile="${annotations-api.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.annotations-api"
      manifest="${tomcat.manifests}/annotations-api.jar.manifest"
      addOSGi="true" />

    <!-- Servlet Implementation JAR File -->
    <jarIt jarfile="${servlet-api.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.servlet-api"
      manifest="${tomcat.manifests}/servlet-api.jar.manifest"
      notice="${tomcat.manifests}/servlet-api.jar.notice"
      license="${tomcat.manifests}/servlet-api.jar.license"
      addOSGi="true" />

    <!-- EL Implementation JAR File -->
    <jarIt jarfile="${el-api.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.el-api"
      manifest="${tomcat.manifests}/el-api.jar.manifest"
      addOSGi="true" />

    <!-- JSP Implementation JAR File -->
    <jarIt jarfile="${jsp-api.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.jsp-api"
      manifest="${tomcat.manifests}/jsp-api.jar.manifest"
      addOSGi="true" />

    <!-- WebSocket API JAR File -->
    <jarIt jarfile="${websocket-api.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.websocket-api"
      manifest="${tomcat.manifests}/websocket-api.jar.manifest"
      addOSGi="true" />

    <!-- WebSocket Client API JAR File -->
    <jarIt jarfile="${websocket-client-api.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.websocket-client-api"
      manifest="${tomcat.manifests}/websocket-client-api.jar.manifest"
      addOSGi="true" />

    <!-- JASPIC API JAR File -->
    <jarIt jarfile="${jaspic-api.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.jaspic-api"
      manifest="${tomcat.manifests}/jaspic-api.jar.manifest"
      addOSGi="true" />

    <!-- Tomcat-juli JAR File -->
    <jarIt jarfile="${tomcat-juli.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.tomcat-juli"
      addOSGi="true" />

    <!-- Bootstrap JAR File -->
    <jarIt jarfile="${bootstrap.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.bootstrap"
      manifest="${tomcat.manifests}/bootstrap.jar.manifest" />

    <!-- Tomcat Util JAR File -->
    <jarIt jarfile="${tomcat-util.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.tomcat-util"
      addOSGi="true" />

    <!-- Tomcat API JAR File -->
    <jarIt jarfile="${tomcat-api.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.tomcat-api"
      addOSGi="true" />

    <!-- Tomcat Util Scan JAR File -->
    <jarIt jarfile="${tomcat-util-scan.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.tomcat-util-scan"
      addOSGi="true" />

    <jarIt jarfile="${tomcat-jni.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.tomcat-jni"
      addOSGi="true" />

    <!-- Protocol handlers - Coyote -->
    <jarIt jarfile="${tomcat-coyote.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.tomcat-coyote"
      addOSGi="true" />

    <!-- OpenSSL FFM - Coyote -->
    <jarIt jarfile="${tomcat-coyote-ffm.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.tomcat-coyote-ffm"
      manifest="${tomcat.manifests}/tomcat-coyote-ffm.jar.manifest"
      addOSGi="true" />

    <!-- WebSocket implementation JAR File -->
    <jarIt jarfile="${tomcat-websocket.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.tomcat-websocket"
      meta-inf="${tomcat.manifests}/tomcat-websocket.jar"
      addOSGi="true" />

    <!-- Catalina GroupCom/Tribes JAR File -->
    <jarIt jarfile="${catalina-tribes.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.catalina-tribes"
      addOSGi="true" />

    <!-- Catalina Main JAR File -->
    <jarIt jarfile="${catalina.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.catalina"
      addOSGi="true" />

    <!-- Catalina Cluster/HA JAR File -->
    <jarIt jarfile="${catalina-ha.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.catalina-ha"
      addOSGi="true" />

    <!-- Server-Side Includes (SSI) -->
    <jarIt jarfile="${catalina-ssi.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.catalina-ssi"
      addOSGi="true" />

    <!-- Catalina Ant Tasks JAR File -->
    <jarIt jarfile="${catalina-ant.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.catalina-ant" />

    <!-- Catalina Storeconfig JAR File -->
    <jarIt jarfile="${catalina-storeconfig.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.catalina-storeconfig"
      addOSGi="true" />

    <!-- Jasper EL Implementation JAR File -->
    <jarIt jarfile="${jasper-el.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.jasper-el"
      meta-inf="${tomcat.manifests}/jasper-el.jar"
      addOSGi="true" />

    <!-- Jasper Implementation JAR File -->
    <jarIt jarfile="${jasper.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.jasper"
      meta-inf="${tomcat.manifests}/jasper.jar"
      addOSGi="true" />

    <!-- Re-packaged Apache Commons DBCP 2-->
    <jarIt jarfile="${tomcat-dbcp.jar}"
      filesDir="${tomcat.classes}"
      filesId="files.tomcat-dbcp"
      addOSGi="true" />

    <!-- i18n JARs -->
    <jar jarfile="${tomcat.build}/lib/tomcat-i18n-cs.jar"
         manifest="${tomcat.manifests}/default.manifest"
         modificationtime="${tstamp.iso.release}">
      <fileset dir="${tomcat.i18n}">
        <include name="**/LocalStrings_cs.properties" />
      </fileset>
      <zipfileset file="${tomcat.manifests}/default.notice"
        fullpath="META-INF/NOTICE" />
      <zipfileset file="${tomcat.manifests}/default.license"
        fullpath="META-INF/LICENSE" />
    </jar>
    <jar jarfile="${tomcat.build}/lib/tomcat-i18n-de.jar"
         manifest="${tomcat.manifests}/default.manifest"
         modificationtime="${tstamp.iso.release}">
      <fileset dir="${tomcat.i18n}">
        <include name="**/LocalStrings_de.properties" />
      </fileset>
      <zipfileset file="${tomcat.manifests}/default.notice"
        fullpath="META-INF/NOTICE" />
      <zipfileset file="${tomcat.manifests}/default.license"
        fullpath="META-INF/LICENSE" />
    </jar>
    <jar jarfile="${tomcat.build}/lib/tomcat-i18n-es.jar"
         manifest="${tomcat.manifests}/default.manifest"
         modificationtime="${tstamp.iso.release}">
      <fileset dir="${tomcat.i18n}">
        <include name="**/LocalStrings_es.properties" />
      </fileset>
      <zipfileset file="${tomcat.manifests}/default.notice"
        fullpath="META-INF/NOTICE" />
      <zipfileset file="${tomcat.manifests}/default.license"
        fullpath="META-INF/LICENSE" />
    </jar>
    <jar jarfile="${tomcat.build}/lib/tomcat-i18n-fr.jar"
         manifest="${tomcat.manifests}/default.manifest"
         modificationtime="${tstamp.iso.release}">
      <fileset dir="${tomcat.i18n}">
        <include name="**/LocalStrings_fr.properties" />
      </fileset>
      <zipfileset file="${tomcat.manifests}/default.notice"
        fullpath="META-INF/NOTICE" />
      <zipfileset file="${tomcat.manifests}/default.license"
        fullpath="META-INF/LICENSE" />
    </jar>
    <jar jarfile="${tomcat.build}/lib/tomcat-i18n-ja.jar"
         manifest="${tomcat.manifests}/default.manifest"
         modificationtime="${tstamp.iso.release}">
      <fileset dir="${tomcat.i18n}">
        <include name="**/LocalStrings_ja.properties" />
      </fileset>
      <zipfileset file="${tomcat.manifests}/default.notice"
        fullpath="META-INF/NOTICE" />
      <zipfileset file="${tomcat.manifests}/default.license"
        fullpath="META-INF/LICENSE" />
    </jar>
    <jar jarfile="${tomcat.build}/lib/tomcat-i18n-ko.jar"
         manifest="${tomcat.manifests}/default.manifest"
         modificationtime="${tstamp.iso.release}">
      <fileset dir="${tomcat.i18n}">
        <include name="**/LocalStrings_ko.properties" />
      </fileset>
      <zipfileset file="${tomcat.manifests}/default.notice"
        fullpath="META-INF/NOTICE" />
      <zipfileset file="${tomcat.manifests}/default.license"
        fullpath="META-INF/LICENSE" />
    </jar>
    <jar jarfile="${tomcat.build}/lib/tomcat-i18n-pt-BR.jar"
         manifest="${tomcat.manifests}/default.manifest"
         modificationtime="${tstamp.iso.release}">
      <fileset dir="${tomcat.i18n}">
        <include name="**/LocalStrings_pt_BR.properties" />
      </fileset>
      <zipfileset file="${tomcat.manifests}/default.notice"
        fullpath="META-INF/NOTICE" />
      <zipfileset file="${tomcat.manifests}/default.license"
        fullpath="META-INF/LICENSE" />
    </jar>
    <jar jarfile="${tomcat.build}/lib/tomcat-i18n-ru.jar"
         manifest="${tomcat.manifests}/default.manifest"
         modificationtime="${tstamp.iso.release}">
      <fileset dir="${tomcat.i18n}">
        <include name="**/LocalStrings_ru.properties" />
      </fileset>
      <zipfileset file="${tomcat.manifests}/default.notice"
        fullpath="META-INF/NOTICE" />
      <zipfileset file="${tomcat.manifests}/default.license"
        fullpath="META-INF/LICENSE" />
    </jar>
    <jar jarfile="${tomcat.build}/lib/tomcat-i18n-zh-CN.jar"
         manifest="${tomcat.manifests}/default.manifest"
         modificationtime="${tstamp.iso.release}">
      <fileset dir="${tomcat.i18n}">
        <include name="**/LocalStrings_zh_CN.properties" />
      </fileset>
      <zipfileset file="${tomcat.manifests}/default.notice"
        fullpath="META-INF/NOTICE" />
      <zipfileset file="${tomcat.manifests}/default.license"
        fullpath="META-INF/LICENSE" />
    </jar>

  </target>

  <target name="build-docs" depends="compile-prepare" description="Builds all documentation from XML sources">

    <!-- Validation of changelog.xml -->
    <xmlvalidate
      file="webapps/docs/changelog.xml"
    />

    <copy todir="${tomcat.build}/webapps">
      <fileset dir="webapps">
        <include name="docs/images/**"/>
        <include name="docs/META-INF/**"/>
        <include name="docs/WEB-INF/**"/>
        <include name="docs/appdev/*.txt"/>
        <include name="docs/appdev/sample/**"/>
      </fileset>
      <fileset dir="webapps">
        <include name="docs/architecture/**"/>
        <exclude name="docs/architecture/*.xml"/>
      </fileset>
    </copy>
    <copy todir="${tomcat.build}/webapps" encoding="UTF-8">
      <filterset refid="version.filters"/>
      <fileset dir="webapps">
        <include name="docs/**/*.html"/>
      </fileset>
    </copy>
    <copy todir="${tomcat.build}/webapps/docs" encoding="ISO-8859-1">
      <filterset refid="version.filters"/>
      <fileset dir=".">
        <include name="BUILDING.txt"/>
        <include name="RUNNING.txt"/>
      </fileset>
    </copy>
    <copy tofile="${tomcat.build}/webapps/docs/RELEASE-NOTES.txt" file="RELEASE-NOTES" encoding="ISO-8859-1">
      <filterset refid="version.filters"/>
    </copy>
    <copy tofile="${tomcat.build}/webapps/docs/mbeans-descriptors.dtd"
            file="java/org/apache/tomcat/util/modeler/mbeans-descriptors.dtd" />

    <copy   tofile="${tomcat.build}/webapps/docs/appdev/sample/build.xml"
              file="webapps/docs/appdev/build.xml.txt"/>

    <!-- XSL processing -->
    <xslt basedir="webapps/docs"
           destdir="${tomcat.build}/webapps/docs"
         extension=".html"
             style="webapps/docs/tomcat-docs.xsl"
 filenameparameter="filename"
          excludes="build.xml project.xml"
          includes="*.xml">
      <param name="sitedir" expression="tomcat-${version.major.minor}-doc/"/>
      <param name="subdir" expression=""/>
      <param name="relative-path" expression="."/>
      <param name="version" expression="${version}"/>
      <param name="majorversion" expression="${version.major}"/>
      <param name="majorminorversion" expression="${version.major.minor}"/>
      <param name="build-date" expression="${today}"/>
      <param name="build-date-iso-8601" expression="${today-iso-8601}"/>
      <param name="year" expression="${year}"/>
    </xslt>
    <xslt basedir="webapps/docs/appdev"
           destdir="${tomcat.build}/webapps/docs/appdev"
         extension=".html"
             style="webapps/docs/tomcat-docs.xsl"
 filenameparameter="filename"
          excludes="project.xml"
          includes="*.xml">
      <param name="sitedir" expression="tomcat-${version.major.minor}-doc/"/>
      <param name="subdir" expression="appdev/"/>
      <param name="relative-path" expression=".."/>
      <param name="version" expression="${version}"/>
      <param name="majorversion" expression="${version.major}"/>
      <param name="majorminorversion" expression="${version.major.minor}"/>
      <param name="build-date" expression="${today}"/>
      <param name="build-date-iso-8601" expression="${today-iso-8601}"/>
      <param name="year" expression="${year}"/>
    </xslt>
    <xslt basedir="webapps/docs/config"
           destdir="${tomcat.build}/webapps/docs/config"
         extension=".html"
             style="webapps/docs/tomcat-docs.xsl"
 filenameparameter="filename"
          excludes="project.xml"
          includes="*.xml">
      <param name="sitedir" expression="tomcat-${version.major.minor}-doc/"/>
      <param name="subdir" expression="config/"/>
      <param name="relative-path" expression=".."/>
      <param name="version" expression="${version}"/>
      <param name="majorversion" expression="${version.major}"/>
      <param name="majorminorversion" expression="${version.major.minor}"/>
      <param name="build-date" expression="${today}"/>
      <param name="build-date-iso-8601" expression="${today-iso-8601}"/>
      <param name="year" expression="${year}"/>
    </xslt>
    <xslt basedir="webapps/docs/architecture"
           destdir="${tomcat.build}/webapps/docs/architecture"
         extension=".html"
             style="webapps/docs/tomcat-docs.xsl"
 filenameparameter="filename"
          excludes="project.xml"
          includes="*.xml">
      <param name="sitedir" expression="tomcat-${version.major.minor}-doc/"/>
      <param name="subdir" expression="architecture/"/>
      <param name="relative-path" expression=".."/>
      <param name="version" expression="${version}"/>
      <param name="majorversion" expression="${version.major}"/>
      <param name="majorminorversion" expression="${version.major.minor}"/>
      <param name="build-date" expression="${today}"/>
      <param name="build-date-iso-8601" expression="${today-iso-8601}"/>
      <param name="year" expression="${year}"/>
    </xslt>

    <xslt basedir="webapps/docs/tribes"
               destdir="${tomcat.build}/webapps/docs/tribes"
             extension=".html"
                 style="webapps/docs/tomcat-docs.xsl"
     filenameparameter="filename"
              excludes="project.xml"
              includes="*.xml">
      <param name="sitedir" expression="tomcat-${version.major.minor}-doc/"/>
      <param name="subdir" expression="tribes/"/>
      <param name="relative-path" expression=".."/>
      <param name="version" expression="${version}"/>
      <param name="majorversion" expression="${version.major}"/>
      <param name="majorminorversion" expression="${version.major.minor}"/>
      <param name="build-date" expression="${today}"/>
      <param name="build-date-iso-8601" expression="${today-iso-8601}"/>
      <param name="year" expression="${year}"/>
    </xslt>
  </target>

  <target name="deploy" depends="package,build-docs,build-tomcat-jdbc,compile-webapp-examples"
          description="Default. Builds a working Tomcat instance">

    <copy tofile="${tomcat.build}/bin/commons-daemon.jar" file="${commons-daemon.jar}" />

    <!-- Copy scripts -->
    <copy todir="${tomcat.build}/bin">
      <fileset dir="bin">
         <exclude name="**/*.launch"/>
         <exclude name="**/*.sh"/>
         <exclude name="**/*.bat"/>
      </fileset>
    </copy>
    <copy todir="${tomcat.build}/bin" encoding="ISO-8859-1">
      <filterset refid="version.filters"/>
      <fileset dir="bin">
         <include name="**/*.sh"/>
         <include name="**/*.bat"/>
      </fileset>
    </copy>
    <!-- Copy doesn't retain permissions -->
    <chmod dir="${tomcat.build}/bin" includes="*.sh" perm="+x"/>

    <!-- Copy static resource files -->
    <copy todir="${tomcat.build}/conf" encoding="ISO-8859-1">
      <filterset refid="version.filters"/>
      <fileset dir="conf">
        <include name="**/*.policy"/>
        <include name="**/*.xml"/>
        <include name="**/*.xsd"/>
        <include name="**/*.properties"/>
      </fileset>
    </copy>

    <!-- Copy other regular webapps -->
    <copy todir="${tomcat.build}/webapps">
      <fileset dir="webapps">
        <include name="ROOT/**"/>
        <exclude name="ROOT/index.jsp"/>
        <include name="examples/**"/>
        <include name="manager/**"/>
        <include name="host-manager/**"/>
      </fileset>
    </copy>
    <copy todir="${tomcat.build}/webapps" encoding="UTF-8">
      <filterset refid="version.filters" />
      <fileset dir="webapps">
        <include name="ROOT/index.jsp"/>
      </fileset>
    </copy>

    <copy tofile="${tomcat.build}/webapps/ROOT/RELEASE-NOTES.txt" file="RELEASE-NOTES" encoding="ISO-8859-1">
      <filterset refid="version.filters"/>
    </copy>

    <!-- Delete all other versions of Eclipse JDT Compiler and copy the current one -->
    <local name="jdt.jar.filename" />
    <basename property="jdt.jar.filename" file="${jdt.jar}"/>
    <delete verbose="true">
      <fileset dir="${tomcat.build}/lib">
        <include name="ecj-*.jar"/>
        <exclude name="${jdt.jar.filename}"/>
      </fileset>
    </delete>
    <copy file="${jdt.jar}" todir="${tomcat.build}/lib"/>

    <!-- Delete all other versions of Tomcat Migration Tool for Jakarta EE and copy the current one -->
    <local name="migration.jar.filename" />
    <basename property="migration.jar.filename" file="${migration-lib.jar}"/>
    <delete verbose="true">
      <fileset dir="${tomcat.build}/lib">
        <include name="jakartaee-migration-*.jar"/>
        <exclude name="${migration-lib.jar.filename}"/>
      </fileset>
    </delete>
    <copy file="${migration-lib.jar}" todir="${tomcat.build}/lib"/>

    <!-- Add sources for examples -->
    <antcall target="examples-sources" />
  </target>

  <target name="compile-webapp-examples" >

    <!-- Build classes for examples webapp -->
    <mkdir dir="${tomcat.build}/webapps/examples/WEB-INF/classes"/>
    <javac   srcdir="webapps/examples/WEB-INF/classes"
             destdir="${tomcat.build}/webapps/examples/WEB-INF/classes"
             debug="${compile.debug}" deprecation="${compile.deprecation}"
             release="${compile.release}"
             classpath="${tomcat.classes}"
             encoding="ISO-8859-1"
             includeantruntime="false">
    </javac>

    <!-- Convert the message files of the examples webapp from UTF-8 to ASCII.
    This can be removed after upgrading to Java 9+ as the minimum JRE and
    specifying the encoding when loading the ResourceBundles -->
    <native2ascii src="webapps/examples/WEB-INF/classes"
                  dest="${tomcat.build}/webapps/examples/WEB-INF/classes"
                  includes="**/LocalStrings*.properties"
                  encoding="UTF-8"/>

  </target>

  <target name="build-tomcat-jdbc" depends="package">
    <!-- build the jdbc-pool jar and source jar-->
    <echo message="Building Tomcat JDBC pool libraries"/>
    <ant antfile="${tomcat.jdbc.dir}/build.xml" dir="${tomcat.jdbc.dir}"
         inheritAll="false" target="build">
      <property name="ant.tstamp.now.iso" value ="${tstamp.iso.release}" />
      <property name="tstamp.file" value ="${tstamp.file}" />
      <property name="tomcat.pool" value="${tomcat.pool}" />
      <property name="tomcat.juli.jar" value="${tomcat-juli.jar}" />
      <property name="skip.download" value="set"/>
      <property name="version" value="${version}"/>
      <property name="version.major" value="${version.major}"/>
      <property name="version.major.minor" value="${version.major.minor}"/>
    </ant>
    <copy file="${tomcat-jdbc.jar}" todir="${tomcat.build}/lib"/>
  </target>

  <target name="build-tomcat-jdbc-src">
    <!-- build the jdbc-pool source jar-->
    <echo message="Building Tomcat JDBC pool src JAR"/>
    <ant antfile="${tomcat.jdbc.dir}/build.xml" dir="${tomcat.jdbc.dir}"
         inheritAll="false" target="build-src">
      <property name="tomcat.pool" value="${tomcat.pool}" />
      <property name="tomcat.juli.jar" value="${tomcat-juli.jar}" />
      <property name="skip.download" value="set"/>
    </ant>
  </target>

  <target name="examples-sources" description="Create examples sources"
          unless="examples.sources.skip" >
    <taskdef name="txt2html"
             classname="org.apache.tomcat.buildutil.Txt2Html"
             classpath="${tomcat.classes}" />

    <txt2html todir="${tomcat.build}/webapps/examples/jsp/jsp2/simpletag">
      <fileset dir="webapps/examples/WEB-INF/classes/jsp2/examples">
        <include name="BookBean.java"/>
      </fileset>
      <fileset dir="webapps/examples/WEB-INF/classes/jsp2/examples/simpletag">
        <include name="FindBookSimpleTag.java"/>
        <include name="RepeatSimpleTag.java"/>
        <include name="HelloWorldSimpleTag.java"/>
      </fileset>
      <fileset dir="webapps/examples/WEB-INF/classes/jsp2/examples/el">
        <include name="Functions.java"/>
      </fileset>
    </txt2html>

    <txt2html todir="${tomcat.build}/webapps/examples/jsp/jsp2/jspattribute">
      <fileset dir="webapps/examples/WEB-INF/classes/jsp2/examples">
        <include name="FooBean.java"/>
      </fileset>
      <fileset dir="webapps/examples/WEB-INF/classes/jsp2/examples/simpletag">
        <include name="ShuffleSimpleTag.java"/>
        <include name="TileSimpleTag.java"/>
        <include name="HelloWorldSimpleTag.java"/>
      </fileset>
    </txt2html>

    <txt2html todir="${tomcat.build}/webapps/examples/jsp/jsptoserv">
      <fileset dir="webapps/examples/WEB-INF/classes">
        <include name="ServletToJsp.java"/>
      </fileset>
    </txt2html>

    <txt2html todir="${tomcat.build}/webapps/examples/jsp/jsp2/el">
      <fileset dir="webapps/examples/WEB-INF/classes/examples">
        <include name="ValuesTag.java"/>
      </fileset>
      <fileset dir="webapps/examples/WEB-INF/classes/jsp2/examples">
        <include name="ValuesBean.java"/>
      </fileset>
      <fileset dir="webapps/examples/WEB-INF/classes/jsp2/examples/el">
        <include name="Functions.java"/>
      </fileset>
    </txt2html>

    <txt2html todir="${tomcat.build}/webapps/examples/jsp/jsp2/misc">
      <fileset dir="webapps/examples/WEB-INF/classes/jsp2/examples/simpletag">
        <include name="EchoAttributesTag.java"/>
      </fileset>
    </txt2html>

    <txt2html todir="${tomcat.build}/webapps/examples/jsp/jsp2/tagfiles">
      <fileset dir="webapps/examples/WEB-INF/tags">
        <include name="**/*.tag" />
      </fileset>
    </txt2html>

    <txt2html todir="${tomcat.build}/webapps/examples">
      <fileset dir="webapps/examples">
        <include name="**/*.jsp" />
        <include name="**/*.jspx" />
        <include name="**/*.jspf" />
        <exclude name="error/errorpge.jsp"/>
        <exclude name="forward/one.jsp"/>
        <exclude name="include/foo.jsp"/>
        <exclude name="jsptoserv/hello.jsp"/>
        <exclude name="security/protected/error.jsp"/>
        <exclude name="security/protected/index.jsp"/>
        <exclude name="security/protected/login.jsp"/>
      </fileset>
    </txt2html>
  </target>
  <target name="embed-jars" description="Create embedded jars"
    depends="build-manifests,setup-bnd,compile,package" >

    <mkdir dir="${tomcat.embed}" />

    <copy file="${basedir}/LICENSE" todir="${tomcat.embed}" />
    <copy file="${basedir}/NOTICE" todir="${tomcat.embed}" />
    <copy file="${tomcat-dbcp.jar}" todir="${tomcat.embed}"
      failonerror="false"/>
    <copy file="${jdt.jar}" todir="${tomcat.embed}" />
    <copy file="${annotations-api.jar}" todir="${tomcat.embed}" />

    <!-- Note the meta-inf below will work as long as there is only one JAR
         that needs to add entries. If there is more than one a more complex
         solution will be required. -->
    <jarIt jarfile="${tomcat-embed-core.jar}"
           filesDir="${tomcat.classes}"
           filesId="files.tomcat-embed-core"
           notice="${tomcat.manifests}/servlet-api.jar.notice"
           license="${tomcat.manifests}/servlet-api.jar.license"
           addOSGi="true"
           addGraal="true"
           graalPrefix="org.apache.tomcat.embed/tomcat-embed-core"
           graalFiles="res/graal/tomcat-embed-core/native-image"
           libs="embed/*.jar"/>
    <jarIt jarfile="${tomcat-embed-el.jar}"
           filesDir="${tomcat.classes}"
           filesId="files.tomcat-embed-el"
           addOSGi="true"
           addGraal="true"
           graalPrefix="org.apache.tomcat.embed/tomcat-embed-el"
           graalFiles="res/graal/tomcat-embed-el/native-image"
           libs="embed/*.jar"/>
    <jarIt jarfile="${tomcat-embed-jasper.jar}"
           filesDir="${tomcat.classes}"
           filesId="files.tomcat-embed-jasper"
           meta-inf="${tomcat.manifests}/jasper.jar"
           addOSGi="true"
           addGraal="true"
           graalPrefix="org.apache.tomcat.embed/tomcat-embed-jasper"
           graalFiles="res/graal/tomcat-embed-jasper/native-image"
           libs="embed/*.jar"/>
    <jarIt jarfile="${tomcat-embed-websocket.jar}"
           filesDir="${tomcat.classes}"
           filesId="files.tomcat-embed-websocket"
           meta-inf="${tomcat.manifests}/tomcat-websocket.jar"
           addOSGi="true"
           addGraal="true"
           graalPrefix="org.apache.tomcat.embed/tomcat-embed-websocket"
           graalFiles="res/graal/tomcat-embed-websocket/native-image"
           libs="embed/*.jar"/>
  </target>

  <target name="embed-sources"
          description="Create source jars for embedded jars"
          depends="build-manifests,package-src-jar" >

    <mkdir dir="${tomcat.embed.sources}" />

    <jarIt jarfile="${tomcat-embed-core-sources.jar}"
           filesDir="java"
           filesId="files.tomcat-embed-core"
            notice="${tomcat.manifests}/servlet-api.jar.notice"
            license="${tomcat.manifests}/servlet-api.jar.license"/>
    <jarIt jarfile="${tomcat-embed-el-sources.jar}"
           filesDir="java"
           filesId="files.tomcat-embed-el"/>
    <jarIt jarfile="${tomcat-embed-jasper-sources.jar}"
           filesDir="java"
           filesId="files.tomcat-embed-jasper"/>
    <jarIt jarfile="${tomcat-embed-websocket-sources.jar}"
           filesDir="java"
           filesId="files.tomcat-embed-websocket"/>

    <copy file="${tomcat-dbcp-src.jar}" todir="${tomcat.embed.sources}" />

    <!--No sources for ${jdt.jar} -->

  </target>

  <target name="embed-programmatic-jar" description="Create non reflection embedded jar"
          depends="embed-jars,embed-sources">

    <!-- temporary directory to store the generated code -->
    <tempfile property="xreflect.directory" destDir="${java.io.tmpdir}" prefix="apache-tomcat-xreflect-"/>
    <echo>Generating Reflection Less Introspection to: ${xreflect.directory}</echo>
    <mkdir dir="${xreflect.directory}"/>
    <copy todir="${xreflect.directory}/sources">
      <fileset dir="java"/>
    </copy>
    <copy todir="${xreflect.directory}/classes">
      <fileset dir="${tomcat.classes}"/>
    </copy>

    <!-- Generate the reflection less XReflectionIntrospectionUtils .java file -->
    <java classname="org.apache.tomcat.util.xreflection.ObjectReflectionPropertyInspector"
          classpath="${xreflect.directory}/classes"
          fork="true">
      <jvmarg value="-Dsecurity.manager=allow"/>
      <arg value="${xreflect.directory}/sources"/>
    </java>

    <!-- Compile the generated XReflectionIntrospectionUtils.java class -->
    <delete file="${xreflect.directory}/classes/org/apache/tomcat/util/XReflectionIntrospectionUtils.class"/>
    <javac includes="org/apache/tomcat/util/XReflectionIntrospectionUtils.java"
           srcdir="${xreflect.directory}/sources"
           destdir="${xreflect.directory}/classes"
           debug="${compile.debug}"
           deprecation="${compile.deprecation}"
           release="${compile.release}"
           encoding="ISO-8859-1"
           includeAntRuntime="true" >
      <compilerarg value="-XDignore.symbol.file"/>
      <classpath refid="compile.classpath" />
    </javac>

    <!-- Create the binary JAR file -->
    <jarIt jarfile="${tomcat-embed-programmatic.jar}"
           filesDir="${xreflect.directory}/classes"
           filesId="files.tomcat-embed-programmatic"
           notice="${tomcat.manifests}/servlet-api.jar.notice"
           license="${tomcat.manifests}/servlet-api.jar.license"
           addOSGi="false"
           addGraal="true"
           graalPrefix="org.apache.tomcat.embed/tomcat-embed-programmatic"
           graalFiles="res/graal/tomcat-embed-programmatic/native-image"
           libs="embed/*.jar"/>

    <!-- Create the source JAR file -->
    <jarIt jarfile="${tomcat-embed-programmatic-sources.jar}"
           filesDir="${xreflect.directory}/sources"
           filesId="files.tomcat-embed-programmatic"
           notice="${tomcat.manifests}/servlet-api.jar.notice"
           license="${tomcat.manifests}/servlet-api.jar.license"/>

    <!-- Leave generated code in an easy place for review -->
    <copy todir="${tomcat.xreflect}"
          file="${xreflect.directory}/sources/org/apache/tomcat/util/XReflectionIntrospectionUtils.java"
          overwrite="true"/>
    <!-- Delete our temporary compilation directory -->
    <delete dir="${xreflect.directory}"/>
  </target>

  <target name="embed"
          description="Creates the embedded release"
          depends="embed-jars,embed-sources,embed-programmatic-jar" >

    <fixcrlf srcdir="${tomcat.embed}" eol="crlf"
        encoding="ISO-8859-1" fixlast="false" >
      <patternset refid="text.files" />
    </fixcrlf>

    <zip destfile="${tomcat.embed}/${final.name}-embed.zip"
         modificationtime="${tstamp.iso.release}"
         encoding="UTF8">
      <fileset dir="${tomcat.embed}">
        <include name="**" />
        <exclude name="*.asc" />
        <exclude name="*.sha512" />
        <exclude name="*.zip" />
        <exclude name="*.tar.gz" />
      </fileset>
    </zip>
    <hashAndSign file="${tomcat.embed}/${final.name}-embed.zip" />

    <fixcrlf srcdir="${tomcat.embed}" eol="lf"
        encoding="ISO-8859-1" fixlast="false" >
      <patternset refid="text.files" />
    </fixcrlf>

    <!-- Reproducible builds: consistent timestamps for distributed files -->
    <touch datetime="${tstamp.file}" pattern="yyyy-MM-dd HH:mm:ss">
      <fileset dir="${tomcat.embed}"/>
    </touch>

    <tar longfile="gnu" compression="gzip"
         tarfile="${tomcat.embed}/${final.name}-embed.tar.gz">
      <tarfileset dir="${tomcat.embed}" prefix="${final.name}-embed">
        <include name="**" />
        <exclude name="*.asc" />
        <exclude name="*.sha512" />
        <exclude name="*.zip" />
        <exclude name="*.tar.gz" />
      </tarfileset>
    </tar>
    <hashAndSign file="${tomcat.embed}/${final.name}-embed.tar.gz" />

  </target>

  <target name="test-compile" depends="compile,download-test-compile,compile-webapp-examples" >
    <mkdir dir="${test.classes}"/>
    <!-- Compile -->
    <javac srcdir="test" destdir="${test.classes}"
           debug="${compile.debug}"
           deprecation="${compile.deprecation}"
           release="${compile.release}"
           encoding="ISO-8859-1"
           includeantruntime="true">
      <classpath refid="tomcat.test.classpath" />
      <include name="org/apache/**" />
      <include name="jakarta/**" />
      <include name="util/**" />
      <!-- Exclude these by default as Gump can't run them because the -->
      <!-- classes on which they depend are not in any output JAR.     -->
      <exclude name="org/apache/tomcat/buildutil/**"/>
    </javac>
    <copy todir="${test.classes}">
      <fileset dir="test">
        <include name="META-INF/**"/>
        <include name="**/service-config.txt"/>
        <include name="**/logging-non-rotatable.properties"/>
        <include name="**/TestStrings.properties"/>
      </fileset>
    </copy>
  </target>

  <!-- Default JUnit log output formatter -->
  <property name="junit.formatter.type" value="plain" />
  <property name="junit.formatter.usefile" value="true" />
  <property name="junit.formatter.extension" value=".txt" />

  <target name="test" description="Runs the JUnit test cases"
          depends="test-nio,test-nio2,coverage-report,test-status" />

  <target name="test-clean" description="Runs the JUnit test cases"
          depends="clean-classes,test-nio,test-nio2,coverage-report,test-status" />

  <target name="test-only" description="Runs the JUnit test cases, without compilation"
          depends="test-only-nio,test-only-nio2,test-status" />

  <target name="test-status"
          description="Analyses logs directory and reports on skipped tests, test failures and test errors">
    <fileset id="test.result.skippedtests" dir="${test.reports}" includes="*.txt">
      <not>
        <contains text="Skipped: 0" />
      </not>
    </fileset>
    <fileset id="test.result.failedtests" dir="${test.reports}" includes="*.txt">
      <not>
        <contains text="Failures: 0, Errors: 0" />
      </not>
    </fileset>
    <concat>
      <header>Testsuites with skipped tests:${line.separator}</header>
      <string>${toString:test.result.skippedtests}</string>
      <filterchain>
        <tokenfilter delimOutput="${line.separator}">
          <stringtokenizer delims=";"/>
        </tokenfilter>
      </filterchain>
    </concat>
    <concat>
      <header>Testsuites with failed tests:${line.separator}</header>
      <string>${toString:test.result.failedtests}</string>
      <filterchain>
        <tokenfilter delimOutput="${line.separator}">
          <stringtokenizer delims=";"/>
        </tokenfilter>
      </filterchain>
    </concat>

    <fail if="test.result.error" message='Some tests completed with an Error. See ${tomcat.build}/logs for details, search for "ERROR".' />
    <fail if="test.result.failure" message='Some tests completed with a Failure. See ${tomcat.build}/logs for details, search for "FAILED".' />
  </target>

  <target name="test-nio" description="Runs the JUnit test cases for NIO. Does not stop on errors."
          depends="setup-jacoco,test-compile,deploy,test-openssl-exists" if="${execute.test.nio}">
    <runtests protocol="org.apache.coyote.http11.Http11NioProtocol"
              extension=".NIO" />
  </target>

  <target name="test-only-nio" description="Runs the JUnit test cases or NIO without test preparations. Does not stop on errors."
          depends="setup-jacoco,test-openssl-exists" if="${execute.test.nio}">
    <runtests protocol="org.apache.coyote.http11.Http11NioProtocol"
              extension=".NIO" />
  </target>

  <target name="test-nio2" description="Runs the JUnit test cases for NIO2. Does not stop on errors."
          depends="setup-jacoco,test-compile,deploy,test-openssl-exists" if="${execute.test.nio2}">
    <runtests protocol="org.apache.coyote.http11.Http11Nio2Protocol"
              extension=".NIO2" />
  </target>

  <target name="test-only-nio2" description="Runs the JUnit test cases or NIO2 without test preparations. Does not stop on errors."
          depends="setup-jacoco,test-openssl-exists" if="${execute.test.nio2}">
    <runtests protocol="org.apache.coyote.http11.Http11Nio2Protocol"
          extension=".NIO2" />
  </target>

  <target name="test-openssl-exists" description="Checks for the OpenSSL binary">
    <property environment="env" />
    <condition property="test.openssl.exists">
      <or>
        <and>
          <length string="${test.openssl.path}" trim="true" length="0" when="gt"/>
          <available file="${test.openssl.path}" property="test.openssl.exists"/>
        </and>
        <and>
          <length string="${test.openssl.path}" trim="true" length="0" when="eq"/>
          <available file="openssl" filepath="${env.PATH}" property="test.openssl.exists"/>
        </and>
      </or>
    </condition>
  </target>

  <!-- Set native specific properties -->
  <condition property="native.nativeaccess" value="--enable-native-access=ALL-UNNAMED"><javaversion atleast="22"/></condition>
  <property name="native.nativeaccess" value="-Dtest.1=1"/>
  <property name="runtests.librarypath" value="-Djava.library.path=${test.apr.loc}${path.separator}${java.library.path}"/>
  <property name="opens.javalang" value="--add-opens=java.base/java.lang=ALL-UNNAMED"/>
  <property name="opens.javaio" value="--add-opens=java.base/java.io=ALL-UNNAMED"/>
  <property name="opens.sunrmi" value="--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED"/>
  <property name="opens.javautil" value="--add-opens=java.base/java.util=ALL-UNNAMED"/>
  <property name="opens.javautilconcurrent" value="--add-opens=java.base/java.util.concurrent=ALL-UNNAMED"/>
  <!-- Set memory properties (unset by default) -->
  <property name="test.xmx" value="-Dnoop"/>

  <macrodef name="runtests"
            description="Runs the unit tests using the specified connector.
              Does not stop on errors, but sets 'test.result.error' and 'test.result.failure' properties.">
    <attribute name="protocol"
               description="The class name for the connector protocol"/>
    <attribute name="extension"
               description="The extension to use to distinguish the output"/>

    <sequential>
      <mkdir dir="${test.reports}" />
      <jacoco:coverage
          enabled="${test.coverage}"
          destfile="${coverage.datafile}"
          >
        <junit printsummary="yes" fork="yes" dir="." showoutput="${test.verbose}"
          errorproperty="test.result.error"
          failureproperty="test.result.failure"
          haltonfailure="${test.haltonfailure}"
          threads="${test.threads}">

          <jvmarg value="${test.jvmarg.egd}"/>
          <jvmarg value="-Dfile.encoding=UTF-8"/>
          <jvmarg value="${test.xmx}"/>
          <jvmarg value="${runtests.librarypath}"/>
          <jvmarg value="${test.formatter}"/>
          <jvmarg value="-Djava.net.preferIPv4Stack=${java.net.preferIPv4Stack}"/>
          <jvmarg value="${opens.javalang}"/>
          <jvmarg value="${opens.javaio}"/>
          <jvmarg value="${opens.sunrmi}"/>
          <jvmarg value="${opens.javautil}"/>
          <jvmarg value="${opens.javautilconcurrent}"/>
          <jvmarg value="${native.nativeaccess}"/>
          <!-- These are managed as jvmargs rather than sysproperty because the default varies by OS -->
          <jvmarg value="${openssl.ffm.1}" />
          <jvmarg value="${openssl.ffm.2}" />
          <jvmarg value="${openssl.ffm.3}" />

          <classpath refid="tomcat.test.classpath" />

          <sysproperty key="tomcat.test.temp" value="${test.temp}" />
          <sysproperty key="tomcat.test.basedir" value="${test.basedir}" />
          <sysproperty key="tomcat.test.tomcatbuild" value="${tomcat.build}" />
          <sysproperty key="tomcat.test.protocol" value="@{protocol}" />
          <sysproperty key="tomcat.test.accesslog" value="${test.accesslog}" />
          <sysproperty key="tomcat.test.reports" value="${test.reports}" />
          <sysproperty key="tomcat.test.openssl.path" value="${test.openssl.path}" />
          <sysproperty key="tomcat.test.openssl.unimplemented" value="${test.openssl.unimplemented}" />
          <sysproperty key="tomcat.test.relaxTiming" value="${test.relaxTiming}" />
          <sysproperty key="tomcat.test.sslImplementation" value="${test.sslImplementation}" />
          <sysproperty key="tomcat.test.http2.loopCount" value="${test.http2.loopCount}" />

          <formatter type="${junit.formatter.type}"
                     usefile="${junit.formatter.usefile}"
                     extension="@{extension}${junit.formatter.extension}" />

          <!-- If test.entry is defined, run a single test, otherwise run all valid tests -->
          <test todir="${test.reports}" name="${test.entry}"
                if="test.entry" unless="test.entry.methods"
                />
          <test todir="${test.reports}" name="${test.entry}" methods="${test.entry.methods}"
                if="test.entry.methods"
                />
          <batchtest todir="${test.reports}" unless="test.entry">
            <!-- Include all by default -->
            <fileset dir="test" includes="${test.name}" excludes="${test.exclude}">
              <!-- Exclude helper classes -->
              <exclude name="**/Tester*.java" />
              <!-- Exclude the tests known to fail -->
              <exclude name="org/apache/catalina/tribes/test/**" />
              <!-- Exclude the OpenSSL tests unless OpenSSL is available -->
              <exclude name="org/apache/tomcat/util/net/openssl/ciphers/**" unless="${test.openssl.exists}" />
              <!-- Exclude performance tests. E.g. on systems with slow/inconsistent timing -->
              <exclude name="**/*Performance.java" if="${test.excludePerformance}" />
              <!-- Exclude tests that Gump can't compile -->
              <exclude name="org/apache/tomcat/buildutil/**" />
              <!-- Exclude tests that require large heaps -->
              <exclude name="**/*LargeHeap.java" unless="${test.includeLargeHeap}" />
              <!--
                Avoid running tests which require the SecurityManager with other
                tests. See below for more details.
              -->
              <exclude name="**/*SecurityManager.java" />
            </fileset>
          </batchtest>
          <!--
             Run tests which require the SecurityManager in their own forked
             batch to ensure that global/system security settings don't pollute
             other tests. See SecurityManagerBaseTest.java for more details.
          -->
          <batchtest todir="${test.reports}" unless="test.entry" fork="true">
            <fileset dir="test" includes="**/SecurityManager.java" excludes="${test.exclude}" />
          </batchtest>
        </junit>
      </jacoco:coverage>
    </sequential>
  </macrodef>

  <target name="coverage-report" if="${test.coverage}"
          depends="test-nio,test-nio2"
          description="Creates report from gathered Code coverage results">

    <jacoco:report>
      <executiondata>
        <file file="${coverage.datafile}"/>
      </executiondata>
      <structure name="Tomcat 10.1.x Code Coverage">
        <classfiles>
          <fileset dir="${tomcat.classes}"/>
        </classfiles>
        <sourcefiles encoding="UTF-8">
          <fileset dir="java"/>
        </sourcefiles>
      </structure>
      <html destdir="${coverage.out}"/>
    </jacoco:report>

  </target>

  <target name="spotbugs"
          if="${execute.spotbugs}"
          depends="test-compile,download-spotbugs">

    <path id="spotbugs.classpath">
      <fileset file="${spotbugs.jar}" />
    </path>

    <taskdef classpathref="spotbugs.classpath" name="spotbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"/>

    <mkdir dir="${spotbugs.out}" />

    <spotbugs home="${spotbugs.home}"
              output="${spotbugs.report.format}"
              outputFile="${spotbugs.out}/spotbugs-report.${spotbugs.report.format}"
              reportLevel="${spotbugs.report.level}"
              excludeFilter="res/spotbugs/filter-false-positives.xml" >
      <sourcePath path="${basedir}/java" />
      <class location="${tomcat.classes}" />
      <class location="${test.classes}" />
      <auxClasspath>
        <path refid="tomcat.test.classpath"/>
        <fileset file="${ant.core.lib}" />
      </auxClasspath>
    </spotbugs>
  </target>

  <target name="dist-prepare" depends="download-dist">
    <mkdir dir="${tomcat.dist}"/>
    <mkdir dir="${tomcat.dist}/bin"/>
    <mkdir dir="${tomcat.dist}/conf"/>
    <mkdir dir="${tomcat.dist}/lib"/>
    <mkdir dir="${tomcat.dist}/logs"/>
    <mkdir dir="${tomcat.dist}/temp"/>
    <mkdir dir="${tomcat.dist}/webapps"/>
    <mkdir dir="${tomcat.dist}/work"/>
    <mkdir dir="${tomcat.release}/v${version}/bin" />
    <mkdir dir="${tomcat.release}/v${version}/src" />
  </target>

  <target name="dist-static" depends="dist-prepare, deploy, embed">

    <!-- Copy the top-level documentation files -->
    <copy todir="${tomcat.dist}" encoding="ISO-8859-1">
      <filterset refid="version.filters"/>
      <fileset dir=".">
        <include name="LICENSE"/>
        <include name="NOTICE"/>
        <include name="RELEASE-NOTES"/>
        <include name="RUNNING.txt"/>
        <include name="README.md"/>
        <include name="BUILDING.txt" />
        <include name="CONTRIBUTING.md"/>
      </fileset>
    </copy>

    <!-- Copy the contents of each "build" directory -->
    <copy todir="${tomcat.dist}/bin">
      <fileset dir="${tomcat.build}/bin">
      </fileset>
    </copy>
    <copy todir="${tomcat.dist}/lib">
      <fileset dir="${tomcat.build}/lib" />
    </copy>
    <copy todir="${tomcat.dist}/conf">
      <fileset dir="${tomcat.build}/conf">
      </fileset>
    </copy>

    <copy todir="${tomcat.dist}/webapps">
      <fileset dir="${tomcat.build}/webapps">
        <exclude name="**/ROOT/WEB-INF/classes/**" />
        <exclude name="**/WEB-INF/src/**" />
      </fileset>
    </copy>

    <touch file="${tomcat.dist}/temp/safeToDelete.tmp" />

    <!-- Correct permissions and line endings on "bin" scripts -->
    <fixcrlf srcdir="${tomcat.dist}/bin" includes="*.sh"  eol="lf"   encoding="ISO-8859-1" fixlast="false" />
    <fixcrlf srcdir="${tomcat.dist}/bin" includes="*.bat" eol="crlf" encoding="ISO-8859-1" fixlast="false" />
    <chmod      dir="${tomcat.dist}/bin" includes="*.sh"  perm="+x"/>

    <!-- Windows binaries -->
    <!-- 32 bit -->
    <copy file="${commons-daemon.home}/windows/prunsrv.exe"
        tofile="${tomcat.dist}/bin/tomcat${version.major}.exe" />
    <copy file="${commons-daemon.home}/windows/prunmgr.exe"
        tofile="${tomcat.dist}/bin/tomcat${version.major}w.exe" />
    <!-- 64 bit amd -->
    <copy file="${commons-daemon.home}/windows/amd64/prunsrv.exe"
        tofile="${tomcat.dist}/bin/x64/tomcat${version.major}.exe" />
    <!-- tc native -->
    <copy todir="${tomcat.dist}/bin">
      <fileset dir="${tomcat-native.home}/bin">
        <include name="*.dll"/>
        <include name="**/*.dll"/>
      </fileset>
    </copy>

    <!-- Source bundles for native components -->
    <copy tofile="${tomcat.dist}/bin/tomcat-native.tar.gz"
            file="${tomcat-native.tar.gz}" />
    <copy tofile="${tomcat.dist}/bin/commons-daemon-native.tar.gz"
            file="${commons-daemon.native.src.tgz}" />

    <!-- platform README files -->
    <echo append="false" file="${tomcat.dist}/bin/x64/README">
Apache Tomcat ${version} native binaries for Win64 AMD64/EMT64 platform.
    </echo>

  </target>

  <target name="javadoc" depends="dist-source,download-compile"
    description="Create the Tomcat javadoc" >
    <javadoc packagenames="jakarta.annotation.*"
      sourcepath="${tomcat.dist}/src/java"
      destdir="${tomcat.dist}/webapps/docs/annotationapi"
      version="true"
      windowtitle="Common Annotations ${annotation.spec.version} API Documentation - Apache Tomcat ${version}"
      doctitle="Common Annotations ${annotation.spec.version} API - Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version}"
      header="&lt;b&gt;Common Annotations ${annotation.spec.version} - Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version}&lt;/b&gt;"
      bottom="Copyright &amp;#169; 2000-${year} Apache Software Foundation.
              &lt;br/&gt;
              Apache Tomcat, Tomcat, Apache, the Apache Tomcat logo and the Apache logo are either registered trademarks
              or trademarks of the Apache Software Foundation."
      encoding="UTF-8"
      docencoding="UTF-8"
      charset="UTF-8"
      additionalparam="-breakiterator -notimestamp -html5"
      source="${compile.release}"
      maxmemory="512m"
      failonerror="${javadoc.failonerror}"
      failonwarning="${javadoc.failonwarning}">
      <classpath>
        <path refid="compile.classpath"/>
        <path location="${ant.core.lib}"/>
      </classpath>
    </javadoc>
    <javadoc packagenames="jakarta.servlet.*"
      excludepackagenames="jakarta.servlet.jsp.*"
      sourcepath="${tomcat.dist}/src/java"
      destdir="${tomcat.dist}/webapps/docs/servletapi"
      version="true"
      windowtitle="Servlet ${servlet.spec.version} API Documentation - Apache Tomcat ${version}"
      doctitle="Servlet ${servlet.spec.version} API - Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version}"
      header="&lt;b&gt;Servlet ${servlet.spec.version} - Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version}&lt;/b&gt;"
      bottom="Copyright &amp;#169; 2000-${year} Apache Software Foundation.
              &lt;br/&gt;
              Apache Tomcat, Tomcat, Apache, the Apache Tomcat logo and the Apache logo are either registered trademarks
              or trademarks of the Apache Software Foundation."
      encoding="UTF-8"
      docencoding="UTF-8"
      charset="UTF-8"
      additionalparam="-breakiterator -notimestamp -html5"
      source="${compile.release}"
      maxmemory="512m"
      failonerror="${javadoc.failonerror}"
      failonwarning="${javadoc.failonwarning}">
      <classpath>
        <path refid="compile.classpath"/>
        <path location="${ant.core.lib}"/>
      </classpath>
    </javadoc>
    <javadoc packagenames="jakarta.servlet.jsp.*"
      sourcepath="${tomcat.dist}/src/java"
      destdir="${tomcat.dist}/webapps/docs/jspapi"
      version="true"
      windowtitle="JSP ${jsp.spec.version} API Documentation - Apache Tomcat ${version}"
      doctitle="JSP ${jsp.spec.version} API - Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version}"
      header="&lt;b&gt;JSP ${jsp.spec.version} - Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version}&lt;/b&gt;"
      bottom="Copyright &amp;#169; 2000-${year} Apache Software Foundation.
              &lt;br/&gt;
              Apache Tomcat, Tomcat, Apache, the Apache Tomcat logo and the Apache logo are either registered trademarks
              or trademarks of the Apache Software Foundation."
      encoding="UTF-8"
      docencoding="UTF-8"
      charset="UTF-8"
      additionalparam="-breakiterator -notimestamp -html5"
      source="${compile.release}"
      maxmemory="512m"
      failonerror="${javadoc.failonerror}"
      failonwarning="${javadoc.failonwarning}">
      <classpath>
        <path refid="compile.classpath"/>
        <path location="${ant.core.lib}"/>
      </classpath>
    </javadoc>
    <javadoc packagenames="jakarta.el.*"
      sourcepath="${tomcat.dist}/src/java"
      destdir="${tomcat.dist}/webapps/docs/elapi"
      version="true"
      windowtitle="EL ${el.spec.version} API Documentation - Apache Tomcat ${version}"
      doctitle="EL ${el.spec.version} API - Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version}"
      header="&lt;b&gt;EL ${el.spec.version} - Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version}&lt;/b&gt;"
      bottom="Copyright &amp;#169; 2000-${year} Apache Software Foundation.
              &lt;br/&gt;
              Apache Tomcat, Tomcat, Apache, the Apache Tomcat logo and the Apache logo are either registered trademarks
              or trademarks of the Apache Software Foundation."
      encoding="UTF-8"
      docencoding="UTF-8"
      charset="UTF-8"
      additionalparam="-breakiterator -notimestamp -html5"
      source="${compile.release}"
      maxmemory="512m"
      failonerror="${javadoc.failonerror}"
      failonwarning="${javadoc.failonwarning}">
      <classpath>
        <path refid="compile.classpath"/>
        <path location="${ant.core.lib}"/>
      </classpath>
    </javadoc>
    <javadoc packagenames="jakarta.websocket.*"
      sourcepath="${tomcat.dist}/src/java"
      destdir="${tomcat.dist}/webapps/docs/websocketapi"
      version="true"
      windowtitle="WebSocket ${websocket.spec.version} API Documentation - Apache Tomcat ${version}"
      doctitle="WebSocket ${websocket.spec.version} API - Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version}"
      header="&lt;b&gt;WebSocket ${websocket.spec.version} - Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version}&lt;/b&gt;"
      bottom="Copyright &amp;#169; 2000-${year} Apache Software Foundation.
              &lt;br/&gt;
              Apache Tomcat, Tomcat, Apache, the Apache Tomcat logo and the Apache logo are either registered trademarks
              or trademarks of the Apache Software Foundation."
      encoding="UTF-8"
      docencoding="UTF-8"
      charset="UTF-8"
      additionalparam="-breakiterator -notimestamp -html5"
      source="${compile.release}"
      maxmemory="512m"
      failonerror="${javadoc.failonerror}"
      failonwarning="${javadoc.failonwarning}">
      <classpath>
        <path refid="compile.classpath"/>
        <path location="${ant.core.lib}"/>
      </classpath>
    </javadoc>
    <javadoc packagenames="jakarta.security.auth.message.*"
      sourcepath="${tomcat.dist}/src/java"
      destdir="${tomcat.dist}/webapps/docs/jaspicapi"
      version="true"
      windowtitle="JASPIC ${jaspic.spec.version} API Documentation - Apache Tomcat ${version}"
      doctitle="JASPIC ${jaspic.spec.version} API - Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version}"
      header="&lt;b&gt;JASPIC ${jaspic.spec.version} - Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version}&lt;/b&gt;"
      bottom="Copyright &amp;#169; 2000-${year} Apache Software Foundation.
              &lt;br/&gt;
              Apache Tomcat, Tomcat, Apache, the Apache Tomcat logo and the Apache logo are either registered trademarks
              or trademarks of the Apache Software Foundation."
      encoding="UTF-8"
      docencoding="UTF-8"
      charset="UTF-8"
      additionalparam="-breakiterator -notimestamp -html5"
      maxmemory="512m"
      failonerror="${javadoc.failonerror}"
      failonwarning="${javadoc.failonwarning}">
      <classpath>
        <path refid="compile.classpath"/>
        <path location="${ant.core.lib}"/>
      </classpath>
    </javadoc>
    <javadoc packagenames="org.apache.*"
      destdir="${tomcat.dist}/webapps/docs/api"
      version="true"
      windowtitle="Apache Tomcat ${version} API Documentation"
      doctitle="Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version} API"
      header="&lt;b&gt;Apache Tomcat&lt;sup&gt;&#174;&lt;/sup&gt; ${version}&lt;/b&gt;"
      bottom="Copyright &amp;#169; 2000-${year} Apache Software Foundation.
              &lt;br/&gt;
              Apache Tomcat, Tomcat, Apache, the Apache Tomcat logo and the Apache logo are either registered trademarks
              or trademarks of the Apache Software Foundation."
      encoding="UTF-8"
      docencoding="UTF-8"
      charset="UTF-8"
      additionalparam="-breakiterator -notimestamp -html5"
      source="${compile.release}"
      maxmemory="512m"
      failonerror="${javadoc.failonerror}"
      failonwarning="${javadoc.failonwarning}">
      <classpath>
        <path refid="compile.classpath"/>
        <path location="${ant.core.lib}"/>
      </classpath>
      <link href="../annotationapi"/>
      <link href="../servletapi"/>
      <link href="../jspapi"/>
      <link href="../elapi"/>
      <link href="../websocketapi"/>
      <link href="../jaspicapi"/>
      <link href="https://docs.oracle.com/en/java/javase/11/docs/api/"/>
      <link href="https://jakarta.ee/specifications/platform/10/apidocs/"/>
      <packageset dir="${tomcat.dist}/src/java/">
        <include name="org/**"/>
        <exclude name="org/apache/el/parser/**"/>
        <exclude name="org/apache/tomcat/util/json/**"/>
        <exclude name="org/apache/tomcat/util/net/openssl/panama/**"/>
        <exclude name="org/apache/tomcat/util/openssl/**"/>
      </packageset>
      <!--jdbc-pool src files for javadoc-->
      <packageset dir="${tomcat.dist}/src/modules/jdbc-pool/src/main/java"/>
    </javadoc>
  </target>

  <target name="dist-deployer" depends="dist-prepare,deploy"
    description="Create the Tomcat deployer binary">

    <!-- Servlet and JSP -->
    <copy todir="${tomcat.deployer}/lib">
      <fileset dir="${tomcat.build}/lib">
        <include name="catalina-ant.jar"/>
        <include name="el-api.jar"/>
        <include name="jsp-api.jar"/>
        <include name="jasper.jar"/>
        <include name="jasper-el.jar"/>
        <include name="jaspic-api.jar"/>
        <include name="servlet-api.jar"/>
        <include name="websocket-api.jar"/>
        <include name="websocket-client-api.jar"/>
        <include name="tomcat-websocket.jar"/>
        <include name="tomcat-coyote.jar"/>
        <include name="tomcat-util.jar"/>
        <include name="tomcat-util-scan.jar"/>
      </fileset>
      <fileset dir="${tomcat.build}/bin">
        <include name="tomcat-juli.jar"/>
      </fileset>
    </copy>

    <!-- Digester and dependencies -->
    <jar jarfile="${tomcat.deployer}/lib/catalina-deployer.jar"
         manifest="${tomcat.manifests}/default.manifest"
         modificationtime="${tstamp.iso.release}">
      <fileset dir="${tomcat.classes}">
        <include name="org/apache/catalina/startup/DigesterFactory.class" />
        <include name="org/apache/catalina/util/SchemaResolver.class" />
        <include name="org/apache/catalina/util/StringManager.class" />
        <include name="org/apache/tomcat/util/*" />
        <include name="org/apache/tomcat/util/digester/**" />
        <exclude name="org/apache/tomcat/util/bcel" />
        <exclude name="org/apache/tomcat/util/buf" />
        <exclude name="org/apache/tomcat/util/codec" />
        <exclude name="org/apache/tomcat/util/collections" />
        <exclude name="org/apache/tomcat/util/compat" />
        <exclude name="org/apache/tomcat/util/descriptor" />
        <exclude name="org/apache/tomcat/util/file" />
        <exclude name="org/apache/tomcat/util/http" />
        <exclude name="org/apache/tomcat/util/log" />
        <exclude name="org/apache/tomcat/util/modeler" />
        <exclude name="org/apache/tomcat/util/net" />
        <exclude name="org/apache/tomcat/util/res" />
        <exclude name="org/apache/tomcat/util/scan" />
        <exclude name="org/apache/tomcat/util/security" />
        <exclude name="org/apache/tomcat/util/threads" />
        <exclude name="**/package.html" />
        <exclude name="**/LocalStrings_*" />
      </fileset>
      <zipfileset file="${tomcat.manifests}/default.notice"
        fullpath="META-INF/NOTICE" />
      <zipfileset file="${tomcat.manifests}/default.license"
        fullpath="META-INF/LICENSE" />
    </jar>

    <!-- Main build script -->
    <copy todir="${tomcat.deployer}">
      <fileset dir="${basedir}/res/deployer" />
    </copy>

    <!-- Copy deployer documentation -->
    <copy todir="${tomcat.deployer}">
      <fileset dir="${tomcat.build}/webapps/docs">
        <include name="images/asf-logo.svg" />
        <include name="images/tomcat.png" />
        <include name="images/docs-stylesheet.css" />
      </fileset>
    </copy>
    <copy tofile="${tomcat.deployer}/deployer-howto.html"
      file="${tomcat.build}/webapps/docs/deployer-howto.html"/>

  </target>

  <target name="dist-source" depends="compile-prepare">

    <mkdir dir="${tomcat.dist}/src"/>

    <!-- Tomcat source -->
    <copy todir="${tomcat.dist}/src">
      <fileset dir="${basedir}" defaultexcludes="true">
        <not>
          <or>
            <filename name="**/.settings/**" />
            <filename name="**/.classpath"/>
            <filename name="**/.checkstyle"/>
            <filename name="**/.pmd"/>
            <filename name="**/.project"/>
            <filename name="**/.sdkmanrc"/>
            <filename name="**/nbproject/**"/>
            <filename name="**/output/**"/>
            <!-- Commented out, because
                 test/webapp-virtual-library and
                 test/webapp-virtual-webapp use it:
            <filename name="**/target/**"/>
            -->
            <filename name="**/build.properties"/>
            <filename name="**/mvn.properties"/>
            <and>
              <!-- Don't exclude the ide support sample files for idea -->
              <filename name="**/*.iml" />
              <not>
                <filename name="res/ide-support/idea/**" />
              </not>
            </and>
            <filename name="**/*.asc" />
            <filename name="**/*.tmp" />
            <filename name="**/.*.sw*" />
            <filename name="**/maven-resolver-ant-tasks-*.jar" />
            <filename name="**/thumbs.db" />
            <filename name="**/Thumbs.db" />
            <filename name="*.launch"/>
            <filename name="bin/setenv.*" />
            <filename name="java/org/apache/catalina/startup/catalina.properties" />
            <filename name="java/org/apache/el/parser/ELParser.jj" />
            <filename name="logs/**" />
            <filename name="webapps/docs/jdbc-pool.xml" />
            <filename name="work/**" />
            <filename name="modules/jdbc-pool/bin/**" />
            <filename name="modules/jdbc-pool/includes/**" />
            <and>
              <!-- exclude all modules except jdbc-pool -->
              <filename name="modules/**" />
              <not>
                <filename name="modules/jdbc-pool/**" />
              </not>
            </and>
          </or>
        </not>
      </fileset>
    </copy>
  </target>

  <target name="-installer-set-properties-1">
    <property environment="env"/>
    <condition property="wine.ok">
      <or>
        <and>
          <equals arg1="${nsis.tool}" arg2="wine" forcestring="true"/>
          <available file="wine" filepath="${env.PATH}"/>
        </and>
      </or>
    </condition>
    <condition property="nsis.executable.unix" value="${nsis.bin.home}/Bin/makensis">
      <and>
        <equals arg1="${nsis.tool}" arg2="makensis" forcestring="true"/>
        <available file="makensis" filepath="${nsis.bin.home}/Bin"/>
      </and>
    </condition>
    <condition property="nsis.executable.unix" value="makensis">
      <and>
        <equals arg1="${nsis.tool}" arg2="makensis" forcestring="true"/>
        <available file="makensis" filepath="${env.PATH}"/>
        <not>
          <available file="makensis" filepath="${nsis.bin.home}/Bin"/>
        </not>
      </and>
    </condition>
    <condition property="installer.ok">
      <or>
        <os family="windows"/>
        <isset property="wine.ok"/>
        <isset property="nsis.executable.unix"/>
        <istrue value="${skip.installer}"/>
      </or>
    </condition>
  </target>

  <target name="-installer-set-properties-2"
      depends="-installer-set-properties-1"
      if="nsis.executable.unix">
    <exec executable="${nsis.executable.unix}" outputproperty="nsis.executable.unix.version">
      <arg value="-VERSION"/>
    </exec>
  </target>

  <target name="-installer-set-properties-3"
      depends="-installer-set-properties-2">
    <condition property="nsis.executable.unix.version.ok">
      <or>
        <istrue value="${skip.installer}"/>
        <os family="windows"/>
        <isset property="wine.ok"/>
        <equals arg1="v${nsis.version}" arg2="${nsis.executable.unix.version}"/>
        <not>
          <!-- Zero length string for version.dev indicates a release build -->
          <equals arg1="${version.dev}" arg2=""/>
        </not>
      </or>
    </condition>
  </target>

  <target name="-installer-check-available"
      depends="-installer-set-properties-1"
      unless="${installer.ok}">
    <fail message="The executable ${nsis.tool} was not found on the current path.
Either wine or makensis are required to build the Windows installer on a non-Windows platform.
Choose the tool by setting property nsis.tool in build.properties.
To skip building the Windows installer, set the skip.installer property in build.properties"/>
  </target>

  <target name="-installer-check-version"
      depends="-installer-set-properties-3"
      unless="${nsis.executable.unix.version.ok}">
    <fail message="An executable makensis was found at: ${nsis.executable.unix}
with version [${nsis.executable.unix.version}] but version [v${nsis.version}] is required
for repeatable builds.
You may need a custom build of makensis. Instructions for this may be found in BUILDING.txt"/>
  </target>

  <target name="-installer-checks"
      depends="-installer-check-available,-installer-check-version">
  </target>

  <target name="-installer-prep"
      depends="dist-static,-installer-checks"
      unless="${skip.installer}">
    <copy todir="${tomcat.dist}">
      <fileset dir="res/install-win">
        <include name="INSTALLLICENSE"/>
        <include name="*.bmp"/>
        <include name="*.ico"/>
        <include name="*.xml"/>
      </fileset>
    </copy>
    <condition property="os.cmd.copy" value="copy" else="cp">
      <or>
        <os family="windows"/>
        <isset property="wine.ok"/>
      </or>
    </condition>
    <copy file="res/install-win/tomcat.nsi" tofile="${tomcat.dist}/tomcat.nsi" overwrite="true" encoding="ISO-8859-1">
      <filterset refid="version.filters"/>
      <filterset>
        <filter token="OS.CMD.COPY" value="${os.cmd.copy}"/>
      </filterset>
    </copy>
    <fixcrlf srcdir="${tomcat.dist}" eol="crlf" encoding="ISO-8859-1" fixlast="false">
      <patternset refid="text.files"/>
    </fixcrlf>
    <!-- Reproducible builds: consistent timestamps for installer files -->
    <touch datetime="${tstamp.file}" pattern="yyyy-MM-dd HH:mm:ss">
      <fileset dir="${tomcat.dist}"/>
    </touch>
  </target>

  <target name="-uninstaller-wine"
      if="${wine.ok}"
      unless="${skip.installer}">
     <exec dir="${tomcat.dist}" executable="wine" osfamily="unix">
      <arg value="${nsis.executable.windows}"/>
      <arg value="/DNSISDIR=${nsis.bin.home}"/>
      <arg value="/DUNINSTALLONLY"/>
      <arg value="/V2"/>
      <arg value="tomcat.nsi"/>
    </exec>
  </target>

  <target name="-uninstaller-makensis"
      if="nsis.executable.unix"
      unless="${skip.installer}">
    <echo message="Using makensis: ${nsis.executable.unix} version [${nsis.executable.unix.version}]"/>
    <exec dir="${tomcat.dist}" executable="${nsis.executable.unix}" osfamily="unix">
      <arg value="-DNSISDIR=${nsis.bin.home}"/>
      <arg value="-DUNINSTALLONLY"/>
      <arg value="-V2"/>
      <arg value="tomcat.nsi"/>
    </exec>
  </target>

  <target name="-uninstaller-build"
      depends="-installer-prep,-uninstaller-wine,-uninstaller-makensis"
      unless="${skip.installer}">
    <exec dir="${tomcat.dist}" executable="${nsis.executable.windows}" osfamily="windows">
      <arg value="/DNSISDIR=${nsis.bin.home}"/>
      <arg value="/DUNINSTALLONLY"/>
      <arg value="/V2"/>
      <arg value="tomcat.nsi"/>
    </exec>
  </target>

  <target name="-installer-wine"
      if="${wine.ok}"
      unless="${skip.installer}">
     <exec dir="${tomcat.dist}" executable="wine" osfamily="unix">
      <arg value="${nsis.executable.windows}"/>
      <arg value="/DNSISDIR=${nsis.bin.home}"/>
      <arg value="/V2"/>
      <arg value="tomcat.nsi"/>
    </exec>
  </target>

  <target name="-installer-makensis"
      if="nsis.executable.unix"
      unless="${skip.installer}">
    <echo message="Using makensis: ${nsis.executable.unix} version [${nsis.executable.unix.version}]"/>
    <exec dir="${tomcat.dist}" executable="${nsis.executable.unix}" osfamily="unix">
      <arg value="-DNSISDIR=${nsis.bin.home}"/>
      <arg value="-V2"/>
      <arg value="tomcat.nsi"/>
    </exec>
  </target>

  <target name="-installer-build"
      depends="-installer-prep,-installer-wine,-installer-makensis"
      unless="${skip.installer}">
    <exec dir="${tomcat.dist}" executable="${nsis.executable.windows}" osfamily="windows">
      <arg value="/DNSISDIR=${nsis.bin.home}"/>
      <arg value="/V2"/>
      <arg value="tomcat.nsi"/>
    </exec>
  </target>

  <target name="-file-jsign"
    depends="setup-jsign">
    <fail unless="file" />
    <fail unless="dir" />
    <fail unless="savedir" />
    <echo>Signing ${file} in ${dir}, using/saving signature in ${savedir}</echo>
    <!-- Copy pre-existing detached signature to signing directory -->
    <copy file="${savedir}/${file}.sig"
        todir="${dir}"
        failonerror="false"/>
    <!-- If the detached signature doesn't exist, this will sign the file  -->
    <!-- and create the detached signature. If the detached signature does -->
    <!-- exist it will be attached to the file.                            -->
    <jsign file="${dir}/${file}"
        storepass="${codesigning.storepass}"
        storetype="${codesigning.storetype}"
        keypass="${codesigning.keypass}"
        alias="${codesigning.alias}"
        alg="${codesigning.digest}"
        tsaurl="http://ts.ssl.com"
        tsmode="RFC3161"
        detached="true"/>
    <!-- Move detached signature to source tree -->
    <move file="${dir}/${file}.sig" todir="${savedir}"/>
    <!-- Reset timestamp of signed file -->
    <touch datetime="${tstamp.file}" pattern="yyyy-MM-dd HH:mm:ss">
      <fileset file="${dir}/${file}"/>
    </touch>
  </target>

  <target name="-uninstaller-jsign"
      if="${do.codesigning}"
      unless="${skip.installer}">
      <antcall target="-file-jsign" >
        <param name="dir" value="${tomcat.dist}" />
        <param name="file" value="Uninstall.exe" />
        <param name="savedir" value="res/install-win" />
      </antcall>
  </target>

  <target name="-installer-jsign"
      if="${do.codesigning}"
      unless="${skip.installer}">
      <antcall target="-file-jsign" >
        <param name="dir" value="${tomcat.dist}" />
        <param name="file" value="tomcat-installer.exe" />
        <param name="savedir" value="res/install-win" />
      </antcall>
  </target>

  <target name="installer"
      description="Builds and optionally signs the Windows installer"
      depends="-uninstaller-build,-uninstaller-jsign,-installer-build,-installer-jsign"
      unless="${skip.installer}">
    <move file="${tomcat.dist}/tomcat-installer.exe" tofile="${tomcat.release}/v${version}/bin/${final.name}.exe"/>
    <!-- .exe has changed so need to redo checksums and OpenPGP signature -->
    <delete file="${tomcat.release}/v${version}/bin/${final.name}.exe.asc"/>
    <delete file="${tomcat.release}/v${version}/bin/${final.name}.exe.sha512"/>
    <hashAndSign file="${tomcat.release}/v${version}/bin/${final.name}.exe"/>
  </target>

  <target name="-local-makensis-set-properties">
    <property environment="env"/>
    <condition property="scons.ok">
      <available file="scons" filepath="${env.PATH}"/>
    </condition>
    <condition property="local.makensis.ok">
      <isset property="scons.ok"/>
    </condition>
  </target>

  <target name="-local-makensis-check"
      depends="-local-makensis-set-properties"
      unless="${local.makensis.ok}">
    <echo message="Unable to build local version of makensis. All following checks must pass."/>
    <echo message="  Found scons on path: ${scons.ok}"/>
  </target>

  <target name="local-makensis"
      description="Builds a local version of makensis with the same version as the equivalent Windows executable"
      depends="-local-makensis-check"
      if="${local.makensis.ok}">
    <exec executable="scons" dir="${nsis.src.home}">
      <arg value="UNICODE=yes"/>
      <arg value="PREFIX=${nsis.bin.home}/Bin"/>
      <arg value="SKIPPLUGINS=all"/>
      <arg value="SKIPUTILS=all"/>
      <arg value="SKIPMISC=all"/>
      <arg value="NSIS_CONFIG_CONST_DATA_PATH=no"/>
      <arg value="VERSION=${nsis.version}"/>
      <arg value="install-compiler"/>
    </exec>
  </target>

  <target name="release-version-check">
    <!--FIXME: add version check for release once Java 22 has reasonable availability
    <fail message="Java version ${release.java.version} or newer is required for release (${java.version} is installed)">
      <condition>
        <not><javaversion atleast="${release.java.version}" /></not>
      </condition>
    </fail>-->
    <condition property="no-ffm">
      <not><javaversion atleast="${release.java.version}" /></not>
    </condition>
    <echo level="error" if:set="no-ffm">JAVA VERSION 22 OR NEWER IS REQUIRED FOR RELEASE</echo>
  </target>

  <target name="-pre-release-lone-target-check">
    <fail message="The pre-release target must be called all on its own. Specifically, you must run 'ant release' /after/ 'ant pre-release' in order to properly configure the build.">
      <condition>
        <not>
          <equals arg1="${ant.project.invoked-targets}" arg2="pre-release" />
        </not>
      </condition>
    </fail>
  </target>

  <target name="-pre-release-read-asf-username" unless="release.asfusername">
    <input message="Enter ASF username" addproperty="release.asfusername" defaultValue="${user.name}" />
  </target>

  <target name="pre-release" depends="release-version-check,-pre-release-lone-target-check, -pre-release-read-asf-username"
      description="Prepares for a release build by writing build.properties.release which contains information about the release-build environment.">
    <antversion property="antversion"/>
    <echo file="build.properties.release"># -----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# -----------------------------------------------------------------------------

# This file was auto-generated by the pre-release Ant target.

# Any unwanted settings may be over-ridden in a build.properties file located
# in the same directory as this file.

# Set the version-dev to "" (empty string) as this is not a development release.
version.dev=

# Ensure consistent timestamps for reproducible builds.
ant.tstamp.now.iso=${tstamp.iso.release}

# Enable insertion of detached signatures into the Windows installer.
do.codesigning=true

# Re-use the same GPG executable.
gpg.exec=${gpg.exec}

# Reproducible builds require the use of the build tools defined below. The
# vendors (where appropriate) and versions must match exactly for a reproducible
# build since this data is embedded in various files, particularly JAR file
# manifests, as part of the build process.
#
# Apache Ant:      ${ant.version}
#
# Java Name:       ${java.vm.name}
# Java Vendor:     ${java.vm.vendor}
# Java Version:    ${java.vm.version}

# The following is provided for information only. Builds will be repeatable
# whether or not the build environment is consistent with this information.
#
# OS:              ${os.arch} ${os.name} ${os.version}
# File encoding:   ${file.encoding}
#
# Release Manager: ${release.asfusername}
release-java-version=${java.vm.version}
release-ant-version=${antversion}
</echo>
    <echo file="res/maven/mvn.properties.release"># -----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# -----------------------------------------------------------------------------

# This file was auto-generated by the pre-release Ant target.

# Remove "-dev" from the version since this is not a development release.
maven.asf.release.deploy.version=${version.major}.${version.minor}.${version.build}${version.suffix}

# Re-use the same GPG executable.
gpg.exec=${gpg.exec}

# Set the user name to use to upload the artefacts to Nexus.
asf.ldap.username=${release.asfusername}
</echo>
    <!-- Update the changelog to include the release-manager's asfid and remove any rtext -->
    <replaceregexp file="webapps/docs/changelog.xml"
               encoding="UTF-8"
                 byline="true"
                  match="&lt;section name=&quot;Tomcat ${version.major}.${version.minor}.${version.build}${version.suffix} \([^)]*\).*&gt;"
                replace="&lt;section name=&quot;Tomcat ${version.major}.${version.minor}.${version.build}${version.suffix} \(${release.asfusername}\)&quot; rtext=&quot;&quot;&gt;" />

    <echo>=====

Configured for ${release.asfusername} to release Tomcat ${version.major}.${version.minor}.${version.build}${version.suffix} using Java ${java.vm.version} and ant ${antversion}

=====
</echo>
  </target>

  <target name="release"
    depends="clean,release-init,dist-deployer,installer,package-zip,package-winzip,package-tgz,package-deployer-zip,package-deployer-tgz,javadoc,package-docs-tgz,package-src-zip,package-src-tgz,package-src-jar"
    description="Create a Tomcat packaged distribution">

    <copy file="KEYS"
         todir="${tomcat.release}/v${version}"/>
    <copy file="RELEASE-NOTES"
         todir="${tomcat.release}/v${version}"
         encoding="ISO-8859-1">
      <filterset refid="version.filters"/>
    </copy>
    <copy file="res/welcome.main.html"
        tofile="${tomcat.release}/v${version}/README.html"
        encoding="UTF-8">
      <filterset refid="version.filters"/>
    </copy>
    <copy file="res/welcome.bin.html"
        tofile="${tomcat.release}/v${version}/bin/README.html"
        encoding="UTF-8">
      <filterset refid="version.filters"/>
    </copy>

    <mkdir dir="${tomcat.release}/v${version}/bin/embed" />
    <copy todir="${tomcat.release}/v${version}/bin/embed">
      <fileset dir="${tomcat.embed}">
        <include name="*.zip"/>
        <include name="*.tar.gz"/>
        <include name="*.asc"/>
        <include name="*.sha512"/>
      </fileset>
    </copy>

  </target>

  <!-- Sets properties only required for releases -->
  <target name="release-init" depends="release-version-check,gpg-init-1,gpg-init-2,gpg-init-3,compile" >
    <taskdef name="forceUtcTimeZone"
             classname="org.apache.tomcat.buildutil.ForceUtcTimeZone"
             classpath="${tomcat.classes}" />
    <forceUtcTimeZone />
  </target>

  <target name="gpg-init-1">
    <available file="${gpg.exec}" property="gpg.exec.available"/>
  </target>

  <target name="gpg-init-2" if="${gpg.exec.available}">
<echo>gpg.exec.available=${gpg.exec.available}</echo>
<echo>gpg.exec=${gpg.exec}</echo>
    <input addproperty="gpg.passphrase"><handler type="secure"/>Enter GPG passphrase
</input>
  </target>

  <!-- Test GPG by signing build.xml as a sample file. -->
  <target name="gpg-init-3" if="gpg.passphrase">
    <exec executable="${gpg.exec}"
          inputstring="${gpg.passphrase}"
          failonerror="true"
          discardOutput="true"
          logError="true">
      <arg value="--batch"/>
      <arg value="--pinentry-mode"/>
      <arg value="loopback"/>
      <arg value="--passphrase-fd"/>
      <arg value="0"/>
      <arg value="-o" /><!-- write to stdout -->
      <arg value="-" />
      <arg value="--detach-sign"/>
      <arg value="build.xml"/>
    </exec>
  </target>

  <!-- Packages the core zip distro -->
  <target name="package-zip" depends="dist-static">
    <fixcrlf srcdir="${tomcat.dist}" eol="crlf"
        encoding="ISO-8859-1" fixlast="false" >
      <patternset refid="text.files" />
    </fixcrlf>

    <zip zipfile="${tomcat.release}/v${version}/bin/${final.name}.zip"
         modificationtime="${tstamp.iso.release}"
         encoding="UTF8">
      <zipfileset file="${tomcat.dist}" fullpath="${final.name}"/>
      <zipfileset dir="${tomcat.dist}" prefix="${final.name}">
        <include name="bin/**"/>
        <include name="conf/**"/>
        <include name="logs/**"/>
        <include name="lib/**"/>
        <include name="webapps/**"/>
        <include name="work/**"/>
        <include name="temp/**"/>
        <include name="LICENSE"/>
        <include name="NOTICE"/>
        <include name="README.md"/>
        <include name="RELEASE-NOTES"/>
        <include name="RUNNING.txt"/>
        <include name="BUILDING.txt" />
        <include name="CONTRIBUTING.md"/>
        <exclude name="bin/service.bat"/>
        <exclude name="bin/x64/"/>
        <exclude name="bin/*.exe"/>
        <exclude name="bin/*.dll"/>
      </zipfileset>
    </zip>

    <hashAndSign file="${tomcat.release}/v${version}/bin/${final.name}.zip" />
  </target>

  <!-- Packages the core windows zip distros -->
  <target name="package-winzip" depends="dist-static">
    <fixcrlf srcdir="${tomcat.dist}" eol="crlf"
        encoding="ISO-8859-1" fixlast="false" >
      <patternset refid="text.files" />
    </fixcrlf>

    <!-- Windows x86 package -->
    <zip zipfile="${tomcat.release}/v${version}/bin/${final.name}-windows-x86.zip"
         modificationtime="${tstamp.iso.release}"
         encoding="UTF8">
      <zipfileset file="${tomcat.dist}" fullpath="${final.name}"/>
      <zipfileset dir="${tomcat.dist}" prefix="${final.name}">
        <include name="bin/**"/>
        <include name="conf/**"/>
        <include name="logs/**"/>
        <include name="lib/**"/>
        <include name="webapps/**"/>
        <include name="work/**"/>
        <include name="temp/**"/>
        <include name="LICENSE"/>
        <include name="NOTICE"/>
        <include name="README.md"/>
        <include name="RELEASE-NOTES"/>
        <include name="RUNNING.txt"/>
        <include name="BUILDING.txt" />
        <include name="CONTRIBUTING.md"/>
        <exclude name="bin/x64/"/>
        <exclude name="bin/commons-daemon-native.tar.gz"/>
        <exclude name="bin/tomcat-native.tar.gz"/>
      </zipfileset>

    </zip>
    <hashAndSign file="${tomcat.release}/v${version}/bin/${final.name}-windows-x86.zip" />

    <!-- Windows x64 package -->
    <zip zipfile="${tomcat.release}/v${version}/bin/${final.name}-windows-x64.zip"
         modificationtime="${tstamp.iso.release}"
         encoding="UTF8">
      <zipfileset file="${tomcat.dist}" fullpath="${final.name}"/>
      <zipfileset dir="${tomcat.dist}" prefix="${final.name}">
        <include name="bin/**"/>
        <include name="conf/**"/>
        <include name="logs/**"/>
        <include name="lib/**"/>
        <include name="webapps/**"/>
        <include name="work/**"/>
        <include name="temp/**"/>
        <include name="LICENSE"/>
        <include name="NOTICE"/>
        <include name="README.md"/>
        <include name="RELEASE-NOTES"/>
        <include name="RUNNING.txt"/>
        <include name="BUILDING.txt" />
        <include name="CONTRIBUTING.md"/>
        <exclude name="bin/x64/"/>
        <exclude name="bin/*.dll"/>
        <exclude name="bin/tomcat${version.major}.exe"/>
        <exclude name="bin/commons-daemon-native.tar.gz"/>
        <exclude name="bin/tomcat-native.tar.gz"/>
      </zipfileset>
      <zipfileset dir="${tomcat.dist}/bin/x64" prefix="${final.name}/bin">
        <include name="*.dll"/>
        <include name="*.exe"/>
      </zipfileset>
    </zip>
    <hashAndSign file="${tomcat.release}/v${version}/bin/${final.name}-windows-x64.zip" />
  </target>

  <!-- Packages the deployer distribution in zip format -->
  <target name="package-deployer-zip">
    <fixcrlf srcdir="${tomcat.dist}" eol="crlf"
        encoding="ISO-8859-1" fixlast="false" >
      <patternset refid="text.files" />
    </fixcrlf>
    <fixcrlf srcdir="${tomcat.deployer}" eol="crlf"
        encoding="ISO-8859-1" fixlast="false" >
      <patternset refid="text.files" />
    </fixcrlf>

    <zip zipfile="${tomcat.release}/v${version}/bin/${final.name}-deployer.zip"
         modificationtime="${tstamp.iso.release}"
         encoding="UTF8">
      <zipfileset file="${tomcat.deployer}" fullpath="${final.name}-deployer"/>
      <zipfileset dir="${tomcat.deployer}" prefix="${final.name}-deployer" includes="**" />
      <zipfileset dir="${tomcat.dist}" prefix="${final.name}-deployer" includes="LICENSE" />
      <zipfileset dir="${tomcat.dist}" prefix="${final.name}-deployer" includes="NOTICE" />
      <zipfileset dir="${tomcat.dist}" prefix="${final.name}-deployer" includes="README.md" />
      <zipfileset dir="${tomcat.dist}" prefix="${final.name}-deployer" includes="RELEASE-NOTES" />
    </zip>

    <hashAndSign file="${tomcat.release}/v${version}/bin/${final.name}-deployer.zip" />
  </target>

  <!-- Packages the core tar.gz distro -->
  <target name="package-tgz" depends="dist-static">
    <fixcrlf srcdir="${tomcat.dist}" eol="lf"
        encoding="ISO-8859-1" fixlast="false" >
      <patternset refid="text.files" />
    </fixcrlf>

    <!-- Reproducible builds: consistent timestamps for distributed files -->
    <touch datetime="${tstamp.file}" pattern="yyyy-MM-dd HH:mm:ss">
      <fileset dir="${tomcat.dist}"/>
    </touch>

    <tar longfile="gnu" compression="gzip"
         tarfile="${tomcat.release}/v${version}/bin/${final.name}.tar.gz">
      <tarfileset dir="${tomcat.dist}" dirmode="700" filemode="600" prefix="${final.name}">
        <include name="conf/**" />
      </tarfileset>
      <tarfileset dir="${tomcat.dist}" dirmode="750" filemode="640" prefix="${final.name}">
        <include name="bin/**" />
        <include name="lib/**" />
        <include name="logs/**" />
        <include name="temp/**" />
        <include name="webapps/**" />
        <include name="work/**" />
        <include name="LICENSE" />
        <include name="NOTICE" />
        <include name="README.md" />
        <include name="RELEASE-NOTES" />
        <include name="RUNNING.txt" />
        <include name="BUILDING.txt" />
        <include name="CONTRIBUTING.md"/>
        <exclude name="conf/**" />
        <exclude name="src/**" />
        <exclude name="bin/service.bat"/>
        <exclude name="bin/*.sh"/>
        <exclude name="bin/x64/"/>
        <exclude name="bin/*.exe"/>
        <exclude name="bin/*.dll"/>
      </tarfileset>
      <!-- These need to be added after the bin directory is added else the  -->
      <!-- bin directory will pick up the wrong permissions.                 -->
      <tarfileset dir="${tomcat.dist}" dirmode="750" filemode="750" prefix="${final.name}">
        <include name="bin/*.sh" />
      </tarfileset>
    </tar>

    <hashAndSign file="${tomcat.release}/v${version}/bin/${final.name}.tar.gz" />
  </target>

  <!-- Packages the deployer Tomcat distro in tar.gz format -->
  <target name="package-deployer-tgz">
    <fixcrlf srcdir="${tomcat.dist}" eol="lf"
        encoding="ISO-8859-1" fixlast="false" >
      <patternset refid="text.files" />
    </fixcrlf>
    <fixcrlf srcdir="${tomcat.deployer}" eol="lf"
        encoding="ISO-8859-1" fixlast="false" >
      <patternset refid="text.files" />
    </fixcrlf>

    <!-- Reproducible builds: consistent timestamps for distributed files -->
    <touch datetime="${tstamp.file}" pattern="yyyy-MM-dd HH:mm:ss">
      <fileset dir="${tomcat.dist}"/>
      <fileset dir="${tomcat.deployer}"/>
    </touch>

    <tar longfile="gnu" compression="gzip"
         tarfile="${tomcat.release}/v${version}/bin/${final.name}-deployer.tar.gz">
      <tarfileset dir="${tomcat.dist}" prefix="${final.name}-deployer">
        <include name="LICENSE" />
        <include name="NOTICE" />
        <include name="README.md" />
        <include name="RELEASE-NOTES" />
      </tarfileset>
      <tarfileset dir="${tomcat.deployer}" prefix="${final.name}-deployer">
        <include name="**" />
      </tarfileset>
    </tar>

    <hashAndSign file="${tomcat.release}/v${version}/bin/${final.name}-deployer.tar.gz" />
  </target>

  <!-- Packages the documentation distro in tar.gz format -->
  <target name="package-docs-tgz" depends="dist-static">
    <fixcrlf srcdir="${tomcat.dist}" eol="lf"
        encoding="ISO-8859-1" fixlast="false" >
      <patternset refid="text.files" />
    </fixcrlf>

    <!-- Reproducible builds: consistent timestamps for distributed files.   -->
    <!-- Javadocs need additional processing.                                -->
    <!-- 1. line endings vary between platforms for some files               -->
    <!-- 2. The contents of generated zip files don't have fixed timestamps  -->
    <!-- Process the zip files first as the resulting zip files will need    -->
    <!-- the last modified timestamp to be changed as well.                  -->
    <fixcrlf srcdir="${tomcat.dist}/webapps/docs" eol="lf"
        encoding="UTF-8" fixlast="false" >
      <include name="**/*.js" />
      <include name="**/element-list" />
    </fixcrlf>
    <taskdef name="repeatableArchive"
             classname="org.apache.tomcat.buildutil.RepeatableArchive"
             classpath="${tomcat.classes}" />
    <repeatableArchive datetime="${tstamp.file}" pattern="yyyy-MM-dd HH:mm:ss">
      <fileset dir="${tomcat.dist}/webapps/docs">
        <include name="**/*.zip"/>
      </fileset>
    </repeatableArchive>
    <touch datetime="${tstamp.file}" pattern="yyyy-MM-dd HH:mm:ss">
      <fileset dir="${tomcat.dist}"/>
    </touch>

    <tar longfile="gnu" compression="gzip"
         tarfile="${tomcat.release}/v${version}/bin/${final.name}-fulldocs.tar.gz">
      <tarfileset dir="${tomcat.dist}" prefix="tomcat-${version.major.minor}-doc">
        <include name="LICENSE" />
        <include name="NOTICE" />
        <include name="README.md" />
      </tarfileset>
      <tarfileset dir="${tomcat.dist}/webapps/docs" prefix="tomcat-${version.major.minor}-doc">
        <include name="**" />
      </tarfileset>
    </tar>

    <hashAndSign file="${tomcat.release}/v${version}/bin/${final.name}-fulldocs.tar.gz" />
  </target>

  <!-- Packages the source code distribution in zip format -->
  <target name="package-src-zip" depends="dist-source">
    <fixcrlf srcdir="${tomcat.dist}/src" eol="crlf"
        encoding="ISO-8859-1" fixlast="false" >
      <patternset refid="text.files"/>
      <include name="bin/*.bat" />
      <include name="bin/*.sh" />
      <include name=".travis/*.sh" />
      <include name="res/graal/*.sh" />
      <include name="res/openssl/*.sh" />
    </fixcrlf>

    <zip zipfile="${tomcat.release}/v${version}/src/${final-src.name}.zip"
         modificationtime="${tstamp.iso.release}"
         encoding="UTF8">
      <zipfileset file="${tomcat.dist}/src" fullpath="${final-src.name}" />
      <zipfileset dir="${tomcat.dist}/src" prefix="${final-src.name}" />
    </zip>

    <hashAndSign file="${tomcat.release}/v${version}/src/${final-src.name}.zip" />
  </target>

  <!-- Packages the source code distribution in tar.gz format -->
  <target name="package-src-tgz" depends="dist-source">
    <fixcrlf srcdir="${tomcat.dist}/src" eol="lf"
        encoding="ISO-8859-1" fixlast="false" >
      <patternset refid="text.files"/>
      <include name="bin/*.bat" />
      <include name="bin/*.sh" />
      <include name=".travis/*.sh" />
      <include name="res/graal/*.sh" />
      <include name="res/openssl/*.sh" />
    </fixcrlf>

    <!-- Reproducible builds: consistent timestamps for distributed files -->
    <touch datetime="${tstamp.file}" pattern="yyyy-MM-dd HH:mm:ss">
      <fileset dir="${tomcat.dist}"/>
    </touch>

    <tar longfile="gnu" compression="gzip"
         tarfile="${tomcat.release}/v${version}/src/${final-src.name}.tar.gz">
      <tarfileset dir="${tomcat.dist}/src" prefix="${final-src.name}" />
    </tar>
    <hashAndSign file="${tomcat.release}/v${version}/src/${final-src.name}.tar.gz" />
  </target>

  <!-- Packages the source code in JARs to match the binary JARs -->
  <target name="package-src-jar"
          depends="build-manifests,build-tomcat-jdbc-src">

    <mkdir dir="${tomcat.src.jars}" />

    <!-- Common Annotations JAR File -->
    <jarIt jarfile="${annotations-api-src.jar}"
      filesDir="java"
      filesId="files.annotations-api"
      manifest="${tomcat.manifests}/annotations-api.jar.manifest" />

    <!-- Servlet Implementation JAR File -->
    <jarIt jarfile="${servlet-api-src.jar}"
      filesDir="java"
      filesId="files.servlet-api"
      manifest="${tomcat.manifests}/servlet-api.jar.manifest"
      notice="${tomcat.manifests}/servlet-api.jar.notice"
      license="${tomcat.manifests}/servlet-api.jar.license" />

    <!-- JSP EL Implementation JAR File -->
    <jarIt jarfile="${el-api-src.jar}"
      filesDir="java"
      filesId="files.el-api"
      manifest="${tomcat.manifests}/el-api.jar.manifest" />

    <!-- JSP Implementation JAR File -->
    <jarIt jarfile="${jsp-api-src.jar}"
      filesDir="java"
      filesId="files.jsp-api"
      manifest="${tomcat.manifests}/jsp-api.jar.manifest"
      notice="${tomcat.manifests}/jsp-api.jar.notice"
      license="${tomcat.manifests}/jsp-api.jar.license" />

    <!-- WebSocket API JAR File -->
    <jarIt jarfile="${websocket-api-src.jar}"
      filesDir="java"
      filesId="files.websocket-api"
      manifest="${tomcat.manifests}/websocket-api.jar.manifest" />

    <!-- WebSocket Client API JAR File -->
    <jarIt jarfile="${websocket-client-api-src.jar}"
      filesDir="java"
      filesId="files.websocket-client-api"
      manifest="${tomcat.manifests}/websocket-client-api.jar.manifest" />

    <!-- JASPIC API JAR File -->
    <jarIt jarfile="${jaspic-api-src.jar}"
      filesDir="java"
      filesId="files.jaspic-api"
      manifest="${tomcat.manifests}/jaspic-api.jar.manifest"
      notice="${tomcat.manifests}/jaspic-api.jar.notice"
      license="${tomcat.manifests}/jaspic-api.jar.license" />

    <!-- Tomcat-juli JAR File -->
    <jarIt jarfile="${tomcat-juli-src.jar}"
      filesDir="java"
      filesId="files.tomcat-juli" />

    <!-- Bootstrap JAR File -->
    <jarIt jarfile="${bootstrap-src.jar}"
      filesDir="java"
      filesId="files.bootstrap"
      manifest="${tomcat.manifests}/bootstrap.jar.manifest" />

    <!-- Tomcat Util JAR File -->
    <jarIt jarfile="${tomcat-util-src.jar}"
      filesDir="java"
      filesId="files.tomcat-util" />

    <!-- Tomcat API JAR File -->
    <jarIt jarfile="${tomcat-api-src.jar}"
      filesDir="java"
      filesId="files.tomcat-api" />

    <!-- Tomcat Util Scan JAR File -->
    <jarIt jarfile="${tomcat-util-scan-src.jar}"
      filesDir="java"
      filesId="files.tomcat-util-scan" />

    <!-- JNI -->
    <jarIt jarfile="${tomcat-jni-src.jar}"
      filesDir="java"
      filesId="files.tomcat-jni" />

    <!-- Protocol handlers - Coyote -->
    <jarIt jarfile="${tomcat-coyote-src.jar}"
      filesDir="java"
      filesId="files.tomcat-coyote" />

    <!-- Protocol handlers - Coyote OpenSSL FFM -->
    <jarIt jarfile="${tomcat-coyote-ffm-src.jar}"
      filesDir="java"
      filesId="files.tomcat-coyote-ffm" />

    <!-- WebSocket implementation JAR File -->
    <jarIt jarfile="${tomcat-websocket-src.jar}"
      filesDir="java"
      filesId="files.tomcat-websocket" />

    <!-- Catalina GroupCom/Tribes JAR File -->
    <jarIt jarfile="${catalina-tribes-src.jar}"
      filesDir="java"
      filesId="files.catalina-tribes" />

    <!-- Catalina Main JAR File -->
    <jarIt jarfile="${catalina-src.jar}"
      filesDir="java"
      filesId="files.catalina" />

    <!-- Catalina Cluster/HA JAR File -->
    <jarIt jarfile="${catalina-ha-src.jar}"
      filesDir="java"
      filesId="files.catalina-ha" />

    <!-- Catalina SSI JAR File -->
    <jarIt jarfile="${catalina-ssi-src.jar}"
      filesDir="java"
      filesId="files.catalina-ssi" />

    <!-- Catalina Ant Tasks JAR File -->
    <jarIt jarfile="${catalina-ant-src.jar}"
      filesDir="java"
      filesId="files.catalina-ant" />

    <!-- Catalina Storeconfig JAR File -->
    <jarIt jarfile="${catalina-storeconfig-src.jar}"
      filesDir="java"
      filesId="files.catalina-storeconfig" />

    <!-- Jasper EL Implementation JAR File -->
    <jarIt jarfile="${jasper-el-src.jar}"
      filesDir="java"
      filesId="files.jasper-el" />

    <!-- Jasper Implementation JAR File -->
    <jarIt jarfile="${jasper-src.jar}"
      filesDir="java"
      filesId="files.jasper" />

    <!-- Repackaged DBCP 2 -->
    <jarIt jarfile="${tomcat-dbcp-src.jar}"
      filesDir="java"
      filesId="files.tomcat-dbcp" />

    <!-- jdbc-pool JAR File -->
    <copy file="${tomcat-jdbc-src.jar}" todir="${tomcat.src.jars}" />
  </target>

  <!-- ========================= Cleaning Targets ========================== -->

  <target name="clean"
          description="Delete the default output folders">
    <delete dir="${tomcat.output}" />
    <!-- Remove the copied catalina.properties -->
    <delete file="java/org/apache/catalina/startup/catalina.properties" />
    <ant antfile="${tomcat.jdbc.dir}/build.xml" dir="${tomcat.jdbc.dir}" inheritAll="false" target="clean">
      <property name="tomcat.pool" value="${tomcat.pool}" />
    </ant>
    <!-- remove jdbc-pool documentation -->
    <delete file="webapps/docs/jdbc-pool.xml"/>
  </target>


  <target name="clean-classes">
    <delete dir="${tomcat.classes}" />
    <delete dir="${test.classes}" />
  </target>

  <!-- ================ Download and dependency building =================== -->

  <target name="download-validate"
          description="Download components necessary to validate source"
          if="${execute.validate}">

    <antcall target="downloadfile">
      <param name="sourcefile" value="${checkstyle.loc}"/>
      <param name="destfile" value="${checkstyle.jar}"/>
      <param name="destdir" value="${base.path}"/>
      <param name="checksum.enabled" value="${checkstyle.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${checkstyle.checksum.algorithm}"/>
      <param name="checksum.value" value="${checkstyle.checksum.value}"/>
    </antcall>

  </target>

  <target name="download-compile"
          description="Download components necessary to compile"
          depends="setup-bnd">

    <!-- Download Commons Daemon -->
    <antcall target="downloadgz-2">
      <param name="sourcefile.1" value="${commons-daemon.bin.loc.1}"/>
      <param name="sourcefile.2" value="${commons-daemon.bin.loc.2}"/>
      <param name="destfile" value="${commons-daemon.jar}"/>
      <param name="checksum.enabled" value="${commons-daemon.bin.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${commons-daemon.bin.checksum.algorithm}"/>
      <param name="checksum.value" value="${commons-daemon.bin.checksum.value}"/>
    </antcall>

    <!-- Download JDT (Eclipse compiler) -->
    <antcall target="downloadfile-2">
      <param name="sourcefile.1" value="${jdt.loc.1}"/>
      <param name="sourcefile.2" value="${jdt.loc.2}"/>
      <param name="destfile" value="${jdt.jar}"/>
      <param name="destdir" value="${jdt.home}"/>
      <param name="checksum.enabled" value="${jdt.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${jdt.checksum.algorithm}"/>
      <param name="checksum.value" value="${jdt.checksum.value}"/>
    </antcall>

    <!-- Download WS API -->
    <antcall target="downloadfile">
      <param name="sourcefile" value="${jaxrpc-lib.loc}"/>
      <param name="destfile" value="${jaxrpc-lib.jar}"/>
      <param name="destdir" value="${jaxrpc-lib.home}"/>
      <param name="checksum.enabled" value="${jaxrpc-lib.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${jaxrpc-lib.checksum.algorithm}"/>
      <param name="checksum.value" value="${jaxrpc-lib.checksum.value}"/>
    </antcall>
    <antcall target="downloadfile">
      <param name="sourcefile" value="${wsdl4j-lib.loc}"/>
      <param name="destfile" value="${wsdl4j-lib.jar}"/>
      <param name="destdir" value="${wsdl4j-lib.home}"/>
      <param name="checksum.enabled" value="${wsdl4j-lib.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${wsdl4j-lib.checksum.algorithm}"/>
      <param name="checksum.value" value="${wsdl4j-lib.checksum.value}"/>
    </antcall>

    <!-- Tomcat Migration Tool for Jakarta EE -->
    <antcall target="downloadfile">
      <param name="sourcefile" value="${migration-lib.loc}"/>
      <param name="destfile" value="${migration-lib.jar}"/>
      <param name="destdir" value="${migration-lib.home}"/>
      <param name="checksum.enabled" value="${migration-lib.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${migration-lib.checksum.algorithm}"/>
      <param name="checksum.value" value="${migration-lib.checksum.value}"/>
    </antcall>

  </target>

  <target name="download-test-compile"
          description="Download additional components for the tests" >

    <antcall target="downloadfile">
      <param name="sourcefile" value="${junit.loc}"/>
      <param name="destfile" value="${junit.jar}"/>
      <param name="destdir" value="${junit.home}"/>
      <param name="checksum.enabled" value="${junit.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${junit.checksum.algorithm}"/>
      <param name="checksum.value" value="${junit.checksum.value}"/>
    </antcall>

    <antcall target="downloadfile">
      <param name="sourcefile" value="${hamcrest.loc}"/>
      <param name="destfile" value="${hamcrest.jar}"/>
      <param name="destdir" value="${hamcrest.home}"/>
      <param name="checksum.enabled" value="${hamcrest.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${hamcrest.checksum.algorithm}"/>
      <param name="checksum.value" value="${hamcrest.checksum.value}"/>
    </antcall>

    <antcall target="downloadfile">
      <param name="sourcefile" value="${easymock.loc}"/>
      <param name="destfile" value="${easymock.jar}"/>
      <param name="destdir" value="${easymock.home}"/>
      <param name="checksum.enabled" value="${easymock.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${easymock.checksum.algorithm}"/>
      <param name="checksum.value" value="${easymock.checksum.value}"/>
    </antcall>

    <antcall target="downloadfile">
      <param name="sourcefile" value="${objenesis.loc}"/>
      <param name="destfile" value="${objenesis.jar}"/>
      <param name="destdir" value="${objenesis.home}"/>
      <param name="checksum.enabled" value="${objenesis.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${objenesis.checksum.algorithm}"/>
      <param name="checksum.value" value="${objenesis.checksum.value}"/>
    </antcall>

    <antcall target="downloadfile">
      <param name="sourcefile" value="${bytebuddy.loc}"/>
      <param name="destfile" value="${bytebuddy.jar}"/>
      <param name="destdir" value="${bytebuddy.home}"/>
      <param name="checksum.enabled" value="${bytebuddy.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${bytebuddy.checksum.algorithm}"/>
      <param name="checksum.value" value="${bytebuddy.checksum.value}"/>
    </antcall>

    <antcall target="downloadfile">
      <param name="sourcefile" value="${unboundid.loc}"/>
      <param name="destfile" value="${unboundid.jar}"/>
      <param name="destdir" value="${unboundid.home}"/>
      <param name="checksum.enabled" value="${unboundid.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${unboundid.checksum.algorithm}"/>
      <param name="checksum.value" value="${unboundid.checksum.value}"/>
    </antcall>

    <antcall target="downloadfile">
      <param name="sourcefile" value="${derby.loc}"/>
      <param name="destfile" value="${derby.jar}"/>
      <param name="destdir" value="${derby.home}"/>
      <param name="checksum.enabled" value="${derby.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${derby.checksum.algorithm}"/>
      <param name="checksum.value" value="${derby.checksum.value}"/>
    </antcall>

    <antcall target="downloadfile">
      <param name="sourcefile" value="${derby-shared.loc}"/>
      <param name="destfile" value="${derby-shared.jar}"/>
      <param name="destdir" value="${derby.home}"/>
      <param name="checksum.enabled" value="${derby-shared.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${derby-shared.checksum.algorithm}"/>
      <param name="checksum.value" value="${derby-shared.checksum.value}"/>
    </antcall>

    <antcall target="downloadfile">
      <param name="sourcefile" value="${derby-tools.loc}"/>
      <param name="destfile" value="${derby-tools.jar}"/>
      <param name="destdir" value="${derby.home}"/>
      <param name="checksum.enabled" value="${derby-tools.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${derby-tools.checksum.algorithm}"/>
      <param name="checksum.value" value="${derby-tools.checksum.value}"/>
    </antcall>

  </target>

  <target name="download-jacoco"
          description="Download the Jacoco code coverage tool" >

    <antcall target="downloadzip">
      <param name="sourcefile" value="${jacoco.loc}"/>
      <param name="destfile" value="${jacoco.jar}"/>
      <param name="destdir" value="${jacoco.home}"/>
      <param name="checksum.enabled" value="${jacoco.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${jacoco.checksum.algorithm}"/>
      <param name="checksum.value" value="${jacoco.checksum.value}"/>
    </antcall>

  </target>

  <target name="setup-jacoco" depends="download-jacoco">
    <!-- Add JaCoCo tasks to project -->
    <path id="jacoco.classpath">
      <fileset file="${jacoco.jar}" />
    </path>

    <taskdef uri="antlib:org.jacoco.ant"
             resource="org/jacoco/ant/antlib.xml"
             classpathref="jacoco.classpath"
             />

  </target>


  <target name="download-spotbugs"
          if="${execute.spotbugs}"
          description="Download SpotBugs" >

    <antcall target="downloadgz">
      <param name="sourcefile" value="${spotbugs.loc}"/>
      <param name="destfile" value="${spotbugs.jar}"/>
      <param name="checksum.enabled" value="${spotbugs.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${spotbugs.checksum.algorithm}"/>
      <param name="checksum.value" value="${spotbugs.checksum.value}"/>
    </antcall>

  </target>

  <target name="download-dist"
          description="Download additional components for a distribution" >

    <antcall target="downloadfile-2">
      <param name="sourcefile.1" value="${tomcat-native.loc.1}"/>
      <param name="sourcefile.2" value="${tomcat-native.loc.2}"/>
      <param name="destfile" value="${tomcat-native.tar.gz}"/>
      <param name="destdir" value="${tomcat-native.home}"/>
      <param name="checksum.enabled" value="${tomcat-native.src.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${tomcat-native.src.checksum.algorithm}"/>
      <param name="checksum.value" value="${tomcat-native.src.checksum.value}"/>
    </antcall>

    <antcall target="downloadzip-2">
      <param name="sourcefile.1" value="${tomcat-native.win.1}"/>
      <param name="sourcefile.2" value="${tomcat-native.win.2}"/>
      <param name="destfile" value="${tomcat-native.home}/LICENSE"/>
      <param name="destdir" value="${tomcat-native.home}"/>
      <param name="checksum.enabled" value="${tomcat-native.win.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${tomcat-native.win.checksum.algorithm}"/>
      <param name="checksum.value" value="${tomcat-native.win.checksum.value}"/>
    </antcall>

    <antcall target="downloadfile-2">
      <param name="sourcefile.1" value="${commons-daemon.native.src.loc.1}"/>
      <param name="sourcefile.2" value="${commons-daemon.native.src.loc.2}"/>
      <param name="destfile" value="${commons-daemon.native.src.tgz}"/>
      <param name="destdir" value="${commons-daemon.home}"/>
      <param name="checksum.enabled" value="${commons-daemon.native.src.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${commons-daemon.native.src.checksum.algorithm}"/>
      <param name="checksum.value" value="${commons-daemon.native.src.checksum.value}"/>
    </antcall>

    <antcall target="downloadzip-2">
      <param name="sourcefile.1" value="${commons-daemon.native.win.loc.1}"/>
      <param name="sourcefile.2" value="${commons-daemon.native.win.loc.2}"/>
      <param name="destfile" value="${commons-daemon.native.win.mgr.exe}"/>
      <param name="destdir" value="${commons-daemon.native.win.home}"/>
      <param name="checksum.enabled" value="${commons-daemon.native.win.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${commons-daemon.native.win.checksum.algorithm}"/>
      <param name="checksum.value" value="${commons-daemon.native.win.checksum.value}"/>
    </antcall>

    <antcall target="downloadzip">
      <param name="sourcefile" value="${nsis.bin.loc}"/>
      <param name="destfile" value="${nsis.executable.windows}"/>
      <param name="destdir" value="${nsis.bin.home}/.."/>
      <param name="checksum.enabled" value="${nsis.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${nsis.bin.checksum.algorithm}"/>
      <param name="checksum.value" value="${nsis.bin.checksum.value}"/>
    </antcall>

    <antcall target="downloadbz2">
      <param name="sourcefile" value="${nsis.src.loc}"/>
      <param name="destfile" value="${nsis.src.home}/INSTALL"/>
      <param name="destdir" value="${nsis.src.home}/.."/>
      <param name="checksum.enabled" value="${nsis.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${nsis.src.checksum.algorithm}"/>
      <param name="checksum.value" value="${nsis.src.checksum.value}"/>
    </antcall>

  </target>

  <!-- =============== Utility Targets to support downloads ================ -->

  <target name="setproxy" if="${proxy.use}">
    <setproxy proxyhost="${proxy.host}" proxyport="${proxy.port}"
              proxyuser="${proxy.user}" proxypassword="${proxy.password}" />
    <echo message="Using ${proxy.host}:${proxy.port} to download ${sourcefile}"/>
  </target>

  <target name="testexist">
    <echo message="Testing  for ${destfile}"/>
    <available file="${destfile}" property="exist"/>
  </target>

  <macrodef name="verifyChecksum">
    <attribute name="file" />
    <attribute name="name" default="@{file}"/>
    <attribute name="enabled" />
    <attribute name="algorithm" />
    <attribute name="value" />
    <sequential>
      <local name="name" />
      <basename property="name" file="@{name}" />
      <sequential if:true="@{enabled}">
        <local name="check.md5" />
        <local name="check.sha1" />
        <local name="check.sha256" />
        <local name="check.sha384" />
        <local name="check.sha512" />
        <local name="value.md5" />
        <local name="value.sha1" />
        <local name="value.sha256" />
        <local name="value.sha384" />
        <local name="value.sha512" />
        <local name="check.success" />
        <condition property="check.md5">
          <or>
            <equals arg1="@{algorithm}" arg2="MD5" />
            <equals arg1="@{algorithm}" arg2="MD5|SHA-1" />
          </or>
        </condition>
        <condition property="check.sha1">
          <or>
            <equals arg1="@{algorithm}" arg2="SHA-1" />
            <equals arg1="@{algorithm}" arg2="MD5|SHA-1" />
          </or>
        </condition>
        <condition property="check.sha256">
          <equals arg1="@{algorithm}" arg2="SHA-256" />
        </condition>
        <condition property="check.sha384">
          <equals arg1="@{algorithm}" arg2="SHA-384" />
        </condition>
        <condition property="check.sha512">
          <equals arg1="@{algorithm}" arg2="SHA-512" />
        </condition>
        <!-- Check that any checksum algorithm is selected -->
        <fail message="Unknown algorithm: @{algorithm}">
          <condition>
            <not>
              <or>
                <equals arg1="${check.md5}" arg2="true" />
                <equals arg1="${check.sha1}" arg2="true" />
                <equals arg1="${check.sha256}" arg2="true" />
                <equals arg1="${check.sha384}" arg2="true" />
                <equals arg1="${check.sha512}" arg2="true" />
              </or>
            </not>
          </condition>
        </fail>
        <!-- Calculate requested checksums -->
        <checksum file="@{file}" if:true="${check.md5}" property="value.md5" algorithm="MD5" />
        <checksum file="@{file}" if:true="${check.sha1}" property="value.sha1" algorithm="SHA-1" />
        <checksum file="@{file}" if:true="${check.sha256}" property="value.sha256" algorithm="SHA-256" />
        <checksum file="@{file}" if:true="${check.sha384}" property="value.sha384" algorithm="SHA-384" />
        <checksum file="@{file}" if:true="${check.sha512}" property="value.sha512" algorithm="SHA-512" />
        <!-- Check actual checksum value -->
        <condition property="check.success">
          <or>
            <and>
              <equals arg1="@{algorithm}" arg2="MD5" />
              <equals arg1="@{value}" arg2="${value.md5}" />
            </and>
            <and>
              <equals arg1="@{algorithm}" arg2="SHA-1" />
              <equals arg1="@{value}" arg2="${value.sha1}" />
            </and>
            <and>
              <equals arg1="@{algorithm}" arg2="MD5|SHA-1" />
              <equals arg1="@{value}" arg2="${value.md5}|${value.sha1}" />
            </and>
            <and>
              <equals arg1="@{algorithm}" arg2="SHA-256" />
              <equals arg1="@{value}" arg2="${value.sha256}" />
            </and>
            <and>
              <equals arg1="@{algorithm}" arg2="SHA-384" />
              <equals arg1="@{value}" arg2="${value.sha384}" />
            </and>
            <and>
              <equals arg1="@{algorithm}" arg2="SHA-512" />
              <equals arg1="@{value}" arg2="${value.sha512}" />
            </and>
          </or>
        </condition>
        <!-- Fail or display a success message -->
        <sequential unless:true="${check.success}">
          <!-- Generate checksums for an error message -->
          <checksum file="@{file}" unless:set="value.md5" property="value.md5" algorithm="MD5" />
          <checksum file="@{file}" unless:set="value.sha1" property="value.sha1" algorithm="SHA-1" />
          <checksum file="@{file}" unless:set="value.sha256" property="value.sha256" algorithm="SHA-256" />
          <checksum file="@{file}" unless:set="value.sha384" property="value.sha384" algorithm="SHA-384" />
          <checksum file="@{file}" unless:set="value.sha512" property="value.sha512" algorithm="SHA-512" />
          <fail>
  Checksum check failure for ${name} (@{file}).
  Algorithm: @{algorithm}
  Expected value: @{value}
  Actual values:
  SHA-512: ${value.sha512}
  SHA-384: ${value.sha384}
  SHA-256: ${value.sha256}
  SHA-1: ${value.sha1}
  MD5: ${value.md5}
          </fail>
        </sequential>
        <echo level="info" message="Checksum check for ${name}, algorithm @{algorithm}: OK" />
      </sequential>
      <echo unless:true="@{enabled}" message="WARNING: Checksum verification is disabled for ${name}"/>
    </sequential>
  </macrodef>

  <target name="downloadgz" unless="exist" if="${execute.download}" depends="testexist,setproxy">
    <!-- Download and extract the package -->
    <local name="temp.file"/>
    <mkdir dir="${base.path}"/>
    <tempfile property="temp.file" destdir="${base.path}" prefix="download-"/>
    <get src="${sourcefile}" httpusecaches="${trydownload.httpusecaches}" dest="${temp.file}.tar.gz" />
    <verifyChecksum
      enabled="${checksum.enabled}"
      algorithm="${checksum.algorithm}" value="${checksum.value}"
      file="${temp.file}.tar.gz" name="${sourcefile}" />

    <gunzip src="${temp.file}.tar.gz" dest="${temp.file}.tar"/>
    <untar src="${temp.file}.tar" dest="${base.path}"/>
    <delete file="${temp.file}.tar"/>
    <delete file="${temp.file}.tar.gz"/>
  </target>

  <target name="downloadgz-2" unless="exist" if="${execute.download}" depends="testexist">
    <!-- Download and extract the package from the two alternative locations -->
    <local name="temp.file"/>
    <mkdir dir="${base.path}"/>
    <tempfile property="temp.file" destdir="${base.path}" prefix="download-"/>
    <antcall target="trydownload">
      <param name="sourcefile" value="${sourcefile.1}" />
      <param name="destfile" value="${temp.file}.tar.gz" />
    </antcall>
    <antcall target="trydownload">
      <param name="sourcefile" value="${sourcefile.2}" />
      <param name="destfile" value="${temp.file}.tar.gz" />
    </antcall>

    <verifyChecksum
      enabled="${checksum.enabled}"
      algorithm="${checksum.algorithm}" value="${checksum.value}"
      file="${temp.file}.tar.gz" name="${sourcefile.1}" />

    <gunzip src="${temp.file}.tar.gz" dest="${temp.file}.tar"/>
    <untar src="${temp.file}.tar" dest="${base.path}"/>
    <delete file="${temp.file}.tar"/>
    <delete file="${temp.file}.tar.gz"/>
  </target>

  <target name="downloadbz2" unless="exist" if="${execute.download}" depends="testexist,setproxy">
    <!-- Download and extract the package -->
    <local name="temp.file"/>
    <mkdir dir="${base.path}"/>
    <tempfile property="temp.file" destdir="${base.path}" prefix="download-"/>
    <get src="${sourcefile}" httpusecaches="${trydownload.httpusecaches}" dest="${temp.file}.tar.bz2" />
    <verifyChecksum
      enabled="${checksum.enabled}"
      algorithm="${checksum.algorithm}" value="${checksum.value}"
      file="${temp.file}.tar.bz2" name="${sourcefile}" />

    <bunzip2 src="${temp.file}.tar.bz2" dest="${temp.file}.tar"/>
    <untar src="${temp.file}.tar" dest="${base.path}"/>
    <delete file="${temp.file}.tar"/>
    <delete file="${temp.file}.tar.bz2"/>
  </target>

  <target name="downloadzip" unless="exist" if="${execute.download}" depends="testexist,setproxy">
    <!-- Download and extract the package -->
    <local name="temp.file"/>
    <mkdir dir="${base.path}"/>
    <tempfile property="temp.file" destdir="${base.path}" prefix="download-" suffix=".zip"/>
    <get src="${sourcefile}" httpusecaches="${trydownload.httpusecaches}" dest="${temp.file}"/>
    <verifyChecksum
      enabled="${checksum.enabled}"
      algorithm="${checksum.algorithm}" value="${checksum.value}"
      file="${temp.file}" name="${sourcefile}" />

    <mkdir dir="${destdir}"/>
    <unzip src="${temp.file}" dest="${destdir}"/>
    <delete file="${temp.file}"/>
  </target>

  <target name="downloadzip-2" unless="exist" if="${execute.download}" depends="testexist">
    <!-- Download and extract the package from the two alternative locations -->
    <local name="temp.file"/>
    <mkdir dir="${base.path}"/>
    <tempfile property="temp.file" destdir="${base.path}" prefix="download-" suffix=".zip"/>
    <antcall target="trydownload">
      <param name="sourcefile" value="${sourcefile.1}" />
      <param name="destfile" value="${temp.file}" />
    </antcall>
    <antcall target="trydownload">
      <param name="sourcefile" value="${sourcefile.2}" />
      <param name="destfile" value="${temp.file}" />
    </antcall>

    <verifyChecksum
      enabled="${checksum.enabled}"
      algorithm="${checksum.algorithm}" value="${checksum.value}"
      file="${temp.file}" name="${sourcefile.1}" />

    <mkdir dir="${destdir}" />
    <unzip src="${temp.file}" dest="${destdir}"/>
    <delete file="${temp.file}"/>
  </target>

  <target name="downloadfile" unless="exist" if="${execute.download}" depends="testexist,setproxy">
    <!-- Download the file -->
    <local name="temp.file"/>
    <mkdir dir="${base.path}"/>
    <tempfile property="temp.file" destdir="${base.path}" prefix="download-" suffix=".tmp"/>
    <get src="${sourcefile}" httpusecaches="${trydownload.httpusecaches}" dest="${temp.file}"/>
    <verifyChecksum
      enabled="${checksum.enabled}"
      algorithm="${checksum.algorithm}" value="${checksum.value}"
      file="${temp.file}" name="${destfile}" />

    <mkdir dir="${destdir}"/>
    <move file="${temp.file}" tofile="${destfile}"/>
  </target>

  <target name="downloadfile-2" unless="exist" if="${execute.download}" depends="testexist">
    <!-- Download the file from the two alternative locations -->
    <local name="temp.file"/>
    <mkdir dir="${base.path}"/>
    <tempfile property="temp.file" destdir="${base.path}" prefix="download-" suffix=".tmp"/>

    <antcall target="trydownload">
      <param name="sourcefile" value="${sourcefile.1}" />
      <param name="destfile" value="${temp.file}" />
    </antcall>

    <antcall target="trydownload">
      <param name="sourcefile" value="${sourcefile.2}" />
      <param name="destfile" value="${temp.file}" />
    </antcall>

    <available file="${temp.file}" property="exist"/>
    <fail unless="exist" message="Failed to download [${destfile}]. All download sources are unavailable." />

    <verifyChecksum
      enabled="${checksum.enabled}"
      algorithm="${checksum.algorithm}" value="${checksum.value}"
      file="${temp.file}" name="${destfile}" />

    <mkdir dir="${destdir}"/>
    <move file="${temp.file}" tofile="${destfile}"/>
  </target>

  <target name="trydownload.check" depends="setproxy">
    <condition property="trydownload.run">
      <and>
        <not>
          <available file="${destfile}" />
        </not>
        <http url="${sourcefile}" />
      </and>
    </condition>
  </target>

  <target name="trydownload" if="trydownload.run" depends="trydownload.check">
    <!-- Downloads a file if not yet downloaded and the source URL is available -->
    <get src="${sourcefile}" httpusecaches="${trydownload.httpusecaches}" dest="${destfile}" />
  </target>

  <!-- ============================ IDE Support ============================ -->

  <!-- ============================ Eclipse ================================ -->

  <target name="ide-eclipse"
          depends="download-compile, download-test-compile"
          description="Prepares the source tree to be built in Eclipse">

    <!-- Copy the sample project files into the root directory -->
    <copy file="${tomcat.home}/res/ide-support/eclipse/eclipse.project" tofile="${tomcat.home}/.project"/>
    <copy file="${tomcat.home}/res/ide-support/eclipse/eclipse.classpath" tofile="${tomcat.home}/.classpath">
      <filterset refid="classpath.filters"/>
      <filterset refid="version.filters"/>
    </copy>

    <!-- Copy compiler settings file -->
    <mkdir dir="${tomcat.home}/.settings"/>
    <copy file="${tomcat.home}/res/ide-support/eclipse/org.eclipse.jdt.core.prefs.properties" tofile="${tomcat.home}/.settings/org.eclipse.jdt.core.prefs">
      <filterset refid="version.filters"/>
    </copy>

    <echo>Eclipse project files created.
Read the Building page on the Apache Tomcat documentation site for details on how to configure your Eclipse workspace.</echo>
  </target>

  <!-- ============================ IntelliJ IDEA=========================== -->

  <target name="ide-intellij"
          depends="download-compile, download-test-compile, deploy"
          description="Creates project directory .idea for IntelliJ IDEA">

    <copy todir="${tomcat.home}/.idea" overwrite="true">
      <fileset dir="${tomcat.home}/res/ide-support/idea"/>
      <filterset refid="classpath.filters"/>
      <filterset refid="version.filters"/>
    </copy>

    <mkdir dir="${tomcat.home}/lib"/>

    <echo>IntelliJ IDEA project directory created.

The SDK was set to &quot;${build.java.version}&quot; so make sure that your IDE has an SDK with that name,
or update the Project Settings accordingly. Choose [File &gt; Project Structure] to open the settings dialog
and set the SDK level, language level, etc. as needed.

Some folders have been excluded by default as they require the latest SDK version and enabling of preview
features. You can remove or comment out the exclusions to enable the directories in the .idea/tomcat.iml
file, or via the IDEA UI by right-clicking folders, and choosing [Mark Directory as &gt; Cancel Exclusion]</echo>
  </target>

  <!-- ============================ NetBeans =============================== -->

  <target name="ide-netbeans"
          depends="-ide-netbeans-protect,-ide-netbeans-create"
          description="Create NetBeans project files only if none exist">
  </target>

  <target name="-ide-netbeans-protect"
          if="tomcat-nb.home.exists"
          depends="-ide-netbeans-check">
    <!-- Protect existing NetBeans project files -->
    <echo>NetBeans project files already exist and have been protected!
Use the "ide-netbeans-replace" target if you wish to overwrite them.</echo>
  </target>

  <target name="-ide-netbeans-check">
    <!-- protect existing files if the NetBeans project directory exists  -->
    <condition property="tomcat-nb.home.exists">
        <available file="${tomcat-nb.home}" type="dir"/>
    </condition>
  </target>

  <target name="ide-netbeans-replace" depends="-ide-netbeans-create">
    <!-- Bypass protection of any existing NetBeans project files -->
  </target>

  <target name="-ide-netbeans-create"
          unless="tomcat-nb.home.exists">
    <!-- Unconditionally create or overwrite default NetBeans project files -->
    <property name="tomcat-nb.dist" value="${tomcat.home}/res/ide-support/netbeans" />
    <mkdir dir="${tomcat-nb.home}/"/>
    <copy todir="${tomcat-nb.home}" overwrite="true">
      <fileset dir="${tomcat-nb.dist}"/>
      <filterset refid="version.filters" />
      <filterset refid="classpath.filters"/>
    </copy>
    <echo>NetBeans project files created.
Read the Building page on the Apache Tomcat documentation site for details on how to customise your NetBeans project.</echo>
  </target>


  <!-- ======================= Macros, Taskdefs etc ======================== -->

  <target name="download-jsign" >
    <!-- Download jsign -->
    <antcall target="downloadfile">
      <param name="sourcefile" value="${jsign.loc}"/>
      <param name="destfile" value="${jsign.jar}"/>
      <param name="destdir" value="${jsign.home}"/>
      <param name="checksum.enabled" value="${jsign.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${jsign.checksum.algorithm}"/>
      <param name="checksum.value" value="${jsign.checksum.value}"/>
    </antcall>
  </target>

  <target name="setup-jsign" depends="download-jsign">
    <!-- Add jsign tasks to project -->
    <path id="jsign.classpath">
      <fileset file="${jsign.jar}" />
    </path>

    <taskdef name="jsign" classname="net.jsign.JsignTask" classpathref="jsign.classpath" />
  </target>

  <target name="download-bnd" >
    <!-- Download bnd -->
    <antcall target="downloadfile">
      <param name="sourcefile" value="${bnd.loc}"/>
      <param name="destfile" value="${bnd.jar}"/>
      <param name="destdir" value="${bnd.home}"/>
      <param name="checksum.enabled" value="${bnd.checksum.enabled}"/>
      <param name="checksum.algorithm" value="${bnd.checksum.algorithm}"/>
      <param name="checksum.value" value="${bnd.checksum.value}"/>
    </antcall>
  </target>

  <target name="setup-bnd" depends="download-bnd" unless="${skip.build.java.version}">
    <!-- Add bnd tasks to project -->
    <path id="bnd.classpath">
      <fileset file="${bnd.jar}" />
    </path>

    <taskdef resource="aQute/bnd/ant/taskdef.properties" classpathref="bnd.classpath" />
  </target>

  <macrodef name="jarIt" description="utility macro for standard JAR packaging">
    <attribute name="jarfile"
               description="the name of the JAR file to create"/>
    <attribute name="filesDir"
               description="the directory from which to obtain the files "/>
    <attribute name="filesId"
               description="the patternset id of the files to use"/>
    <attribute name="manifest" description="the manifest file use"
               default="${tomcat.manifests}/default.manifest" />
    <attribute name="notice" description="the LICENSE file to use"
               default="${tomcat.manifests}/default.notice" />
    <attribute name="license" description="the NOTICE file to use"
               default="${tomcat.manifests}/default.license" />
    <attribute name="meta-inf" description="additional contents for META-INF"
               default="${tomcat.manifests}/default" />
    <attribute name="addOSGi" description="generate OSGi metadata"
               default="false" />
    <attribute name="addGraal" description="add Graal resource/reflection files if set"
               default="false" />
    <attribute name="graalPrefix" description="Graal resource/reflection location prefix (group_id/artifact_id)"
               default="" />
    <attribute name="graalFiles" description="Graal resource/reflection file location"
               default="" />
    <attribute name="libs" description="libraries to use for bnd classpath analysis relative to ${tomcat.output}"
               default="build/lib/*.jar,build/bin/tomcat-juli.jar" />
    <sequential>
      <local name="jar.uptodate"/>
      <uptodate property="jar.uptodate" targetfile="@{jarfile}" >
        <srcfiles dir="@{filesDir}">
          <patternset refid="@{filesId}"/>
          <!-- Javadoc exclusions -->
          <exclude name="**/package.html" />
        </srcfiles>
        <srcfiles dir="@{meta-inf}" excludes=".gitignore" />
        <srcfiles file="@{notice}" />
        <srcfiles file="@{license}" />
      </uptodate>
      <sequential unless:true="${jar.uptodate}">
        <jar jarfile="@{jarfile}"
             manifest="@{manifest}"
             modificationtime="${tstamp.iso.release}">
          <fileset dir="@{filesDir}">
            <patternset refid="@{filesId}"/>
            <!-- Javadoc exclusions -->
            <exclude name="**/package.html" />
          </fileset>
          <zipfileset dir="@{meta-inf}" prefix="META-INF/"
                      excludes=".gitignore" />
          <zipfileset file="@{notice}" fullpath="META-INF/NOTICE" />
          <zipfileset file="@{license}" fullpath="META-INF/LICENSE" />
        </jar>
        <antcall target="add-osgi" >
          <param name="jarfile" value="@{jarfile}" />
          <param name="addOSGi" value="@{addOSGi}" />
          <param name="libs" value="@{libs}" />
        </antcall>
        <antcall target="add-graal">
          <param name="jarfile" value="@{jarfile}" />
          <param name="addGraal" value="@{addGraal}" />
          <param name="graalFiles" value="@{graalFiles}" />
          <param name="graalPrefix" value="@{graalPrefix}" />
        </antcall>
      </sequential>
    </sequential>
  </macrodef>

  <target name="add-osgi" if="${addOSGi}" unless="${skip.build.java.version}" >
    <echo message="add-osgi ${jarfile} ${addOSGi}"></echo>
    <local name="filename"/>
    <basename property="filename" file="${jarfile}"/>
    <bnd
      basedir="${basedir}"
      output="${jarfile}.tmp"
    >
      <classpath>
        <pathelement location="${bnd.jar}"/>
        <fileset dir="${tomcat.output}" includes="${libs}" excludes="build/lib/tomcat-i18n-*.jar" />
      </classpath>
      <bndfiles>
        <pathelement location="${tomcat.bnd}/${filename}.tmp.bnd"/>
      </bndfiles>
    </bnd>
    <delete file="${jarfile}" />
    <move file="${jarfile}.tmp" tofile="${jarfile}" />
  </target>

  <target name="add-graal" if="${addGraal}">
    <echo message="add-graal  ${addGraal} ${jarfile} ${graalFiles} ${graalPrefix}"></echo>
    <!-- Reproducible builds: consistent timestamps for graal files -->
    <copy todir="${tomcat.graal}/${graalPrefix}">
      <fileset dir="${basedir}/${graalFiles}" />
    </copy>
    <!-- Reproducible builds: consistent line endings  for graal files -->
    <fixcrlf srcdir="${tomcat.graal}/${graalPrefix}" eol="lf"
        encoding="ISO-8859-1" fixlast="false" />
    <zip destfile="${jarfile}" update="true" filesonly="true"
         modificationtime="${tstamp.iso.release}"
         encoding="UTF8">
      <zipfileset dir="${tomcat.graal}/${graalPrefix}" prefix="META-INF/native-image/${graalPrefix}" includes="*.*"/>
    </zip>
  </target>

  <!-- Macro, used to create checksum and signature files  -->
  <!-- Requires 'file' as a parameter. -->
  <macrodef name="hashAndSign">
    <attribute name="file" />
    <sequential>
      <local name="filename" />
      <local name="sha512value" />

      <basename file="@{file}" property="filename" />
      <checksum algorithm="SHA-512" file="@{file}" property="sha512value" />

      <echo file="@{file}.sha512" message="${sha512value}${md5sum.binary-prefix}${filename}" />

      <antcall target="sign" >
        <param name="file" value="@{file}" />
      </antcall>
    </sequential>
  </macrodef>

  <!-- Helper target, used to create a detached ascii OpenPGP signature.     -->
  <!-- Uses GPG with default key. Requires 'file' as a parameter. Only       -->
  <!-- executes if gpg passphrase is set which is only set when using the    -->
  <!-- release target.                                                       -->
  <target name="sign" if="gpg.passphrase">
    <fail unless="file" />
    <exec executable="${gpg.exec}" failonerror="true"
          inputstring="${gpg.passphrase}">
      <arg value="--batch"/>
      <arg value="--pinentry-mode"/>
      <arg value="loopback"/>
      <arg value="--passphrase-fd"/>
      <arg value="0"/>
      <arg value="-a"/>
      <arg value="-b"/>
      <arg value="${file}"/>
    </exec>
  </target>

  <macrodef name="printfile">
    <attribute name="file" />

    <sequential>
      <local name="contents" />
      <loadfile property="contents" srcfile="@{file}" quiet="true" failonerror="false" />
      <property name="contents" value="(missing file)" /><!-- Establish default value -->
      <echo>${contents}</echo>
    </sequential>
  </macrodef>

  <macrodef name="get-release-hash">
    <attribute name="basefile" />
    <attribute name="src-or-bin" />

    <sequential>
      <local name="success" />

      <!-- Release hashes can be either 'released' or staged-for-release -->
      <!-- First, try to find a released version hash. -->
      <antcall target="trydownload">
        <param name="sourcefile" value="https://dist.apache.org/repos/dist/release/tomcat/tomcat-${version.major}/v${version}/@{src-or-bin}/@{basefile}.sha512" />
        <param name="destfile" value="${tomcat.release.verify}/@{basefile}.sha512" />
      </antcall>
      <!-- If necessary, try to find a dev version hash. -->
      <antcall target="trydownload">
        <param name="sourcefile" value="https://dist.apache.org/repos/dist/dev/tomcat/tomcat-${version.major}/v${version}/@{src-or-bin}/@{basefile}.sha512" />
        <param name="destfile" value="${tomcat.release.verify}/@{basefile}.sha512" />
      </antcall>

      <condition property="success">
        <or>
          <available file="${tomcat.release.verify}/@{basefile}.sha512" />
          <and>
            <contains string="${version}" substring="11.0." /><!-- Super hack -->
            <contains string="@{basefile}" substring="x86" />
          </and>
        </or>
      </condition>

      <fail unless="success">
Unable to locate release hash for @{basefile}
</fail>
    </sequential>
  </macrodef>

  <macrodef name="compare-hashes">
    <attribute name="basefile" />
    <attribute name="num" />
    <attribute name="src-or-bin" />

    <sequential>
<!--
      <echo>Comparing hash files output/release/v${version}/@{src-or-bin}/@{basefile}.sha512 ${tomcat.release.verify}/@{basefile}.sha512</echo>
-->
      <condition property="reproducible-@{num}">
        <filesmatch file1="output/release/v${version}/@{src-or-bin}/@{basefile}.sha512"
                    file2="${tomcat.release.verify}/@{basefile}.sha512"/>
      </condition>
      <echo if:set="reproducible-@{num}">Signature MATCH for @{src-or-bin}/@{basefile}</echo>
      <echo unless:set="reproducible-@{num}">
Signature mismatch for @{src-or-bin}/@{basefile}:
  </echo>
      <printfile unless:set="reproducible-@{num}" file="output/release/v${version}/@{src-or-bin}/@{basefile}.sha512" />
      <printfile unless:set="reproducible-@{num}" file="${tomcat.release.verify}/@{basefile}.sha512" />
    </sequential>
  </macrodef>

  <target name="verify-release" depends="-check-release-toolchain-versions, -require-release-toolchain-versions" description="Verifies a release build against published hashes.">

    <available property="released" file="build.properties.release" />
    <fail unless="released">

This does not appear to be a copy of a released tag; no build.properties.release file exists.
</fail>
    <available property="built" file="output/release/v${version}/bin/${final.name}.tar.gz" />
    <fail unless="built">

It appears there are no build artifacts to verify. Please run 'ant release' first.
</fail>
    <delete dir="${tomcat.release.verify}" />
    <mkdir dir="${tomcat.release.verify}" />
    <get-release-hash src-or-bin="bin" basefile="${final.name}-deployer.tar.gz" />
    <get-release-hash src-or-bin="bin" basefile="${final.name}-deployer.zip" />
    <get-release-hash src-or-bin="bin" basefile="${final.name}-fulldocs.tar.gz" />
    <get-release-hash src-or-bin="bin" basefile="${final.name}-windows-x64.zip" />
    <get-release-hash src-or-bin="bin" basefile="${final.name}-windows-x86.zip" />
    <get-release-hash src-or-bin="bin" basefile="${final.name}.exe" />
    <get-release-hash src-or-bin="bin" basefile="${final.name}.tar.gz" />
    <get-release-hash src-or-bin="bin" basefile="${final.name}.zip" />
    <get-release-hash src-or-bin="src" basefile="${final-src.name}.tar.gz" />
    <get-release-hash src-or-bin="src" basefile="${final-src.name}.zip" />

    <compare-hashes num="1"  src-or-bin="bin" basefile="${final.name}-deployer.tar.gz" />
    <compare-hashes num="2"  src-or-bin="bin" basefile="${final.name}-deployer.zip" />
    <compare-hashes num="3"  src-or-bin="bin" basefile="${final.name}-fulldocs.tar.gz" />
    <compare-hashes num="4"  src-or-bin="bin" basefile="${final.name}-windows-x64.zip" />
    <compare-hashes num="5"  src-or-bin="bin" basefile="${final.name}-windows-x86.zip" />
    <compare-hashes num="6"  src-or-bin="bin" basefile="${final.name}.exe" />
    <compare-hashes num="7"  src-or-bin="bin" basefile="${final.name}.tar.gz" />
    <compare-hashes num="8"  src-or-bin="bin" basefile="${final.name}.zip" />
    <compare-hashes num="9"  src-or-bin="src" basefile="${final-src.name}.tar.gz" />
    <compare-hashes num="10" src-or-bin="src" basefile="${final-src.name}.zip" />

<!--
<echo>
reproducible-1=${reproducible-1}
reproducible-2=${reproducible-2}
reproducible-3=${reproducible-3}
reproducible-4=${reproducible-4}
reproducible-5=${reproducible-5}
reproducible-6=${reproducible-6}
reproducible-7=${reproducible-7}
reproducible-8=${reproducible-8}
reproducible-9=${reproducible-9}
reproducible-10=${reproducible-10}
</echo>
-->

    <condition property="reproducible">
      <and>
        <isset property="reproducible-1" />
        <isset property="reproducible-2" />
<!--
        <isset property="reproducible-3" />
-->
        <isset property="reproducible-4" />
        <or>
          <isset property="reproducible-5" />
          <contains string="${version}" substring="11.0." /><!-- Super hack, Tomcat 11 does not produce x86 binaries. -->
        </or>
        <isset property="reproducible-6" />
        <isset property="reproducible-7" />
        <isset property="reproducible-8" />
        <isset property="reproducible-9" />
        <isset property="reproducible-10" />
      </and>
    </condition>

    <fail unless="reproducible">
One or more signatures failed.

Considering using a tool such as "diffoscope"[1] to inspect the differences
between the official release and your local-build. There may be trivial
differences that should not be considered troublesome.

For example:
$ wget https://dist.apache.org/repos/dist/release/tomcat/tomcat-${version.major}/v${version}/src/apache-tomcat-${version}-src.tar.gz
  or, for a release candidate:
$ wget https://dist.apache.org/repos/dist/dev/tomcat/tomcat-${version.major}/v${version}/src/apache-tomcat-${version}-src.tar.gz
  then:
$ diffoscope apache-tomcat-${version}-src.tar.gz output/release/v${version}/src/apache-tomcat-${version}-src.tar.gz


[1] https://diffoscope.org/
</fail>
    <echo>

                SSSS                   SSSS
                S  SS                 SS  S
               SS   S                 S   SS
               SS   S                 S   SS
              SS   SS                 S   SS
             SS    S                  S    SS
           SSS    SS                  SS    SSS
          SS     SS                    SS     SS
         SS      SS                    SS      SS
        SS       S                       S       SS
       SS        SSSSSSS           SSSSSSS        SS
   SSSSS               SSS       SSS               SSSS
  SSS            SSSS    SS     SS    SSSS            SS
 SS            SSS  SSS   S     S   SSS  SSS           S
 S            SSS        SS     SS        SSS           S
 S            SSSSSS    SS       SS    SSSSSS           S
 S           SS    SSSSSSS       SSSSSSS    SS          S
 S           SSSS       SS       SS       SSSS          S
 SS         SS  SSSSSSSSS         SSSSSSSSS  SS        S
  SSSS     SSSS        S           S        SSSS      SS
   SSSSS    SSSSSS    SS           SS    SSSSSS    SSSS
       SS  SS    SSSSSS             SSSSSS    SS  SS
        SSS SSS     S                S     SSS SSS
          SSSSSSSSSS                  SSSSSSSSS

</echo>
    <echo if:set="reproducible-3">
All signatures are verified; the build appears to be 100% reproducible.
</echo>
    <echo unless:set="reproducible-3">
All (important) signatures are verified; the build appears to be reproducible.

The fulldocs bundle appears to be different than that of the release.
It is likely due to this JDK bug:

  https://bugs.openjdk.org/browse/JDK-8306980
</echo>
  </target>

  <target name="-check-release-toolchain-versions" if="release-java-version">
    <!-- Establish default value -->
    <property name="check-release-toolchain" value="true" />
    <condition property="check-release-toolchain-versions">
      <not>
        <isfalse value="${check-release-toolchain}" />
      </not>
    </condition>
  </target>

  <target name="-require-release-toolchain-versions" if="check-release-toolchain-versions">
    <antversion property="antversion"/>
    <condition property="release-toolchain-versions-match">
      <and>
        <antversion exactly="${release-ant-version}" />
        <equals arg1="${java.vm.version}" arg2="${release-java-version}" />
      </and>
    </condition>

    <fail unless="release-toolchain-versions-match">
Release toolchain versions do not match local toolchain:

Release Java: ${release-java-version}
Local Java:   ${java.vm.version}
Release Ant:  ${release-ant-version}
Local Ant:    ${antversion}

You may not be able to verify that this build is reproducible.

Re-run with -Dcheck-release-toolchain=false to disable this check.
</fail>
    <echo>Local toolchain versions match release toolchain (Java ${release-java-version}, Ant ${release-ant-version}).
</echo>
  </target>
</project>
