Merge branch '1.9.x'
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 79f94be..3f45cf2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -23,11 +23,24 @@
 first. This way you can make sure you're not wasting your time on
 something that isn't considered to be in Ant's scope.
 
+Branches
+--------
+
+The master branch is where we develop the next release of Ant 1.10.x -
+any patch or PR against this branch must be buildable using Java8.
+
+The branch 1.9.x is where we develop the next release of Ant 1.9.x -
+any patch or PR against this branch must be buildable using Java5.
+
+Please state clearly whether you are targeting 1.9.x or 1.10.x -
+usually we port changes from 1.9.x to 1.10.x but not necessarily the
+other way around.
+
 Making Changes
 --------------
 
 + Create a topic branch from where you want to base your work (this is
-  usually the master branch).
+  usually the master or the 1.9.x branch, see above).
 + Make commits of logical units.
 + Respect the original code style:
   + Only use spaces for indentation.
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index bb1705b..72c790d 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -287,6 +287,7 @@
 Nigel Magnay
 Oliver Merkel
 Oliver Rossmueller
+Olivier Parent
 Ondra Medek
 Omer Shapira
 Oystein Gisnas
diff --git a/ReleaseInstructions b/ReleaseInstructions
index 27d4c41..7a752fc 100644
--- a/ReleaseInstructions
+++ b/ReleaseInstructions
@@ -5,8 +5,9 @@
          Magesh Umasankar
          Antoine Levy-Lambert
 
-Note: This document was updated in the context of releasing Ant
-      1.9.7 which was the first release cut from the 1.9.x branch.
+Note: This document was adapted from the one created in the context of
+      releasing Ant 1.9.7. It assumes the first release created from
+      master will be 1.10.
       Please interpret the branch names, tags, etc. according to
       your context.
 
@@ -31,7 +32,7 @@
 
 2.  Ensure you have all the external libraries that Ant uses in your
     lib/optional directory.  All dependencies are either provided by
-    JDK 1.5.0 or downloadable using
+    JDK 1.8.0 or downloadable using
     ant -f fetch.xml -Ddest=optional
     To find out whether you have all the libraries you need, execute
     the build with -verbose option and scan for lines beginning with
@@ -40,9 +41,9 @@
 3.  We don't want tags for failed votes to end up on out branches so
     the release is first created from a detached head.
 
-    Checkout the HEAD of the 1.9.x branch as a detached head:
+    Checkout the HEAD of the master branch as a detached head:
 
-    $ git checkout 1.9.x^0
+    $ git checkout master^0
 
 4.  Make sure that your directory tree is clean by running git status.
     Some tests leave behind leftovers which end up in the source
@@ -57,7 +58,7 @@
     * POM files under src/etc/poms and subdirectories
       if you've got mvn installed
 
-      $ mvn versions:set -DnewVersion=1.9.7 -DgenerateBackupPoms=false
+      $ mvn versions:set -DnewVersion=1.10.0 -DgenerateBackupPoms=false
 
       inside src/etc/poms should do the trick.
 
@@ -82,11 +83,11 @@
     $ ./dist/bin/ant -nouserlib -lib lib/optional distribution
 
     build.xml specifies that the code should be compiled with
-    source=1.5 and target=1.5.
+    source=1.8 and target=1.8.
 
 8.  Commit your changes, tag them, push them.
 
-    $ git tag -s -m "Tagging RC1 for version 1.9.7 of Ant" ANT_197_RC1
+    $ git tag -s -m "Tagging RC1 for version 1.10.0 of Ant" ANT_1.10.0_RC1
     $ git push --tags
 
 9.  Ensure that the GPG key you use is inside the KEYS file in Ant's
@@ -144,12 +145,12 @@
     This target generates a file build/html/WHATSNEW.html
 
     Add an html head element with a title like "Release Notes of Apache Ant
-    1.9.7" (from the default txt2html)
+    1.10.0" (from the default txt2html)
 
     Cut all sections about previous releases to keep only the current release,
-    and save as  RELEASE-NOTES-1.9.7.html inside the distribution folder.
+    and save as  RELEASE-NOTES-1.10.0.html inside the distribution folder.
 
-    Copy the contents of RELEASE-NOTES-1.9.7.html also into README.html
+    Copy the contents of RELEASE-NOTES-1.10.0.html also into README.html
 
 12. The distribution is now ready to go.
     Create a SVN sandbox on your computer with https://dist.apache.org/repos/dist/dev/ant in it
@@ -193,7 +194,7 @@
 
 16. Once the vote has passed, tag the last RC created with the final tag
 
-    $ git tag -s -m "Tagging version 1.9.7 of Ant" rel/1.9.7 HASH_OF_LAST_RC
+    $ git tag -s -m "Tagging version 1.10.0 of Ant" rel/1.10.0 HASH_OF_LAST_RC
     $ git push --tags
 
 17. The distrib artifacts should be published the apache dist. It is
@@ -221,36 +222,40 @@
     https://reporter.apache.org/addrelease.html?ant
 
 19. Address the available version tags in BugZilla. Create new
-    milestone 1.9.8 and version 1.9.7.
+    milestone 1.10.1 and version 1.10.0.
 
 20. Add a new release tag to doap_Ant.rdf in Ant's site.
 
-21. checkout the 1.9.x branch, merge the tag but don't push the
+21. checkout the master branch, merge the tag but don't push the
     commit
 
-    $ git checkout 1.9.x
-    $ git merge rel/1.9.7
+    [if a release of Ant 1.9.x happened at the same time, deal with
+    the 1.9.x tag on the 1.9.x branch first and merge the 1.9.x branch
+    to master before proceeding here]
+
+    $ git checkout master
+    $ git merge rel/1.10.0
 
     Set the version number in several files to the required version of
-    the next 1.9.x release. These are:
+    the next 1.10.x release. These are:
 
     * manual/cover.html
     * manual/credits.html
     * build.xml properties : project.version,manifest-version,pom.version
 
       project.version property in build.xml gets bumped to
-      [newversion]alpha, for example 1.9.8alpha
+      [newversion]alpha, for example 1.10.1alpha
 
       manifest-version gets bumped to the exact next release number
-      for example 1.9.8.
+      for example 1.10.1.
 
       pom.version gets bumped to [newversion]-SNAPSHOT
-      for example 1.9.8-SNAPSHOT.
+      for example 1.10.1-SNAPSHOT.
 
     * POM files under src/etc/poms and subdirectories
       if you've got mvn installed
 
-      $ mvn versions:set -DnewVersion=1.9.8-SNAPSHOT -DgenerateBackupPoms=false
+      $ mvn versions:set -DnewVersion=1.10.1-SNAPSHOT -DgenerateBackupPoms=false
 
       inside src/etc/poms should do the trick.
 
@@ -264,15 +269,9 @@
     $ git commit -a --amend
     $ git push
 
-22. checkout the master branch, merge the 1.9.x branch
+22. wait a few hours for the mirrors to catch up
 
-    $ git checkout master
-    $ git merge 1.9.x
-    $ git push
-
-23. wait a few hours for the mirrors to catch up
-
-24. Update the ant.apache.org site :
+23. Update the ant.apache.org site :
 
     The website is managed here: https://svn.apache.org/repos/asf/ant/site/ant/
 
@@ -280,6 +279,10 @@
     the site still uses svn and Ant proper uses git there currently is
     no way to use the scm for this.
 
+    [TODO once there is the first release of 1.10.0, we'll likely need
+    to restructure the site to allow two versions of the manual to
+    exist in parallel]
+
     Update the following files for version number:
 
     * source/antnews.xml (Announcement)
@@ -294,17 +297,20 @@
     Commit the modified/generated files in the 'production' folder, it will go
     live on ant.apache.org in a matter on seconds.
 
-25. At this point in time, the release is done and announcements are made.
+24. At this point in time, the release is done and announcements are made.
     PGP-sign your announcement posts.
 
     Apache mailing lists that should get the announcements:
     announce@apache.org, dev@ant and user@ant.
 
-26. You can now reacquaint yourself with your family and friends.
+25. You can now reacquaint yourself with your family and friends.
 
-27. After a few days "svn rm" the older release artifacts and release
+26. After a few days "svn rm" the older release artifacts and release
     notes from https://dist.apache.org/repos/dist/release/ant/
 
+    "older" here means any older 1.10.x release but not the latest
+    1.9.x release.
+
 Related Information
 
 http://www.apache.org/dev/#releases
diff --git a/STATUS b/STATUS
index 874396d..67ba9d8 100644
--- a/STATUS
+++ b/STATUS
@@ -1,10 +1,10 @@
 Apache Ant Status
-Last modified at 2016-02-24
+Last modified at 2016-04-09
 
 Release:
-    Current:        1.9.6  (in GIT Tag: ANT_196)
-    Maintenance:    1.9.x  (in GIT Branch: master)
-    Development:    1.9.7  (in GIT Branch: master)
+    Current:        1.9.6  (in GIT Tag: rel/1.9.6)
+    Maintenance:    1.9.x  (in GIT Branch: 1.9.x)
+    Development:    1.10.x (in GIT Branch: master)
 
 Assets:
     DNS:                ant.apache.org
diff --git a/WHATSNEW b/WHATSNEW
index 923f75a..92fbfdf 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -1,9 +1,35 @@
-Changes from Ant 1.9.9 TO Ant 1.9.10
-====================================
+Changes from Ant 1.10.1 TO Ant 1.10.2
+=====================================
+
+Changes that could break older environments:
+-------------------------------------------
+
+ * updated the dependency of BCEL to 6.2.
+   Bugzilla Report 61196
+
+ * delete task previously would silently accept wildcard (*)
+   value for the "file" attribute. That's no longer the case
+   and an exception could get thrown by the underlying filesystem
+   for such use. Usage like:
+
+   <delete file="/foo/bar/*.something"/>
+
+   should instead be changed to use resource collections like:
+
+   <delete>
+   	 <fileset dir="/foo/bar/" includes="*.something"/>
+   </delete>
+
+ * Commons Net 3.6 is binary-code, but not source compatible;
+   see change list of Commons Net 3.0 for details
 
  * The Log4jListener is marked as deprecated as the required log4j library
    (in version 1.x) is not maintained any more.
 
+ * Image task is marked as deprecated as the required JAI library is not
+   maintained any more and internal APIs that JAI depended on are no longer
+   available in Java 9.
+
 Fixed bugs:
 -----------
 
@@ -11,6 +37,9 @@
    value.
    Bugzilla Report 60767
 
+ * bootstrapping Ant on Windows failed
+   Bugzilla Report 61027
+
  * Fixed the issue where the SCP based tasks would try to change
    the permissions on the parent directory of a transferred file,
    instead of changing it on the transferred file itself.
@@ -21,6 +50,11 @@
    the same source file (symlinked back to itself).
    Bugzilla Report 60644
 
+ * Fixed the issue where symlink creation with "overwrite=false",
+   on existing symlink whose target was a directory, would end
+   up creating a new symlink under the target directory.
+   Bugzilla Report 58683
+
  * Improvement to the Zip task for reduced memory usage in certain
    cases. Thanks to Glen Lewis for reporting the issue and
    suggesting the fix.
@@ -42,9 +76,23 @@
    values always get quoted.
    Github Pull Request #32
 
+ * Added <encoding> attributes to various script related tasks and a
+   compiled attribute to scriptdef.
+   Github Pull Request #30
+
+ * Added support for jarsigner's -tsadigestalg to <signjar>.
+   Bugzilla Report 60665
+
  * added "regexp" attribute to <linecontainsregexp>
    Bugzilla Report 60968
 
+ * reduced GC pressure by replacing all usage of FileInputStream and
+   FileOutputStream.
+
+ * Task can now also use attribute setters that expect a
+   java.nio.file.Path argument.
+   Bugzilla Report 61042
+
  * added a new magic property ant.tstamp.now that can be used to
    override the current time/date used by <tstamp>.
    Bugzilla Report 61079
@@ -74,20 +122,21 @@
 
  * Updated Maven Ant Tasks, Jakarta Regexp and JUnit 4 to the latest
    stable version (2.1.3, 1.4, and 4.12 respectively); updated
-   Java Mail API, JRuby and Jython to the latest Java 5 compatible
-   version (1.5.6, 1.6.8 and 2.5.3, respectively); added resolve targets
-   for Ivy and AntUnit to facilitate releases and updates, respectively.
+   JRuby to the latest Java 5 compatible version (1.6.8); added
+   resolve target for AntUnit to facilitate updates.
    Github Pull Request #50
 
-* Updated Commons Net to the latest Java 5 compatible version (2.2).
+ * Updated Java Mail API, Jython, Rhino and Commons Net to the latest
+   stable version (1.6.0, 2.7.0, 1.7.7.2 and 3.6, respectively).
+   Github Pull Request #53
 
-Changes from Ant 1.9.8 TO Ant 1.9.9
-===================================
+Changes from Ant 1.10.0 TO Ant 1.10.1
+=====================================
 
 Fixed bugs:
 -----------
 
- * Ant 1.9.8 made Path#systemClasspath final which broke the Eclipse
+ * Ant 1.10.0 made Path#systemClasspath final which broke the Eclipse
    integration.
    Bugzilla Report 60582
 
@@ -97,17 +146,36 @@
    newlines present in command line arguments.
    Bugzilla Report 60562
 
-Changes from Ant 1.9.7 TO Ant 1.9.8
-===================================
+Other changes:
+--------------
+
+ * new tasks <xz> and <unxz> and resource <xzresource> for XZ
+   compression. Also the compression attribute of <tar>/<untar> now
+   accepts "xz" as valid value.
+   The tasks and type are contained in the new ant-xz.jar and require
+   the library XZ for Java to be on the CLASSPATH.
+   Bugzilla Report 60350
+
+Changes from Ant 1.9.7 TO Ant 1.10.0
+====================================
 
 Changes that could break older environments:
 -------------------------------------------
 
+ * Ant 1.10.x requires Java8 or newer at compile or build time.
+   The 1.9.x series wil stay compatible with Java5.
+
+ * The <apt> task has been removed since apt itself has been removed
+   with Java8.
+
  * <fileset>/<zipfileset>/<tarfileset> exhibited undefined
    behavior when both the dir and file attribute have been used on the
    same instance. This will now cause the build to fail.
    Bugzilla Report 59402
 
+ * <native2ascii> will default to the builtin implementation on Java8
+   as well (sun isn't available for Java9+ anyway).
+
  * The ant.java.version property will now hold the value "9" rather
    than "1.9" if running on Java 9.
 
@@ -115,6 +183,9 @@
    be used when running on Java 9 since this option has been removed.
    Bugzilla Report 59906
 
+ * <javah> will default to the "forking" implementation on Java8
+   as well.
+
 Fixed bugs:
 -----------
 
@@ -162,6 +233,11 @@
 Other changes:
 --------------
 
+ * New file selectors <executable>, <symlink> and <ownedBy>.
+
+ * New task <setpermissions> that provides the ability to set POSIX
+   compatible permssions via NIO's PosixFilePermission
+
  * <junit> now initializes the cause of the AssertionFailedError when
    converting from AssertionError.
    Bugzilla Report 58982
@@ -199,6 +275,9 @@
  * it is now possible to use references to Ant types and classloaders
    built around Ant <path>s as values for TraX factory attributes.
 
+ * AntClassLoader and its subclasses register themselves as parallel
+   capable.
+
  * <junitreport> now enables the feature
    http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions
    when run on Java 9 so the redirect extension function can be used
diff --git a/build.xml b/build.xml
index 37476c0..62314dd 100644
--- a/build.xml
+++ b/build.xml
@@ -33,10 +33,10 @@
   <property name="name" value="ant"/>
   <!-- this is the groupId of ant in the Maven repository -->
   <property name="groupid" value="org/apache/ant"/>
-  <property name="project.version" value="1.9.10alpha"/>
+  <property name="project.version" value="1.10.2alpha"/>
   <!-- pom.version is used when doing a distribution and must match with what is checked in under src/etc/poms -->
-  <property name="pom.version" value="1.9.10-SNAPSHOT"/>
-  <property name="manifest-version" value="1.9.10"/>
+  <property name="pom.version" value="1.10.2-SNAPSHOT"/>
+  <property name="manifest-version" value="1.10.2"/>
   <property name="bootstrap.jar" value="ant-bootstrap.jar"/>
 
   <property name="ant.package" value="org/apache/tools/ant"/>
@@ -92,6 +92,7 @@
   <property name="manifest.tmp" value="${build.dir}/optional.manifest"/>
   <!-- the absolute path -->
   <property name="build.tests.value" location="${build.tests}"/>
+  <property name="build.pkg.dir" value="${build.dir}/pkg"/>
 
   <!--
        ===================================================================
@@ -99,12 +100,12 @@
        ===================================================================
   -->
   <property name="debug" value="true"/>
-  <property name="chmod.fail" value="true"/>
-  <property name="chmod.maxparallel" value="250"/>
+  <property name="setpermissions.fail" value="true"/>
+  <property name="setpermissions.nonposixmode" value="tryDosOrPass"/>
   <property name="deprecation" value="false"/>
   <property name="optimize" value="true"/>
-  <property name="javac.target" value="1.5"/>
-  <property name="javac.source" value="1.5"/>
+  <property name="javac.target" value="1.8"/>
+  <property name="javac.source" value="1.8"/>
   <property name="junit.filtertrace" value="off"/>
   <property name="junit.summary" value="no"/>
   <property name="test.haltonfailure" value="false"/>
@@ -121,7 +122,6 @@
   <property name="junit.collector.dir" value="${build.dir}/failingTests"/>
   <property name="junit.collector.class" value="FailedTests"/>
 
-
   <!--
        ===================================================================
          Set the paths used in the build
@@ -293,6 +293,13 @@
     <filename name="${optional.package}/Xalan2TraceSupport*"/>
   </selector>
 
+  <selector id="needs.xz">
+    <or>
+      <filename name="${optional.package}/xz/"/>
+      <filename name="${type.package}/optional/xz/"/>
+    </or>
+  </selector>
+
   <selector id="ant.launcher">
     <filename name="${ant.package}/launch/"/>
   </selector>
@@ -319,6 +326,7 @@
         <selector refid="needs.junit4"/>
         <selector refid="needs.netrexx"/>
         <selector refid="needs.swing"/>
+        <selector refid="needs.xz"/>
         <selector refid="ant.launcher"/>
       </or>
     </not>
@@ -337,7 +345,7 @@
     <exclude unless="run.failing.tests" name="${optional.package}/jdepend/JDependTest.java"/>
   </patternset>
 
-  <!--tests that need an XML Schema-supporting parser to work-->
+  <!-- tests that need an XML Schema-supporting parser to work -->
   <selector id="needs.xmlschema">
     <or>
       <filename name="${optional.package}/SchemaValidateTest.*"/>
@@ -374,9 +382,6 @@
       </not>
     </condition>
     <property name="ignoresystemclasses" value="false"/>
-    <available property="jdk1.6+" classname="java.net.CookieStore"/>
-    <available property="jdk1.7+" classname="java.nio.file.FileSystem"/>
-    <available property="jdk1.8+" classname="java.lang.reflect.Executable"/>
     <available property="jdk9+" classname="java.lang.module.ModuleDescriptor"/>
     <condition property="jdk10+">
       <javaversion atleast="10"/>
@@ -444,15 +449,9 @@
     <available property="bcel.present"
                classname="org.apache.bcel.Constants"
                classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
-
-    <condition property="javamail.complete">
-      <and>
-        <available classname="javax.activation.DataHandler"
-          classpathref="classpath"/>
-        <available classname="javax.mail.Transport"
-          classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
-      </and>
-    </condition>
+    <available property="javamail.present"
+               classname="javax.mail.Transport"
+               classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
 
     <condition property="tests.and.ant.share.classloader">
       <or>
@@ -511,30 +510,19 @@
     <available property="jsch.present"
                classname="com.jcraft.jsch.Session"
                classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+    <available property="xz.present"
+               classname="org.tukaani.xz.XZOutputStream"
+               classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
 
     <property name="build.compiler" value="modern"/>
 
-    <!--check for XSD support in the parser-->
+    <!-- check for XSD support in the parser -->
     <condition property="xmlschema.present">
       <or>
         <parsersupports feature="http://apache.org/xml/features/validation/schema"/>
         <parsersupports feature="http://java.sun.com/xml/jaxp/properties/schemaSource"/>
       </or>
     </condition>
-
-    <!-- 
-    Java8 introduced a HTML checker 'doclint' which is very strict and breaks 
-    the build if there is a HTML error in the JavaDoc.
-    -->
-    <condition 
-      property="javadoc.doclint.none" 
-      value="-Xdoclint:none" 
-      else="">
-      <and>
-        <isset property="jdk1.8+"/>
-        <not><isset property="withDoclint"/></not>
-      </and>
-    </condition>
   </target>
 
   <!--
@@ -542,7 +530,7 @@
          Prepare the build
        ===================================================================
   -->
-  <target name="prepare">
+  <target name="prepare" depends="check-optional-packages">
     <tstamp>
       <format property="year" pattern="yyyy"/>
     </tstamp>
@@ -556,7 +544,7 @@
          Build the code
        ===================================================================
   -->
-  <target name="build" depends="prepare,check-optional-packages"
+  <target name="build" depends="prepare"
           description="--> compiles the source code">
     <mkdir dir="${build.dir}"/>
     <mkdir dir="${build.classes}"/>
@@ -586,7 +574,7 @@
             <selector refid="needs.apache-log4j" unless="log4j.present"/>
             <selector refid="needs.commons-logging" unless="commons.logging.present"/>
             <selector refid="needs.apache-bsf" unless="bsf.present"/>
-            <selector refid="needs.javamail" unless="javamail.complete"/>
+            <selector refid="needs.javamail" unless="javamail.present"/>
             <selector refid="needs.netrexx" unless="netrexx.present"/>
             <selector refid="needs.commons-net" unless="commons.net.present"/>
             <selector refid="needs.antlr" unless="antlr.present"/>
@@ -595,6 +583,7 @@
             <selector refid="needs.jdepend" unless="jdepend.present"/>
             <selector refid="needs.swing" unless="swing.present"/>
             <selector refid="needs.jsch" unless="jsch.present"/>
+            <selector refid="needs.xz" unless="xz.present"/>
             <selector refid="needs.xmlschema" unless="xmlschema.present"/>
             <selector refid="needs.apache-xalan2" unless="recent.xalan2.present"/>
           </or>
@@ -765,6 +754,7 @@
     <optional-jar dep="jsch"/>
     <optional-jar dep="jdepend"/>
     <optional-jar dep="apache-xalan2"/>
+    <optional-jar dep="xz"/>
 
   </target>
 
@@ -857,6 +847,7 @@
     <optional-src-jar dep="jsch"/>
     <optional-src-jar dep="jdepend"/>
     <optional-src-jar dep="apache-xalan2"/>
+    <optional-src-jar dep="xz"/>
 
   </target>
 
@@ -909,18 +900,23 @@
       <include name="*.pl"/>
     </fixcrlf>
 
-    <chmod perm="ugo+rx" dir="${dist.dir}" type="dir" includes="**"
-      failonerror="${chmod.fail}"/>
-    <chmod perm="ugo+r" dir="${dist.dir}" type="file" includes="**"
-      failonerror="${chmod.fail}" maxparallel="${chmod.maxparallel}"/>
-    <chmod perm="ugo+x" type="file" failonerror="${chmod.fail}">
+    <setpermissions mode="755" failonerror="${setpermissions.fail}"
+                    nonPosixMode="${setpermissions.nonposixmode}">
+      <dirset dir="${dist.dir}"/>
+    </setpermissions>
+    <setpermissions mode="644" failonerror="${setpermissions.fail}"
+                    nonPosixMode="${setpermissions.nonposixmode}">
+      <fileset dir="${dist.dir}"/>
+    </setpermissions>
+    <setpermissions mode="755" failonerror="${setpermissions.fail}"
+                    nonPosixMode="${setpermissions.nonposixmode}">
       <fileset dir="${dist.bin}">
         <include name="**/ant"/>
         <include name="**/antRun"/>
         <include name="**/*.pl"/>
         <include name="**/*.py"/>
       </fileset>
-    </chmod>
+    </setpermissions>
 
   </target>
 
@@ -1020,18 +1016,23 @@
       </fileset>
     </copy>
 
-    <chmod perm="ugo+rx" dir="${dist.dir}" type="dir" includes="**"
-      failonerror="${chmod.fail}"/>
-    <chmod perm="ugo+r" dir="${dist.dir}" type="file" includes="**"
-      failonerror="${chmod.fail}" maxparallel="${chmod.maxparallel}"/>
-    <chmod perm="ugo+x" type="file" failonerror="${chmod.fail}">
+    <setpermissions mode="755" failonerror="${setpermissions.fail}"
+                    nonPosixMode="${setpermissions.nonposixmode}">
+      <dirset dir="${dist.dir}"/>
+    </setpermissions>
+    <setpermissions mode="644" failonerror="${setpermissions.fail}"
+                    nonPosixMode="${setpermissions.nonposixmode}">
+      <fileset dir="${dist.dir}"/>
+    </setpermissions>
+    <setpermissions mode="755" failonerror="${setpermissions.fail}"
+                    nonPosixMode="${setpermissions.nonposixmode}">
       <fileset dir="${dist.bin}">
         <include name="**/ant"/>
         <include name="**/antRun"/>
         <include name="**/*.pl"/>
         <include name="**/*.py"/>
       </fileset>
-    </chmod>
+    </setpermissions>
 
     <!-- publish some useful stylesheets -->
     <copy todir="${dist.etc}">
@@ -1135,18 +1136,26 @@
       <exclude name="${tests.etc.dir}/taskdefs/fixcrlf/input/Junk?.java"/>
     </fixcrlf>
 
-    <chmod perm="ugo+x" dir="${src.dist.dir}" type="dir"
-      failonerror="${chmod.fail}"/>
-    <chmod perm="ugo+r" dir="${src.dist.dir}" failonerror="${chmod.fail}"/>
-    <chmod perm="ugo+x" failonerror="${chmod.fail}">
+    <setpermissions mode="755" failonerror="${setpermissions.fail}"
+                    nonPosixMode="${setpermissions.nonposixmode}">
+      <dirset dir="${src.dist.dir}"/>
+    </setpermissions>
+
+    <setpermissions mode="644" failonerror="${setpermissions.fail}"
+                    nonPosixMode="${setpermissions.nonposixmode}">
+      <fileset dir="${src.dist.dir}"/>
+    </setpermissions>
+
+    <setpermissions mode="755" failonerror="${setpermissions.fail}"
+                    nonPosixMode="${setpermissions.nonposixmode}">
       <fileset dir="${src.dist.dir}">
-        <include name="**/.sh"/>
-        <include name="**/.pl"/>
-        <include name="**/.py"/>
+        <include name="**/*.sh"/>
+        <include name="**/*.pl"/>
+        <include name="**/*.py"/>
         <include name="**/ant"/>
         <include name="**/antRun"/>
       </fileset>
-    </chmod>
+    </setpermissions>
 
   </target>
 
@@ -1196,10 +1205,28 @@
   </condition>
 
   <target name="pkg-distribution" depends="zip-distribution" if="buildosxpackage">
-    <exec executable="release/build-osx-pkg.py">
-      <arg value="--output-dir"/>
-      <arg value="${dist.base.binaries}"/>
-      <arg value="${dist.base.binaries}/${dist.name}-bin.zip"/>
+    <mkdir dir="${build.pkg.dir}"/>
+    <unzip src="${dist.base.binaries}/${dist.name}-bin.zip" dest="${build.pkg.dir}">
+      <mapper type="regexp" from="^([^/]*)/(.*)$$" to="\2"/>
+    </unzip>
+    <chmod perm="+x" type="file">
+      <fileset dir="${build.pkg.dir}/bin">
+        <include name="ant"/>
+        <include name="antRun"/>
+        <include name="*.pl"/>
+        <include name="*.py"/>
+      </fileset>
+    </chmod>
+    <exec executable="/usr/bin/pkgbuild">
+      <arg value="--root"/>
+      <arg value="${build.pkg.dir}"/>
+      <arg value="--identifier"/>
+      <arg value="org.apache.ant"/>
+      <arg value="--version"/>
+      <arg value="${project.version}"/>
+      <arg value="--install-location"/>
+      <arg value="/usr/local/ant"/>
+      <arg value="${dist.base.binaries}/${dist.name}.pkg"/>
     </exec>
   </target>
 
@@ -1229,6 +1256,8 @@
           src="${dist.base.binaries}/${dist.name}-bin.tar"/>
     <bzip2 destfile="${dist.base.binaries}/${dist.name}-bin.tar.bz2"
            src="${dist.base.binaries}/${dist.name}-bin.tar"/>
+    <xz destfile="${dist.base.binaries}/${dist.name}-bin.tar.xz"
+        src="${dist.base.binaries}/${dist.name}-bin.tar"/>
     <delete file="${dist.base.binaries}/${dist.name}-bin.tar"/>
   </target>
 
@@ -1282,6 +1311,8 @@
           src="${dist.base.manual}/${dist.name}-manual.tar"/>
     <bzip2 destfile="${dist.base.manual}/${dist.name}-manual.tar.bz2"
            src="${dist.base.manual}/${dist.name}-manual.tar"/>
+    <xz destfile="${dist.base.manual}/${dist.name}-manual.tar.xz"
+        src="${dist.base.manual}/${dist.name}-manual.tar"/>
     <delete file="${dist.base.manual}/${dist.name}-manual.tar"/>
 
     <delete dir="${dist.name}"/>
@@ -1333,6 +1364,8 @@
           src="${dist.base.source}/${dist.name}-src.tar"/>
     <bzip2 destfile="${dist.base.source}/${dist.name}-src.tar.bz2"
            src="${dist.base.source}/${dist.name}-src.tar"/>
+    <xz destfile="${dist.base.source}/${dist.name}-src.tar.xz"
+        src="${dist.base.source}/${dist.name}-src.tar"/>
     <delete file="${dist.base.source}/${dist.name}-src.tar"/>
     <delete dir="${dist.name}"/>
     <checksums>
@@ -1373,8 +1406,10 @@
           description="--> cleans up everything">
     <delete file="${bootstrap.dir}/bin/antRun"/>
     <delete file="${bootstrap.dir}/bin/antRun.bat"/>
-    <delete file="${bootstrap.dir}/bin/*.pl"/>
-    <delete file="${bootstrap.dir}/bin/*.py"/>
+    <delete>
+      <fileset dir="${bootstrap.dir}/bin" includes="*.pl"/>
+      <fileset dir="${bootstrap.dir}/bin" includes="*.py"/>
+    </delete>
   </target>
 
   <!--
@@ -1401,20 +1436,23 @@
          Creates the API documentation
        ===================================================================
   -->
-  <target name="check-javadoc">
+  <target name="check-javadoc" depends="prepare">
     <uptodate property="javadoc.notrequired"
-      targetfile="${build.javadocs}/packages.html">
+              targetfile="${build.javadocs}/packages.html">
       <srcfiles dir="${java.dir}" includes="**/*.java"/>
     </uptodate>
     <uptodate property="tests.javadoc.notrequired"
-      targetfile="${build.tests.javadocs}/packages.html">
+              targetfile="${build.tests.javadocs}/packages.html">
       <srcfiles dir="${src.junit}">
         <patternset refid="useful.tests"/>
       </srcfiles>
     </uptodate>
+    <condition property="javadoc.jaf.module" value="--add-modules java.activation" else="">
+      <isset property="jdk9+"/>
+    </condition>
   </target>
 
-  <target name="javadocs" depends="prepare,check-javadoc,check-optional-packages"
+  <target name="javadocs" depends="check-javadoc"
           description="--> creates the API documentation" unless="javadoc.notrequired">
     <mkdir dir="${build.javadocs}"/>
     <javadoc useexternalfile="yes"
@@ -1444,10 +1482,11 @@
       <group title="Optional Types" packages="org.apache.tools.ant.types.optional*"/>
       <group title="Ant Utilities" packages="org.apache.tools.ant.util*"/>
       <classpath refid="tests-classpath"/>
+      <arg line="${javadoc.jaf.module}"/>
     </javadoc>
   </target>
 
-  <target name="test-javadocs" depends="prepare,check-javadoc" unless="tests.javadoc.notrequired"
+  <target name="test-javadocs" depends="check-javadoc" unless="tests.javadoc.notrequired"
           description="--> creates the API documentation for test utilities">
     <mkdir dir="${build.tests.javadocs}"/>
     <javadoc useexternalfile="yes"
@@ -1581,6 +1620,11 @@
 
   <target name="test-init" depends="probe-offline,check-optional-packages,dump-info">
     <mkdir dir="${build.junit.tmpdir}"/>
+    <condition property="sun.io.useCanonCaches" value="false">
+      <not>
+        <javaversion atleast="9"/>
+      </not>
+    </condition>
     <macrodef name="test-junit">
       <element name="junit-nested" implicit="true"/>
       <sequential>
@@ -1626,6 +1670,11 @@
           <sysproperty key="tests.and.ant.share.classloader"
                        value="${tests.and.ant.share.classloader}"/>
           <sysproperty key="java.io.tmpdir" file="${build.junit.tmpdir}"/>
+          <!-- in Java8 the canonical cache seems to interfere with
+               our symlink tests -->
+          <syspropertyset>
+            <propertyref name="sun.io.useCanonCaches"/>
+          </syspropertyset>
           <classpath>
             <path refid="tests-runtime-classpath"/>
             <pathelement location="${junit.collector.dir}"/>
@@ -1763,8 +1812,7 @@
           <exclude name="${taskdefs.package}/TestProcess.java"/>
           <exclude name="${optional.package}/splash/SplashScreenTest.java"/>
 
-          <!-- only run these tests if their required libraries are
-               installed -->
+          <!-- only run these tests if their required libraries are installed -->
           <selector refid="conditional-patterns"/>
 
           <!-- tests excluded if the test is run in offline mode -->
diff --git a/contributors.xml b/contributors.xml
index be53be9..fb92b6b 100644
--- a/contributors.xml
+++ b/contributors.xml
@@ -1169,6 +1169,10 @@
     <last>Rossmueller</last>
   </name>
   <name>
+    <first>Olivier</first>
+    <last>Parent</last>
+  </name>
+  <name>
     <first>Omer</first>
     <last>Shapira</last>
   </name>
diff --git a/docs.xml b/docs.xml
index f49e70f..1cb7806 100644
--- a/docs.xml
+++ b/docs.xml
@@ -17,9 +17,7 @@
 -->
 <project name="docs" default="txt2html">
 
-    <available property="jdk1.5+" classname="java.net.Proxy"/>
     <target name="txt2html">
-        <fail unless="jdk1.5+" message="Tomcat BuildUtils requires Java5+"/>
         <property name="build.dir" value="build"/>
         <tempfile property="temp.dir"/>
         <mkdir dir="${temp.dir}/org/apache/tomcat/buildutil"/>
diff --git a/fetch.xml b/fetch.xml
index b92673e..899b0f3 100644
--- a/fetch.xml
+++ b/fetch.xml
@@ -261,7 +261,7 @@
   <target name="bcel"
           description="load Byte Code Engineering Library (BCEL)"
           depends="init">
-    <f2 project="bcel"/>
+    <f2 project="org.apache.bcel" archive="bcel"/>
   </target>
 
   <target name="jdepend"
@@ -315,7 +315,6 @@
           description="load Java Mail"
           depends="init">
     <f2 project="javax.mail" archive="javax.mail-api"/>
-    <f2 project="javax.activation" archive="activation"/>
   </target>
 
   <target name="jspc"
@@ -359,8 +358,13 @@
          dest="${temp.dir}/NetRexx.zip" skipexisting="true"/>
   </target>
 
+  <target name="xz"
+          description="load XZ for Java"
+          depends="init">
+    <f2 project="org.tukaani" archive="xz"/>
+  </target>
+
   <target name="all"
     description="load all the libraries (except jython)"
-    depends="antunit,ivy,logging,junit,xml,networking,regexp,antlr,bcel,jdepend,bsf,debugging,script,javamail,jspc,jai,netrexx"/>
-
+    depends="antunit,ivy,logging,junit,xml,networking,regexp,antlr,bcel,jdepend,bsf,debugging,script,javamail,jspc,jai,xz,netrexx"/>
 </project>
diff --git a/lib/libraries.properties b/lib/libraries.properties
index 355daa3..3d8cdef 100644
--- a/lib/libraries.properties
+++ b/lib/libraries.properties
@@ -31,15 +31,13 @@
 # Versions of different libraries. Please keep in alphabetical order, except
 # when a specific dependency forces them to be out-of-order
 ivy.version=2.4.0
-activation.version=1.1.1
 ant-antunit.version=1.3
 antlr.version=2.7.7
-bcel.version=5.1
+bcel.version=6.2
 bsf.version=2.4.0
 bsh.version=2.0b4
 bsh-core.version=${bsh.version}
-# Later versions are built with Java 6
-commons-net.version=2.2
+commons-net.version=3.6
 commons-logging.version=1.1
 commons-logging-api.version=${commons-logging.version}
 hamcrest-core.version=1.3
@@ -50,16 +48,13 @@
 # Later versions of Tomcat provide a jspc task
 jasper-compiler.version=4.1.36
 jasper-runtime.version=${jasper-compiler.version}
-# Later versions are built with Java 7
-javax.mail-api.version=1.5.6
+javax.mail-api.version=1.6.0
 jdepend.version=2.9.1
-# Later versions are built with Java 7
 jruby.version=1.6.8
 junit.version=4.12
-# Later versions are built with Java 6
-rhino.version=1.7R5
+rhino.version=1.7.7.2
 jsch.version=0.1.54
-jython.version=2.5.3
+jython.version=2.7.0
 # log4j 1.2.15 requires JMS and a few other Sun jars that are not in the m2 repo
 log4j.version=1.2.14
 oro.version=2.0.8
@@ -67,6 +62,7 @@
 which.version=1.0
 xalan.version=2.7.2
 xml-resolver.version=1.2
+xz.version=1.6
 # paired
 jacl.version=1.2.6
 tcljava.version=${jacl.version}
diff --git a/manual/Tasks/BorlandEJBTasks.html b/manual/Tasks/BorlandEJBTasks.html
index 126fe5c..3ee56c6 100644
--- a/manual/Tasks/BorlandEJBTasks.html
+++ b/manual/Tasks/BorlandEJBTasks.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="log">BorlandDeploy</a>Tool</h2>
+<h2 id="log">BorlandDeploy Tool</h2>
 <p>by Benoit Moussaud (<a href="mailto:benoit.moussaud@criltelecom.com">benoit.moussaud@criltelecom.com</a>)</p>
 
 
@@ -40,7 +40,7 @@
 his homepage.</p>
 
 <h3>Borland element</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top" width="63"><b>Attribute</b></td>
     <td valign="top" width="915"><b>Description</b></td>
@@ -92,11 +92,11 @@
       if you have borland in your classpath. If you do not, you should use a
       nested <a href="ejb.html#ejbjar-dtd"><code>&lt;dtd&gt;</code></a> element,
       described in the ejbjar task
-      documentation. </td>
+      documentation.</td>
     <td align="center" valign="middle" width="62">no</td>
   </tr>
   <tr>
-    <td valign="top" width="63">generateclient </td>
+    <td valign="top" width="63">generateclient</td>
     <td valign="top" width="915">If true, turn on the generation of the corresponding
       ejbjar (default = false)</td>
     <td align="center" valign="middle" width="62">no</td>
@@ -112,7 +112,7 @@
     <td align="center" valign="middle" width="62">No, defaults to 4</td>
   </tr>
   <tr>
-    <td valign="top" width="63">java2iiopParams </td>
+    <td valign="top" width="63">java2iiopParams</td>
     <td valign="top" width="915">If filled, the params are added to the java2iiop command (ex: -no_warn_missing_define)</td>
     <td align="center" valign="middle" width="62">no</td>
   </tr>
@@ -136,8 +136,5 @@
 The verify phase is turned on and the generate client phase as well.
 </pre>
 
-<h3>&nbsp;</h3>
-
 </body>
 </html>
-
diff --git a/manual/Tasks/BorlandGenerateClient.html b/manual/Tasks/BorlandGenerateClient.html
index 01956b2..9454444 100644
--- a/manual/Tasks/BorlandGenerateClient.html
+++ b/manual/Tasks/BorlandGenerateClient.html
@@ -24,14 +24,14 @@
 
 <body>
 
-<h2><a name="log">BorlandGenerateClient</a></h2>
+<h2 id="log">BorlandGenerateClient</h2>
 <p>by Benoit Moussaud (<a href="mailto:benoit.moussaud@criltelecom.com">benoit.moussaud@criltelecom.com</a>)</p>
 <h3>Description</h3>
 <p>The BorlandGenerateClient is a task dedicated to Borland Application Server
   v 4.5. It offers to generate the client jar file corresponding to an ejb jar
   file.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top" width="63"><b>Attribute</b></td>
     <td valign="top" width="915"><b>Description</b></td>
@@ -83,8 +83,6 @@
     &lt;/classpath&gt;
 &lt;/blgenclient&gt;
 </pre>
-<pre>&nbsp;</pre>
 
 </body>
 </html>
-
diff --git a/manual/Tasks/ant.html b/manual/Tasks/ant.html
index 87b78bb..7088d2c 100644
--- a/manual/Tasks/ant.html
+++ b/manual/Tasks/ant.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="ant">Ant</a></h2>
+<h2 id="ant">Ant</h2>
 <h3>Description</h3>
 
 <p>Runs Apache Ant on a supplied buildfile. This can be used to build
@@ -59,7 +59,7 @@
 
 <p>Properties defined on the command line cannot be overridden by
   nested <code>&lt;property&gt;</code> elements.  <em>Since Ant
-  1.8.0.</em> the same is true for nested structures
+  1.8.0</em> the same is true for nested structures
   of <code>&lt;ant&gt;</code> tasks: if a build file <em>A</em>
   invokes <em>B</em> via an <code>&lt;ant&gt;</code> task setting a
   property with a nested <code>&lt;property&gt;</code> element
@@ -81,7 +81,7 @@
 inside of targets.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -115,7 +115,7 @@
   </tr>
   <tr>
     <td valign="top">output</td>
-    <td valign="top">Filename to write the ant output to.  This is
+    <td valign="top">Filename to write the Ant output to.  This is
     relative to the value of the dir attribute if it has been set or
     to the base directory of the current project otherwise.
     </td>
@@ -156,11 +156,11 @@
 Note that the <code>refid</code> attribute points to a
 reference in the calling project, not in the new one.</p>
 
-<h4><a name="reference">reference</a></h4>
+<h4 id="reference">reference</h4>
 <p>Used to choose references that shall be copied into the new project,
 optionally changing their id.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -192,7 +192,7 @@
 instead of using the target attribute.  These will be executed as if
 Ant had been invoked with a single target whose dependencies are the
 targets so specified, in the order specified.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -215,7 +215,7 @@
   no matter what any other attribute of this task says and no matter
   how deeply nested into levels of
   <code>&lt;ant&gt;</code> invocations this task lives.</p>
- 
+
 <p>If you haven't set <code>useNativeBasedir</code> or set it to
   false, the following rules apply:</p>
 
@@ -231,7 +231,7 @@
   different <code>&lt;ant&gt;</code> (or <code>&lt;antcall&gt;</code>)
   task "higher up", the following table shows the details:</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>dir attribute</b></td>
     <td valign="top"><b>inheritAll attribute</b></td>
@@ -267,7 +267,7 @@
   attribute will always win, but if the dir attribute has been omitted
   an even more complex situation arises:</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>parent dir attribute</b></td>
     <td valign="top"><b>parent inheritAll attribute</b></td>
@@ -407,7 +407,5 @@
 <p>will copy the parent's definition of <code>path1</code> into the
 new project using the id <code>path2</code>.</p>
 
-
-
 </body>
 </html>
diff --git a/manual/Tasks/antcall.html b/manual/Tasks/antcall.html
index 00cf615..32044c8 100644
--- a/manual/Tasks/antcall.html
+++ b/manual/Tasks/antcall.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="antcall">AntCall</a></h2>
+<h2 id="antcall">AntCall</h2>
 <h3>Description</h3>
 
 <p>Call another target within the same buildfile optionally
@@ -75,7 +75,7 @@
 behavior of this task is undefined.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -122,11 +122,11 @@
 false (see above).
 </p>
 
-<h4><a name="reference">reference</a></h4>
+<h4 id="reference">reference</h4>
 <p>Used to choose references that shall be copied into the new project,
 optionally changing their id.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -158,7 +158,7 @@
 instead of using the target attribute.  These will be executed as if
 Ant had been invoked with a single target whose dependencies are the
 targets so specified, in the order specified.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -195,7 +195,5 @@
 <p>will copy the parent's definition of <code>path1</code> into the
 new project using the id <code>path2</code>.</p>
 
-
-
 </body>
 </html>
diff --git a/manual/Tasks/antlr.html b/manual/Tasks/antlr.html
index ca0bcde..36d22cb 100644
--- a/manual/Tasks/antlr.html
+++ b/manual/Tasks/antlr.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="antlr">ANTLR</a></h2>
+<h2 id="antlr">ANTLR</h2>
 <h3>Description</h3>
 <p>
   Invokes the <a HREF="http://www.antlr.org/" target="_top">ANTLR</a> Translator generator
@@ -42,7 +42,7 @@
   supergrammar specified by the glib attribute) is newer than the
   generated files.
 </p>
-<p><strong>Note:</strong> This task depends on external libraries not
+<p><strong>Note</strong>: This task depends on external libraries not
 included in the Apache Ant distribution. See <a href="../install.html#librarydependencies">Library Dependencies</a>
 for more information.</p>
 <p>Antlr 2.7.1 Note:
@@ -63,7 +63,7 @@
 </p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -160,7 +160,7 @@
   </tr>
 </table>
 
-<h3><a name="nested">Nested Elements</a></h3>
+<h3 id="nested">Nested Elements</h3>
 
 <p><code>ANTLR</code> supports a nested <code>&lt;classpath&gt;</code>
 element, that represents a <a href="../using.html#path">PATH like
@@ -189,15 +189,12 @@
 <blockquote><pre>
 &lt;antlr
     target=&quot;etc/java.g&quot;
-    outputdirectory=&quot;build/src&quot;
-/&gt;
+    outputdirectory=&quot;build/src&quot;/&gt;
 </pre></blockquote>
 <p>
   This invokes ANTLR on grammar file etc/java.g, writing the generated
   files to build/src.
 </p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/antstructure.html b/manual/Tasks/antstructure.html
index ab7acc1..5581040 100644
--- a/manual/Tasks/antstructure.html
+++ b/manual/Tasks/antstructure.html
@@ -24,8 +24,8 @@
 
 <body>
 
-<h2><a name="antstructure">AntStructure</a></h2>
-<h3>Description</h3> 
+<h2 id="antstructure">AntStructure</h2>
+<h3>Description</h3>
 
 <p>Generates an DTD for Apache Ant buildfiles which contains information
 about all tasks currently known to Ant.</p>
@@ -51,11 +51,11 @@
 instead of the one that emits a DTD.  In order to plug in your own
 structure, you have to implement the interface
 <code>org.apache.tools.ant.taskdefs.AntStructure.StructurePrinter</code>
-and <code>&lt;typedef&gt; your class and use the new type as a nested
-element of this task - see the example below.</code>
+and <code>&lt;typedef&gt;</code> your class and use the new type as a nested
+element of this task - see the example below.
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
diff --git a/manual/Tasks/antversion.html b/manual/Tasks/antversion.html
index cd9f838..3e9919f 100644
--- a/manual/Tasks/antversion.html
+++ b/manual/Tasks/antversion.html
@@ -24,15 +24,15 @@
 
 <body>
 
-<h2><a name="antversion">Antversion</a></h2>
+<h2 id="antversion">Antversion</h2>
 <h3>Description</h3>
 <p>
-Stores the Apache Ant version (when used as task) or checks for a specific Ant version 
+Stores the Apache Ant version (when used as task) or checks for a specific Ant version
 (when used as condition).
-<b>Since Ant 1.7.0</b>
+<em>Since Ant 1.7.0</em>
 </p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -41,15 +41,15 @@
   </tr>
   <tr>
     <td valign="top">atleast</td>
-    <td valign="top">The version that this at least.
-      The format is major.minor.point.</td>
+    <td valign="top">The version that this Ant is of at least.
+      The format is <code>major.minor.point</code>.</td>
     <td valign="top" align="center">No</td>
-    <td valign="top" rowspan="2" align="center">One of these.</td>
+    <td valign="top" rowspan="2" align="center">Exactly one of these</td>
   </tr>
   <tr>
     <td valign="top">exactly</td>
-    <td valign="top">The version that this ant is exactly.
-      The format is <tt>major.minor.point</tt>.</td>
+    <td valign="top">The version that this Ant is of exactly.
+      The format is <code>major.minor.point</code>.</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
diff --git a/manual/Tasks/apply.html b/manual/Tasks/apply.html
index 5444a64..540be75 100644
--- a/manual/Tasks/apply.html
+++ b/manual/Tasks/apply.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="apply">Apply/<i>ExecOn</i></a></h2>
+<h2 id="apply">Apply/<i>ExecOn</i></h2>
 <p><i>The name <code>execon</code> is deprecated and only kept for backwards
 compatibility.</i></p>
 <h3>Description</h3>
@@ -40,8 +40,7 @@
  (<em>since&nbsp;Ant&nbsp;1.6</em>) or
  <a href="../Types/filelist.html">FileList</a>s
  (<em>since&nbsp;Ant&nbsp;1.6</em>)
-&ndash;
- are passed as arguments to the system command.</p>
+&ndash; are passed as arguments to the system command.</p>
 <p>If you specify a nested <a href="../Types/mapper.html">mapper</a>,
 the timestamp of each source file is compared to the timestamp of a
 target file which is defined by the nested mapper element and searched
@@ -52,8 +51,8 @@
 <p>Note that you cannot interact with the forked program, the only way
 to send input to it is via the input and inputstring attributes.</p>
 
-<h4><a name="background">Running Ant as a background process on
-    Unix(-like) systems</a></h4>
+<h4 id="background">Running Ant as a background process on
+    Unix(-like) systems</h4>
 
 <p>If you run Ant as a background process (like <code>ant &</code>)
   and use the <code>&lt;apply&gt;</code> task with <code>spawn</code>
@@ -62,7 +61,7 @@
   from the standard input.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -85,7 +84,7 @@
   <tr>
     <td valign="top">spawn</td>
     <td valign="top">whether or not you want the commands to be spawned.<br>
-    If you spawn a command, its output will not be logged by ant.<br>
+    If you spawn a command, its output will not be logged by Ant.<br>
     The input, output, error, and result property settings are not active when spawning a process.<br>
     <em>since&nbsp;Ant&nbsp;1.6</em>
     </td>
@@ -96,7 +95,7 @@
     <td valign="top">dir</td>
     <td valign="top">the directory in which the command should be executed.</td>
     <td align="center" valign="top">No.<br/>
-      <strong>Note:</strong> the default used when dir has not been
+      <strong>Note</strong>: the default used when dir has not been
       specified depends on the <code>vmlauncher</code> attribute.  If
       <code>vmlauncher</code> is <code>true</code> the task will use
       the current working directory, otherwise it uses the project's basedir.
@@ -211,7 +210,7 @@
   <tr>
     <td valign="top">failifexecutionfails</td>
     <td valign="top">Stop the build if we can't start the program.
-      Defaults to true. </td>
+      Defaults to true.</td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
@@ -234,7 +233,7 @@
       <i>both</i>. If set to <i>file</i>, only the names of plain
       files will be sent to the command. If set to <i>dir</i>, only
       the names of directories are considered.<br>
-      <strong>Note:</strong> The type attribute does not apply to
+      <strong>Note</strong>: The type attribute does not apply to
       nested <i>dirset</i>s - <i>dirset</i>s always implicitly
       assume type to be <i>dir</i>.</td>
     <td align="center" valign="top">No, default is <i>file</i></td>
@@ -273,31 +272,31 @@
     <td valign="top">maxparallel</td>
     <td valign="top">Limit the amount of parallelism by passing at
       most this many sourcefiles at once.  Set it to &lt;= 0 for
-      unlimited. <em>Since&nbsp;Ant&nbsp;1.6.</em></td>
+      unlimited. <em>Since&nbsp;Ant&nbsp;1.6</em>.</td>
     <td align="center" valign="top">No, unlimited by default</td>
   </tr>
   <tr>
     <td valign="top">addsourcefile</td>
     <td valign="top">Whether source file names should be added to the
-      command automatically. <em>Since&nbsp;Ant&nbsp;1.6.</em></td>
+      command automatically. <em>Since&nbsp;Ant&nbsp;1.6</em>.</td>
     <td align="center" valign="top">No, default is <i>true</i></td>
   </tr>
   <tr>
     <td valign="top">verbose</td>
     <td valign="top">Whether to print a summary after execution or not.
-      <em>Since&nbsp;Ant&nbsp;1.6.</em></td>
+      <em>Since&nbsp;Ant&nbsp;1.6</em>.</td>
     <td align="center" valign="top">No, default <i>false</i></td>
   </tr>
   <tr>
     <td valign="top">ignoremissing</td>
     <td valign="top">Whether to ignore nonexistent files specified
-      via filelists.  <em>Since&nbsp;Ant&nbsp;1.6.2.</em></td>
+      via filelists.  <em>Since&nbsp;Ant&nbsp;1.6.2</em>.</td>
     <td align="center" valign="top">No, default is <i>true</i></td>
   </tr>
   <tr>
     <td valign="top">force</td>
     <td valign="top">Whether to bypass timestamp comparisons
-      for target files.  <em>Since&nbsp;Ant&nbsp;1.6.3.</em></td>
+      for target files.  <em>Since&nbsp;Ant&nbsp;1.6.3</em>.</td>
     <td align="center" valign="top">No, default is <i>false</i></td>
   </tr>
 </table>
@@ -338,7 +337,7 @@
 <code>false</code>). If you need to place it somewhere different,
 use a nested <code>&lt;srcfile&gt;</code> element between your
 <code>&lt;arg&gt;</code> elements to mark the insertion point.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -363,7 +362,7 @@
 filename on the command line. If omitted, the target filenames will
 not be added to the command line at all. This element can only be
 specified if you also define a nested mapper.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -387,7 +386,7 @@
 system command via nested <code>&lt;env&gt;</code> elements. See the
 description in the section about <a href="exec.html#env">exec</a></p>
 <h4>redirector</h4>
-<i><b>Since&nbsp;Ant&nbsp;1.6.2</b></i>
+<em>Since&nbsp;Ant&nbsp;1.6.2</em>
 <p>A nested <a href="../Types/redirector.html">I/O Redirector</a>
 can be specified.  &lt;apply&gt;'s behavior is like that of
 <a href="exec.html#redirector">exec</a> with regard to
@@ -495,10 +494,5 @@
 to the <code>jsmin</code> program, the <code>addsourcefile</code> is set to
 <code>false</code>.
 
-
-
-
-
-
 </body>
 </html>
diff --git a/manual/Tasks/apt.html b/manual/Tasks/apt.html
deleted file mode 100644
index 4bdd9a9..0000000
--- a/manual/Tasks/apt.html
+++ /dev/null
@@ -1,179 +0,0 @@
-<!--
-   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.
--->
-<html lang="en-us"><head>
-<meta http-equiv="Content-Language" content="en-us"><link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
-<title>Apt Task</title></head>
-
-<body>
-
-<h2><a name="Apt">Apt</a></h2>
-<h3>Description</h3>
-<p>Runs the annotation processor tool (apt), and then optionally compiles
-   the original code, and any generated source code.
-   <p>This task runs on Java 1.5 to Java 1.7.</p>
-   <p>Apt is deprecated in Java 1.6, which can run annotation
-   processors as part of javac, and removed from the distribution in Java 1.8.
-   The task will fire an exception when attempting to run under Java 1.8.</p>
-
-
-<p>This task inherits from the <a href="javac.html">Javac Task</a>, and thus
-   supports nearly all of the same attributes, and subelements.  
-   There is one special case, the <tt>fork</tt> attribute, which is present
-   but which can only be set to <tt>true</tt>. That is, apt only works as
-   a forked process.
- </p>
- <p>
-   In addition, it supports
-   the following addition items:</p>
-
-<h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
-  <tbody><tr>
-    <td valign="top"><b>Attribute</b></td>
-    <td valign="top"><b>Description</b></td>
-    <td align="center" valign="top"><b>Required</b></td>
-  </tr>
-  <tr>
-    <td valign="top">compile</td>
-    <td valign="top">After running the Apt, should the code be compiled.  (see the
-                     <code>-nocompile</code> flag on the Apt executable)</td>
-    <td align="center" valign="top">No, defaults to false.</td>
-  </tr>
-  <tr>
-    <td valign="top">factory</td>
-    <td valign="top">The fully qualified classname of the AnnotationProcessFactory to be used
-                     to construct annotation processors.  This represents the <code>-factory</code>
-                     command line flag of the Apt executable.</td>
-    <td align="center" valign="top">No</td>
-  </tr>
-  <tr>
-    <td valign="top">factorypathref</td>
-    <td valign="top">The reference id of the path used to find the classes needed by the
-                     AnnotationProcessorFactory (and the location of the factory itself).
-                     This represents the <code>-factorypath</code> flag on the Apt executable.</td>
-    <td align="center" valign="top">No</td>
-  </tr>
-  <tr>
-    <td valign="top">preprocessdir</td>
-    <td valign="top">The directory used for preprocessing.  This is the directory where the
-                     generated source code will be place.  This represents the <code>-s</code> flag on
-                     the Apt executable.</td>
-    <td align="center" valign="top">No</td>
-  </tr>
-</tbody></table>
-
-<h3>Parameters specified as nested elements</h3>
-
-
-<h4>factorypath</h4>
-
-<p>You can specify the path used to find the classes needed by the AnnotationProcessorFactory
-   at runtime, using this element.  It is represents as a generic path like structure.  This
-   represents the <code>-factorypath</code> flag on the Apt executable.</p>
-
-
-<h4>option</h4>
-
-<p>Used to represent a generic option to pass to Apt.  This represents the <code>-A</code> flag on the
-   Apt executable.  You can specify zero or more <code>&lt;option&gt;</code> elements.</p>
-
-<table border="1" cellpadding="2" cellspacing="0">
-<tbody><tr>
-  <td valign="top" width="12%"><b>Attribute</b></td>
-  <td valign="top" width="78%"><b>Description</b></td>
-  <td valign="top" width="10%"><b>Required</b></td>
-</tr>
-  <tr>
-    <td valign="top">name</td>
-    <td align="center">The name of the option</td>
-    <td align="center">Yes.</td>
-  </tr>
-  <tr>
-    <td valign="top">value</td>
-    <td align="center">The value to set the option to</td>
-    <td align="center">Yes.</td>
-  </tr>
-</tbody></table>
-
-<h3>Examples</h3>
-<blockquote><pre>
-&lt;apt srcdir="${src}"
-     destdir="${build}"
-     classpath="xyz.jar"
-     debug="on"
-     compile="true"
-     factory="com.mycom.MyAnnotationProcessorFactory"
-     factorypathref="my.factorypath.id"
-     preprocessdir="${preprocess.dir}"&gt;
-&lt;/apt&gt;
-</pre></blockquote>
-<p>compiles all <code>.java</code> files under the <code>${src}</code>
-directory, and stores
-the <code>.class</code> files in the <code>${build}</code> directory.
-The classpath used includes <code>xyz.jar</code>, and compiling with
-debug information is on.  It also forces the generated source code to
-be compiled.  The generated source code will be placed in
-<code>${preprocess.dir}</code> directory, using the class
-<code>com.mycom.MyAnnotationProcessorFactory</code> to supply
-AnnotationProcessor instances.</p>
-
-
-<h3>Notes</h3>
-
-<p>
-The inherited "fork" attribute is set to true by default; please do not change it.
-</p>
-
-<p>
-The inherited "compiler" attribute is ignored, as it is forced to use the Apt compiler
-</p>
-
-<p>Using the Apt compiler with the "compile" option set to "true"
-   forces you to use Sun's Apt compiler, which will use the JDK's Javac compiler.
-   If you wish to use another compiler, you will first need run the Apt processor
-   with the "compile" flag set to "false", and then use a
-   <code>&lt;javac&gt;</code> task to compile first your original source code, and then the
-   generated source code:</p>
-
-<blockquote><pre>
-&lt;apt srcdir="${src}"
-     destdir="${build}"
-     classpath="xyz.jar"
-     debug="true"
-     compile="false"
-     factory="com.mycom.MyAnnotationProcessorFactory"
-     factorypathref="my.factorypath.id"
-     preprocessdir="${preprocess.dir}"&gt;
-&lt;/apt&gt;
-
-&lt;javac srcdir="${src}"
-       destdir="${build}"
-       classpath="xyz.jar"
-       debug="on"/&gt;
-
-&lt;javac srcdir="${preprocess.dir}"
-       destdir="${build}"
-       classpath="xyz.jar"
-       debug="true"/&gt;
-</pre></blockquote>
-
-This may involve more build file coding, but the speedup gained from switching
-to jikes may justify the effort.
-<p>
-</p>
-
-</body></html>
diff --git a/manual/Tasks/attrib.html b/manual/Tasks/attrib.html
index a26f0c5..86200b8 100644
--- a/manual/Tasks/attrib.html
+++ b/manual/Tasks/attrib.html
@@ -24,8 +24,8 @@
 
 <body>
 
-<h2><a name="attrib">Attrib</a></h2>
-<p><em>Since Apache Ant 1.6.</em></p>
+<h2 id="attrib">Attrib</h2>
+<p><em>Since Apache Ant 1.6</em>.</p>
 <h3>Description</h3>
 
 <p>Changes the attributes of a file or all files inside specified
@@ -33,13 +33,13 @@
 4 possible permissions has its own attribute, matching the arguments
 for the attrib command.</p>
 
-<p><a href="../Types/fileset.html">FileSet</a>s, 
+<p><a href="../Types/fileset.html">FileSet</a>s,
 <a href="../Types/dirset.html">DirSet</a>s or <a
 href="../Types/filelist.html">FileList</a>s can be specified using
-nested <code>&lt;fileset&gt;</code>, <code>&lt;dirset&gt;</code> and 
+nested <code>&lt;fileset&gt;</code>, <code>&lt;dirset&gt;</code> and
 <code>&lt;filelist&gt;</code> elements.</p>
 
-<p>Starting with Ant 1.7, this task supports arbitrary <a
+<p><em>Since Ant 1.7</em>, this task supports arbitrary <a
 href="../Types/resources.html#collection">Resource Collection</a>s
 as nested elements.</p>
 
@@ -57,24 +57,27 @@
   the Windows command, you can use the task's os attribute and set its
   value to your current os.</p>
 
+<p>See the <a href="setpermissions.html">setpermissions</a> task for a
+  platform independent alternative.</p>
+
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
-    <td align="center" valign="top"><b>Required</b></td>
+    <td valign="top" align="center"><b>Required</b></td>
   </tr>
   <tr>
     <td valign="top">file</td>
     <td valign="top">the file or directory of which the permissions must be
     changed.</td>
-    <td valign="top" valign="middle">Yes or nested
-    <code>&lt;fileset/list&gt;</code> elements.</td>
+    <td valign="top" align="center">Yes, or nested
+    <code>&lt;fileset/list&gt;</code> elements</td>
   </tr>
   <tr>
     <td valign="top">readonly</td>
     <td valign="top">the readonly permission.</td>
-    <td valign="top" rowspan="4">at least one of the four. </td>
+    <td valign="top" rowspan="4">At least one of the four</td>
   </tr>
   <tr>
     <td valign="top">archive</td>
@@ -93,7 +96,7 @@
     <td valign="top">One of <i>file</i>, <i>dir</i> or <i>both</i>. If set to
       <i>file</i>, only the permissions of plain files are going to be changed.
       If set to <i>dir</i>, only the directories are considered.<br>
-      <strong>Note:</strong> The type attribute does not apply to
+      <strong>Note</strong>: The type attribute does not apply to
       nested <i>dirset</i>s - <i>dirset</i>s always implicitly
       assume type to be <i>dir</i>.</td>
     <td align="center" valign="top">No, default is <i>file</i></td>
@@ -114,7 +117,7 @@
     <td valign="top">maxparallel</td>
     <td valign="top">Limit the amount of parallelism by passing at
       most this many sourcefiles at once.  Set it to &lt;= 0 for
-      unlimited.  Defaults to unlimited.  <em>Since Ant 1.6.</em></td>
+      unlimited.  Defaults to unlimited.  <em>Since Ant 1.6</em>.</td>
     <td align="center" valign="top">No</td>
   </tr-->
   <tr>
@@ -161,7 +164,5 @@
   to a FileSet with <code>id</code> <code>other.shared.sources</code> get the
   same attributes.</p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/augment.html b/manual/Tasks/augment.html
index 305e39a..6699be8 100644
--- a/manual/Tasks/augment.html
+++ b/manual/Tasks/augment.html
@@ -32,10 +32,10 @@
 processing mechanisms to reload a previously declared reference by means of the 'id'
 attribute, then treats the declared <code>augment</code> element as though it were the
 original element.
-<b>Since Apache Ant 1.8.1</b></p>
+<em>Since Apache Ant 1.8.1</em></p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
diff --git a/manual/Tasks/available.html b/manual/Tasks/available.html
index 6e4a171..bda0f58 100644
--- a/manual/Tasks/available.html
+++ b/manual/Tasks/available.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="available">Available</a></h2>
+<h2 id="available">Available</h2>
 <h3>Description</h3>
 <p>Sets a property if a resource is available at runtime. This resource can be a
 file, a directory, a class in the classpath, or a JVM system resource.</p>
@@ -34,7 +34,7 @@
 <p>Normally, this task is used to set properties that are useful to avoid target
 execution depending on system parameters.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -154,7 +154,5 @@
 if the resource-file <code>extratasks.properties</code> is found.
 </p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/basename.html b/manual/Tasks/basename.html
index 0822d8f..b185b24 100644
--- a/manual/Tasks/basename.html
+++ b/manual/Tasks/basename.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="echo">Basename</a></h2>
+<h2 id="echo">Basename</h2>
 <h3>Description</h3>
 <p>
 Task to determine the basename of a specified file, optionally minus a
@@ -37,9 +37,9 @@
 <code>file</code> is a full-path, relative-path, or simple filename,
 the basename will be the simple file name, without any directory elements.
 </p>
-<p> 
+<p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -81,12 +81,8 @@
 &lt;property environment=&quot;env&quot;/&gt;
 &lt;basename property=&quot;temp.dirname&quot; file=&quot;${env.TEMP}&quot;/&gt;
 </pre></blockquote>
-
 will set <code>temp.dirname</code> to the last directory element of
-the path defined for the <code>TEMP</code> environment variable.</p>
-
-
+the path defined for the <code>TEMP</code> environment variable.
 
 </body>
 </html>
-
diff --git a/manual/Tasks/bindtargets.html b/manual/Tasks/bindtargets.html
index d8374a4..fdf679f 100644
--- a/manual/Tasks/bindtargets.html
+++ b/manual/Tasks/bindtargets.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="ant">Bindtargets</a></h2>
+<h2 id="ant">Bindtargets</h2>
 <h3>Description</h3>
 
 <p>Make some target the extension of some defined
@@ -40,7 +40,7 @@
 target dependencies but only in your context.
 </p>
 
-<p>Note: this task is quite equivalent to the definition of an intermediate
+<p><strong>Note</strong>: this task is quite equivalent to the definition of an intermediate
 target which will be the bridge between the target to bind and the extension
 point. For instance:
 </p>
@@ -55,10 +55,10 @@
 it may not be used in a target. This is making the target dependency graph static
 and predictable as soon as every build file is loaded.</p>
 
-<p><b>Since Apache Ant 1.8.2</b></p>
+<p><em>Since Apache Ant 1.8.2</em></p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
diff --git a/manual/Tasks/buildnumber.html b/manual/Tasks/buildnumber.html
index aaaa14c..7351e22 100644
--- a/manual/Tasks/buildnumber.html
+++ b/manual/Tasks/buildnumber.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="buildnumber">BuildNumber</a></h2>
+<h2 id="buildnumber">BuildNumber</h2>
 <h3>Description</h3>
 <p>This is a basic task that can be used to track build numbers.</p>
 <p>It will first attempt to read a build number from a file (by default,
@@ -39,7 +39,7 @@
 </p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -67,8 +67,5 @@
 <p>Read, increment, and write a build number to the file
 <code>mybuild.number</code>.</p>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/cab.html b/manual/Tasks/cab.html
index e981827..6d7a4d6 100644
--- a/manual/Tasks/cab.html
+++ b/manual/Tasks/cab.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="cab">Cab</a></h2>
+<h2 id="cab">Cab</h2>
 <h3>Description</h3>
 <p>The cab task creates Microsoft cab archive files.  It is invoked
 similar to the <a href="../Tasks/jar.html">jar</a> or <a href="../Tasks/zip.html">zip</a> tasks.
@@ -42,7 +42,7 @@
 <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
 <code>&lt;patternset&gt;</code> elements.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -120,16 +120,14 @@
 <h3>Examples</h3>
 <blockquote><pre>
 &lt;cab cabfile=&quot;${dist}/manual.cab&quot;
-     basedir=&quot;htdocs/manual&quot;
-  /&gt;
+     basedir=&quot;htdocs/manual&quot;/&gt;
 </pre></blockquote>
 <p>cabs all files in the htdocs/manual directory into a file called
 manual.cab in the ${dist} directory.</p>
 <blockquote><pre>
 &lt;cab cabfile=&quot;${dist}/manual.cab&quot;
      basedir=&quot;htdocs/manual&quot;
-     excludes=&quot;mydocs/**, **/todo.html&quot;
-  /&gt;
+     excludes=&quot;mydocs/**, **/todo.html&quot;/&gt;
 </pre></blockquote>
 <p>cabs all files in the htdocs/manual directory into a file called
 manual.cab in the ${dist} directory. Files in the directory mydocs,
@@ -139,8 +137,7 @@
      basedir=&quot;htdocs/manual&quot;
      includes=&quot;api/**/*.html&quot;
      excludes=&quot;**/todo.html&quot;
-     verbose=&quot;yes&quot;
-  /&gt;
+     verbose=&quot;yes&quot;/&gt;
 </pre></blockquote>
 <p>Cab all files in the htdocs/manual directory into a file called
 manual.cab in the ${dist} directory. Only html files under the
@@ -154,14 +151,10 @@
   &lt;fileset
        dir=&quot;htdocs/manual&quot;
        includes=&quot;api/**/*.html&quot;
-       excludes=&quot;**/todo.html&quot;
-  /&gt;
+       excludes=&quot;**/todo.html&quot;/&gt;
 &lt;/cab&gt;
 </pre></blockquote>
 <p>is equivalent to the example above.</p>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/ccm.html b/manual/Tasks/ccm.html
index 9f4725f..8e22909 100644
--- a/manual/Tasks/ccm.html
+++ b/manual/Tasks/ccm.html
@@ -35,12 +35,12 @@
 
 <p>These Apache Ant tasks are wrappers around Continuus Source Manager. They have been tested
   against versions 5.1/6.2 on Windows 2000, but should work on other platforms with ccm installed.</p>
-<hr>
-<h2><a name="ccmcheckin">CCMCheckin</a></h2>
+<hr/>
+<h2 id="ccmcheckin">CCMCheckin</h2>
 <h3>Description</h3>
 Task to checkin a file
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0" width="598">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -76,12 +76,12 @@
 <p>Checks in the file <i>c:/wa/com/foo/MyFile.java</i>.
   Comment attribute <i>mycomment</i> is added as a task comment. The task
   used is the one set as the default.</p>
-<hr>
-<h2><a name="ccmcheckout">CCMCheckout</a></h2>
+<hr/>
+<h2 id="ccmcheckout">CCMCheckout</h2>
 <h3>Description</h3>
 Task to perform a Checkout command to Continuus
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0" width="614">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -90,7 +90,7 @@
   <tr>
     <td>file</td>
     <td>Path to the file that the command will operate on</td>
-    <td rowspan=2">Yes (file|fileset)</td>
+    <td rowspan="2">Yes (file|fileset)</td>
   </tr>
   <tr>
     <td>fileset</td>
@@ -134,15 +134,12 @@
 <p>Check out all the files in the <i>lib</i> directory having the <i>.jar</i> extension.
   Comment attribute <i>mycomment</i> is added as a task comment
    The used task is the one set as the default.</p>
-
-
-
-<hr>
-<h2><a name="ccmcheckintask">CCMCheckinTask</a></h2>
+<hr/>
+<h2 id="ccmcheckintask">CCMCheckinTask</h2>
 <h3>Description</h3>
 Task to perform a check in default task command to Continuus
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -164,18 +161,18 @@
     <td>No</td>
   </tr>
 </table>
-<h3>Examples </h3>
+<h3>Examples</h3>
 <blockquote>
   <pre>&lt;ccmcheckintask comment=&quot;blahblah/&gt;
 </pre>
 </blockquote>
 <p>Does a Checkin default task on all the checked out files in the current task.</p>
-<hr>
-<h2><a name="ccmreconfigure">CCMReconfigure</a></h2>
+<hr/>
+<h2 id="ccmreconfigure">CCMReconfigure</h2>
 <h3>Description</h3>
 Task to perform an reconfigure command to Continuus.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -210,12 +207,12 @@
 </blockquote>
 <p>Does a Continuus <i>reconfigure</i> on the project <i>ANTCCM_TEST#BMO_1</i>.
 </p>
-<hr>
-<h2><a name="ccmcreatetask">CCMCreateTask</a></h2>
+<hr/>
+<h2 id="ccmcreatetask">CCMCreateTask</h2>
 <h3>Description</h3>
 Create a Continuus task.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -266,7 +263,5 @@
 <p>Creates a task for the release <i>ANTCCM_TEST</i> with the
   current user as the resolver for this task.</p>
 
-
 </body>
-
 </html>
diff --git a/manual/Tasks/changelog.html b/manual/Tasks/changelog.html
index 8d9a70b..b09e1c0 100644
--- a/manual/Tasks/changelog.html
+++ b/manual/Tasks/changelog.html
@@ -24,20 +24,20 @@
 
 <body>
 
-<h2><a name="changelog">CvsChangeLog</a></h2>
+<h2 id="changelog">CvsChangeLog</h2>
 <h3>Description</h3>
 <p>Generates an XML-formatted report file of the change logs recorded in a
-<a href="http://www.nongnu.org/cvs/" target="_top">CVS</a> repository. </p>
+<a href="http://www.nongnu.org/cvs/" target="_top">CVS</a> repository.</p>
 <p><b>Important:</b> This task needs &quot;<code>cvs</code>&quot; on the path. If it isn't, you will get
-an error (such as error <code>2</code> on windows). If <code>&lt;cvs&gt;</code> doesn't work, try to execute <code>cvs.exe</code>
+an error (such as error <code>2</code> on Windows). If <code>&lt;cvs&gt;</code> doesn't work, try to execute <code>cvs.exe</code>
 from the command line in the target directory in which you are working.
 Also note that this task assumes that the cvs executable is compatible
-with the Unix version from cvshome.org, this is not completely true
-for certain other cvs clients - like CVSNT for example - and some
+with the Unix version, this is not completely true
+for certain other CVS clients - like CVSNT for example - and some
 operation may fail when using such an incompatible client.
 </p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -45,7 +45,7 @@
   </tr>
   <tr>
     <td colspan="3">Attributes from parent Cvs task which are meaningful here<br>
-    Since Apache Ant 1.6.1</td>
+      <em>Since Apache Ant 1.6.1</em></td>
   </tr>
   <tr>
     <td valign="top">cvsRoot</td>
@@ -59,7 +59,7 @@
   </tr>
   <tr>
     <td valign="top">package</td>
-    <td valign="top">the package/module to check out.  <b>Note:</b>
+    <td valign="top">the package/module to check out.  <strong>Note</strong>:
       multiple attributes can be split using spaces.  Use a nested
       &lt;module&gt; element if you want to specify a module with
       spaces in its name.</td>
@@ -129,7 +129,7 @@
     <td valign="top">remote</td>
     <td valign="top">If set to true, works against the repository
       (using rlog) without a working copy.  Default is
-      false.  <em>Since Ant 1.8.0</em></td>
+      false. <em>Since Ant 1.8.0</em></td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
@@ -137,7 +137,7 @@
     <td valign="top">The start of a tag range. If endTag is also
       specified, they must both be on the same branch. If endTag is not
       specified, the end of the range will be the latest on the same
-      branch on which startTag lives.  <em>Since Ant 1.8.0</em></td>
+      branch on which startTag lives. <em>Since Ant 1.8.0</em></td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
@@ -145,14 +145,13 @@
     <td valign="top">The end of a tag range. If startTag is also
      specified, they must both be on the same branch. If startTag is
      not specified, the start of the range will be the top of the
-     branch on which endTag lives.</td>  included in the report.
-    <em>Since Ant 1.8.0</em></td>
+     branch on which endTag lives. <em>Since Ant 1.8.0</em></td>
     <td align="center" valign="top">No</td>
   </tr>
 </table>
 
 <h3>Parameters specified as nested elements</h3>
-<h4><a name="user">user</a></h4>
+<h4 id="user">user</h4>
 <p>The nested <code>&lt;user&gt;</code> element allows you to specify a
 mapping between a user ID as it appears on the CVS server and a name to
 include in the formatted report.
@@ -161,7 +160,7 @@
 the name specified in <code>displayname</code> rather than the user ID.
 </p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -186,7 +185,7 @@
   modules specified using this attribute can contain spaces in their
   name.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -201,8 +200,7 @@
 
 <h3>Examples</h3>
 <pre>  &lt;cvschangelog dir=&quot;dve/network&quot;
-                destfile=&quot;changelog.xml&quot;
-  /&gt;</pre>
+                destfile=&quot;changelog.xml&quot;/&gt;</pre>
 
 <p>Generates a change log report for all the changes that have been made
 under the <code>dve/network</code> directory.
@@ -210,8 +208,7 @@
 
 <pre>  &lt;cvschangelog dir=&quot;dve/network&quot;
                 destfile=&quot;changelog.xml&quot;
-                daysinpast=&quot;10&quot;
-  /&gt;</pre>
+                daysinpast=&quot;10&quot;/&gt;</pre>
 
 <p>Generates a change log report for any changes that were made
 under the <code>dve/network</code> directory in the past 10 days.
@@ -220,8 +217,7 @@
 <pre>  &lt;cvschangelog dir=&quot;dve/network&quot;
                 destfile=&quot;changelog.xml&quot;
                 start=&quot;20 Feb 2002&quot;
-                end=&quot;20 Mar 2002&quot;
-  /&gt;</pre>
+                end=&quot;20 Mar 2002&quot;/&gt;</pre>
 
 <p>Generates a change log report for any changes that were made
 between February 20, 2002 and March 20, 2002
@@ -230,8 +226,7 @@
 
 <pre>  &lt;cvschangelog dir=&quot;dve/network&quot;
                 destfile=&quot;changelog.xml&quot;
-                start=&quot;20 Feb 2002&quot;
-  /&gt;</pre>
+                start=&quot;20 Feb 2002&quot;/&gt;</pre>
 
 <p>Generates a change log report for any changes that were made
 after February 20, 2002 under the <code>dve/network</code> directory.
@@ -254,13 +249,13 @@
                 destfile=&quot;changelogant.xml&quot; tag=&quot;ANT_16_BRANCH&quot;/&gt;
 </pre>
 <h4>Generate Report</h4>
-<p>Ant includes a basic XSLT stylesheet that you can use to generate 
+<p>Ant includes a basic XSLT stylesheet that you can use to generate
 a HTML report based on the xml output. The following example illustrates
 how to generate a HTML report from the XML report.</p>
 
 <pre>
-        &lt;style in="changelog.xml" 
-               out="changelog.html" 
+        &lt;style in="changelog.xml"
+               out="changelog.html"
                style="${ant.home}/etc/changelog.xsl"&gt;
           &lt;param name="title" expression="Ant ChangeLog"/&gt;
           &lt;param name="module" expression="ant"/&gt;
@@ -287,8 +282,5 @@
 &lt;/changelog&gt;
 </pre>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/checksum.html b/manual/Tasks/checksum.html
index 29f48dd..8abb45f 100644
--- a/manual/Tasks/checksum.html
+++ b/manual/Tasks/checksum.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="checksum">Checksum</a></h2>
+<h2 id="checksum">Checksum</h2>
 <h3>Description</h3>
 <p>
 Generates checksum for files.  This task can also be used to
@@ -53,7 +53,7 @@
 </p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -62,8 +62,8 @@
   <tr>
     <td valign="top">file</td>
     <td valign="top">The file to generate checksum for.</td>
-    <td valign="top" align="center">One of either <var>file</var> or
-    at least one nested (filesystem-only) resource collection.</td>
+    <td valign="top" align="center">Yes, unless
+    at least one nested (filesystem-only) resource collection is specified.</td>
   </tr>
   <tr>
     <td valign="top">todir</td>
@@ -119,7 +119,7 @@
     where <code>{0}</code> is replaced with the checksum and
       <code>{1}</code> with the file name. <em>Since Ant
       1.7.0</em><br/>
-      <em>starting with Ant 1.8.2</em> <code>{2}</code> is replaced by
+      <em>Since Ant 1.8.2</em> <code>{2}</code> is replaced by
       the path of the file relative to the checksum file being
       written, <code>{3}</code> with tha path of the file relative to
       the project's basedir and <code>{4}</code> with the absolute
@@ -129,27 +129,27 @@
   <tr>
     <td valign="top">format</td>
     <td valign="top">Specifies the pattern to use as one of a
-    well-known format.  Supported values are 
-      <table border="1">
+    well-known format.  Supported values are
+      <table>
       <tr>
         <th>name</th>
         <th>pattern</th>
         <th>description</th>
       </tr>
       <tr>
-        <td>CHECKSUM </td>
+        <td>CHECKSUM</td>
         <td><tt>{0}</tt></td>
-        <td>only the checksum itself </td>
+        <td>only the checksum itself</td>
       </tr>
       <tr>
-        <td>MD5SUM </td>
+        <td>MD5SUM</td>
         <td><tt>{0} *{1}</tt></td>
         <td>the format of GNU textutils md5sum</td>
       </tr>
       <tr>
-        <td>SVF </td>
+        <td>SVF</td>
         <td><tt>MD5 ({1}) = {0}</tt></td>
-        <td>the format of BSDs md5 command </td>
+        <td>the format of BSDs md5 command</td>
       </tr>
       </table>
        <em>Since Ant 1.7.0</em>
@@ -256,14 +256,10 @@
 checksum matches - it will never be set to false.  This example
 demonstrates use with the Condition task.
 
-
 <h3>Note:</h3>
 When working with more than one file, if condition and/or verifyproperty is used,
 the result will be true only if the checksums matched correctly for all files being
 considered.
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/chgrp.html b/manual/Tasks/chgrp.html
index 2126fb7..a56c1ad 100644
--- a/manual/Tasks/chgrp.html
+++ b/manual/Tasks/chgrp.html
@@ -24,8 +24,8 @@
 
 <body>
 
-<h2><a name="Chgrp">Chgrp</a></h2>
-<p><em>Since Apache Ant 1.6.</em></p>
+<h2 id="chgrp">Chgrp</h2>
+<p><em>Since Apache Ant 1.6</em>.</p>
 <h3>Description</h3>
 
 <p>Changes the group of a file or all files inside specified
@@ -33,13 +33,13 @@
 attribute is equivalent to the corresponding argument for the chgrp
 command.</p>
 
-<p><a href="../Types/fileset.html">FileSet</a>s, 
+<p><a href="../Types/fileset.html">FileSet</a>s,
 <a href="../Types/dirset.html">DirSet</a>s or <a
 href="../Types/filelist.html">FileList</a>s can be specified using
-nested <code>&lt;fileset&gt;</code>, <code>&lt;dirset&gt;</code> and 
+nested <code>&lt;fileset&gt;</code>, <code>&lt;dirset&gt;</code> and
 <code>&lt;filelist&gt;</code> elements.</p>
 
-<p>Starting with Ant 1.7, this task supports arbitrary <a
+<p><em>Since Ant 1.7</em>, this task supports arbitrary <a
 href="../Types/resources.html#collection">Resource Collection</a>s
 as nested elements.</p>
 
@@ -61,17 +61,17 @@
   value to your current os.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
-    <td align="center" valign="top"><b>Required</b></td>
+    <td valign="top" align="center"><b>Required</b></td>
   </tr>
   <tr>
     <td valign="top">file</td>
     <td valign="top">the file or directory of which the group must be
     changed.</td>
-    <td valign="top" valign="middle">Yes, unless nested
+    <td valign="top" align="center">Yes, unless nested
       <code>&lt;fileset|filelist|dirset&gt;</code>
       elements are specified</td>
   </tr>
@@ -92,7 +92,7 @@
       <i>both</i>. If set to <i>file</i>, only the group of
       plain files are going to be changed. If set to <i>dir</i>, only
       the directories are considered.<br>
-      <strong>Note:</strong> The type attribute does not apply to
+      <strong>Note</strong>: The type attribute does not apply to
       nested <i>dirset</i>s - <i>dirset</i>s always implicitly
       assume type to be <i>dir</i>.</td>
     <td align="center" valign="top">No, default is <i>file</i></td>
@@ -153,7 +153,7 @@
 </pre>
 </blockquote>
 <p>makes all files below <code>shared/sources1</code> (except those
-below any directory named trial) belong to the coders group on a UNIX 
+below any directory named trial) belong to the coders group on a UNIX
 system. In addition all files belonging to a FileSet
 with <code>id</code> <code>other.shared.sources</code> get the same
 group.</p>
@@ -172,14 +172,10 @@
 </pre>
 </blockquote>
 
-<p>makes all <code>.test.jsp</code>, and <code>.new</code> files belong to 
-group webdev. Directories beginning with <code>test_</code> also will belong 
+<p>makes all <code>.test.jsp</code>, and <code>.new</code> files belong to
+group webdev. Directories beginning with <code>test_</code> also will belong
 to webdev, but if there is a directory that ends in <code>.new</code> or a file
 that begins with <code>test_</code> it will be unaffected.</p>
 
-
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/chmod.html b/manual/Tasks/chmod.html
index 74e71d0..5dd369a 100644
--- a/manual/Tasks/chmod.html
+++ b/manual/Tasks/chmod.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="chmod">Chmod</a></h2>
+<h2 id="chmod">Chmod</h2>
 <h3>Description</h3>
 <p>Changes the permissions of a file or all files inside specified
 directories. Right now it has effect only under Unix or NonStop Kernel (Tandem).
@@ -37,12 +37,12 @@
 href="../Types/fileset.html">FileSet</a> and supports all of
 FileSet's attributes and nested elements directly. More sets can be
 specified using nested <code>&lt;fileset&gt;</code> or
-<code>&lt;dirset&gt;</code> (<em>since Apache Ant 1.6</em>) elements. </p>
+<code>&lt;dirset&gt;</code> (<em>since Apache Ant 1.6</em>) elements.</p>
 
-<p>Starting with Ant 1.6, this task also supports nested <a
+<p><em>Since Ant 1.6</em>, this task also supports nested <a
 href="../Types/filelist.html">filelist</a>s.</p>
 
-<p>Starting with Ant 1.7, this task supports arbitrary <a
+<p><em>Since Ant 1.7</em>, this task supports arbitrary <a
 href="../Types/resources.html#collection">Resource Collection</a>s
 as nested elements.</p>
 
@@ -63,24 +63,27 @@
   the Unix command, you can use the task's os attribute and set its
   value to your current os.</p>
 
+<p>See the <a href="setpermissions.html">setpermissions</a> task for a
+  platform independent alternative.</p>
+
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
-    <td align="center" valign="top"><b>Required</b></td>
+    <td valign="top" align="center"><b>Required</b></td>
   </tr>
   <tr>
     <td valign="top">file</td>
-    <td valign="top">the file or single directory of which the permissions 
+    <td valign="top">the file or single directory of which the permissions
       must be changed.</td>
-    <td valign="top" valign="middle" rowspan="2">exactly one of the two or nested <code>&lt;fileset/list&gt;</code> elements.</td>
+    <td valign="top" align="center" rowspan="2">Exactly one of the two, or nested <code>&lt;fileset/list&gt;</code>s</td>
   </tr>
   <tr>
     <td valign="top">dir</td>
-    <td valign="top">the directory which holds the files whose permissions 
+    <td valign="top">the directory which holds the files whose permissions
       must be changed.<br/>
-      <b>Note:</b> for backwards compatibility
+      <strong>Note</strong>: for backwards compatibility
       reasons <code>&lt;chmod&nbsp;dir="some-dir"/&gt;</code> will
       only change the permissions on "some-dir" but not recurse into
       it, unless you also specify any patterns.</td>
@@ -120,7 +123,7 @@
       <i>both</i>. If set to <i>file</i>, only the permissions of
       plain files are going to be changed. If set to <i>dir</i>, only
       the directories are considered.<br>
-      <strong>Note:</strong> The type attribute does not apply to
+      <strong>Note</strong>: The type attribute does not apply to
       nested <i>dirset</i>s - <i>dirset</i>s always implicitly
       assume type to be <i>dir</i>.</td>
     <td align="center" valign="top">No, default is <i>file</i></td>
@@ -129,13 +132,13 @@
     <td valign="top">maxparallel</td>
     <td valign="top">Limit the amount of parallelism by passing at
       most this many sourcefiles at once.  Set it to &lt;= 0 for
-      unlimited.  Defaults to unlimited.  <em>Since Ant 1.6.</em></td>
+      unlimited.  Defaults to unlimited.  <em>Since Ant 1.6</em>.</td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
     <td valign="top">verbose</td>
     <td valign="top">Whether to print a summary after execution or not.
-      Defaults to <code>false</code>.  <em>Since Ant 1.6.</em></td>
+      Defaults to <code>false</code>.  <em>Since Ant 1.6</em>.</td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
@@ -164,7 +167,7 @@
 UNIX system.</p>
 <blockquote>
 <pre>
-&lt;chmod dir=&quot;${dist}/bin&quot; perm=&quot;ugo+rx&quot; 
+&lt;chmod dir=&quot;${dist}/bin&quot; perm=&quot;ugo+rx&quot;
        includes=&quot;**/*.sh&quot;/&gt;
 </pre>
 </blockquote>
@@ -201,7 +204,7 @@
 </blockquote>
 
 <p>keeps non-owners from touching cgi scripts, files with a <code>.old</code>
-extension or directories beginning with <code>private_</code>. A directory 
+extension or directories beginning with <code>private_</code>. A directory
 ending in <code>.old</code> or a file beginning with private_ would remain
 unaffected.</p>
 
@@ -209,17 +212,16 @@
   <h3>Note on maxparallel attribute</h3>
   <p>
     Some shells have a limit of the number of characters that
-    a command line may contain. 
+    a command line may contain.
     This maximum limit varies from shell to shell and from operating
     system to operating system.
     If one has a large number of files to change mode on, consider
     using the <em>maxparallel</em> attribute. For example
     when using AIX and the limit is reached, the system responds
-    with a warning: "Warning: 
+    with a warning: "Warning:
     UNIXProcess.forkAndExec native error: The parameter or environment lists
     are too long". A value of about 300 seems to result in a
     command line that is acceptable.
   </p>
 </body>
 </html>
-
diff --git a/manual/Tasks/chown.html b/manual/Tasks/chown.html
index 33a9f44..587878a 100644
--- a/manual/Tasks/chown.html
+++ b/manual/Tasks/chown.html
@@ -24,8 +24,8 @@
 
 <body>
 
-<h2><a name="Chown">Chown</a></h2>
-<p><em>Since Apache Ant 1.6.</em></p>
+<h2 id="chown">Chown</h2>
+<p><em>Since Apache Ant 1.6</em>.</p>
 <h3>Description</h3>
 
 <p>Changes the owner of a file or all files inside specified
@@ -33,13 +33,13 @@
 attribute is equivalent to the corresponding argument for the chown
 command.</p>
 
-<p><a href="../Types/fileset.html">FileSet</a>s, 
+<p><a href="../Types/fileset.html">FileSet</a>s,
 <a href="../Types/dirset.html">DirSet</a>s or <a
 href="../Types/filelist.html">FileList</a>s can be specified using
-nested <code>&lt;fileset&gt;</code>, <code>&lt;dirset&gt;</code> and 
+nested <code>&lt;fileset&gt;</code>, <code>&lt;dirset&gt;</code> and
 <code>&lt;filelist&gt;</code> elements.</p>
 
-<p>Starting with Ant 1.7, this task supports arbitrary <a
+<p><em>Since Ant 1.7</em>, this task supports arbitrary <a
 href="../Types/resources.html#collection">Resource Collection</a>s
 as nested elements.</p>
 
@@ -61,7 +61,7 @@
   value to your current os.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -71,7 +71,7 @@
     <td valign="top">file</td>
     <td valign="top">the file or directory of which the owner must be
     changed.</td>
-    <td valign="top" valign="middle">Yes or nested
+    <td valign="top" align="center">Yes or nested
     <code>&lt;fileset/list&gt;</code> elements.</td>
   </tr>
   <tr>
@@ -91,7 +91,7 @@
       <i>both</i>. If set to <i>file</i>, only the owner of
       plain files are going to be changed. If set to <i>dir</i>, only
       the directories are considered.<br>
-      <strong>Note:</strong> The type attribute does not apply to
+      <strong>Note</strong>: The type attribute does not apply to
       nested <i>dirset</i>s - <i>dirset</i>s always implicitly
       assume type to be <i>dir</i>.</td>
     <td align="center" valign="top">No, default is <i>file</i></td>
@@ -152,7 +152,7 @@
 </pre>
 </blockquote>
 <p>makes all files below <code>shared/sources1</code> (except those
-below any directory named trial) belong to coderjoe on a UNIX 
+below any directory named trial) belong to coderjoe on a UNIX
 system. In addition all files belonging to a FileSet
 with <code>id</code> <code>other.shared.sources</code> get the same
 owner.</p>
@@ -173,11 +173,8 @@
 
 <p>makes cgi scripts, files with a <code>.old</code> extension or
 directories beginning with <code>private_</code> belong to the user named
-webadmin. A directory ending in <code>.old</code> or a file beginning with 
+webadmin. A directory ending in <code>.old</code> or a file beginning with
 <code>private_</code> would remain unaffected.</p>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/clearcase.html b/manual/Tasks/clearcase.html
index 902d5ef..18e4e66 100644
--- a/manual/Tasks/clearcase.html
+++ b/manual/Tasks/clearcase.html
@@ -35,25 +35,25 @@
 <h1>ClearCase Support</h1>
 <h2>Table of Contents</h2>
 <ul>
-  <li><A href="#introduction">Introduction</a>
-  <li><A href="#cccheckin">CCCheckin</a>
-  <li><A href="#cccheckout">CCCheckout</a>
-  <li><A href="#ccuncheckout">CCUnCheckout</a>
-  <li><A href="#ccupdate">CCUpdate</a>
-  <li><A href="#ccmklbtype">CCMklbtype</a>
-  <li><A href="#ccmklabel">CCMklabel</a>
-  <li><A href="#ccrmtype">CCRmtype</a>
-  <li><A href="#cclock">CCLock</a>
-  <li><A href="#ccunlock">CCUnlock</a>
-  <li><A href="#ccmkbl">CCMkbl</a>
-  <li><A href="#ccmkattr">CCMkattr</a>
-  <li><A href="#ccmkdir">CCMkdir</a>
-  <li><A href="#ccmkelem">CCMkelem</a></li>
+  <li><a href="#introduction">Introduction</a>
+  <li><a href="#cccheckin">CCCheckin</a>
+  <li><a href="#cccheckout">CCCheckout</a>
+  <li><a href="#ccuncheckout">CCUnCheckout</a>
+  <li><a href="#ccupdate">CCUpdate</a>
+  <li><a href="#ccmklbtype">CCMklbtype</a>
+  <li><a href="#ccmklabel">CCMklabel</a>
+  <li><a href="#ccrmtype">CCRmtype</a>
+  <li><a href="#cclock">CCLock</a>
+  <li><a href="#ccunlock">CCUnlock</a>
+  <li><a href="#ccmkbl">CCMkbl</a>
+  <li><a href="#ccmkattr">CCMkattr</a>
+  <li><a href="#ccmkdir">CCMkdir</a>
+  <li><a href="#ccmkelem">CCMkelem</a></li>
 
 </ul>
 
-<hr>
-<h2><a name="introduction">Introduction</a></h2>
+<hr/>
+<h2 id="introduction">Introduction</h2>
 <p>Apache Ant provides several optional tasks for working with ClearCase. These tasks correspond to various
 ClearCase commands using the Cleartool program. The current tasks available for Ant correspond to only
 a few of the significant ClearCase commands.</p>
@@ -67,12 +67,12 @@
 </p>
 
 
-<hr>
-<h2><a name="cccheckin">CCCheckin</a></h2>
+<hr/>
+<h2 id="cccheckin">CCCheckin</h2>
 <h3>Description</h3>
 Task to perform a "cleartool checkin" command to ClearCase.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -86,14 +86,12 @@
   </tr>
   <tr>
     <td>comment</td>
-    <td>Specify a comment. Only one of comment or commentfile may be used.</td>
-    <td>No</td>
+    <td>Specify a comment</td>
+    <td rowspan="2">No; only one of the two may be used</td>
   </tr>
   <tr>
     <td>commentfile</td>
-    <td>Specify a file containing a comment. Only one of comment or commentfile
-        may be used.</td>
-    <td>No</td>
+    <td>Specify a file containing a comment</td>
   </tr>
   <tr>
     <td>nowarn</td>
@@ -135,12 +133,12 @@
 Comment text from the file <i>acomment.txt</i> is added to ClearCase as a comment.
 All warning messages are suppressed. The file is checked in even if it is
 <i>identical</i> to the original.</p>
-<hr>
-<h2><a name="cccheckout">CCCheckout</a></h2>
+<hr/>
+<h2 id="cccheckout">CCCheckout</h2>
 <h3>Description</h3>
 Task to perform a "cleartool checkout" command to ClearCase.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -185,25 +183,23 @@
   </tr>
   <tr>
     <td>comment</td>
-    <td>Specify a comment. Only one of comment or commentfile may be used.</td>
-    <td>No</td>
+    <td>Specify a comment</td>
+    <td rowspan="2">No; only one of the two may be used</td>
   </tr>
   <tr>
     <td>commentfile</td>
-    <td>Specify a file containing a comment. Only one of comment or
-        commentfile may be used.</td>
-    <td>No</td>
+    <td>Specify a file containing a comment</td>
   </tr>
   <tr>
     <td>notco</td>
     <td>Fail if it's already checked out to the current view. Set to false to ignore it.<br>
-    Since ant 1.6.1</td>
+    <em>Since Ant 1.6.1</em></td>
     <td>No</td>
   </tr>
   <tr>
     <td>failonerr</td>
     <td>Throw an exception if the command fails. Default is true.<br>
-    Since ant 1.6.1</td>
+    <em>Since Ant 1.6.1</em></td>
     <td>No</td>
   </tr>
 </table>
@@ -221,12 +217,12 @@
 It is checked out as <i>reserved</i> on branch called <i>abranch</i>. All
 warning messages are suppressed. A <i>Some comment text</i> is added to
 ClearCase as a comment.</p>
-<hr>
-<h2><a name="ccuncheckout">CCUnCheckout</a></h2>
+<hr/>
+<h2 id="ccuncheckout">CCUnCheckout</h2>
 <h3>Description</h3>
 Task to perform a UnCheckout command to ClearCase.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -246,8 +242,8 @@
   </tr>
   <tr>
     <td>failonerr</td>
-    <td>Throw an exception if the command fails. Default is true<br>
-    Since ant 1.6.1</td>
+    <td>Throw an exception if the command fails. Default is true.<br>
+    <em>Since Ant 1.6.1</em></td>
     <td>No</td>
   </tr>
 </table>
@@ -260,12 +256,12 @@
 </blockquote>
 <p>Does a ClearCase <i>uncheckout</i> on the file <i>c:/views/viewdir/afile</i>.
 A copy of the file called <i>c:/views/viewdir/afile.keep</i> is kept.</p>
-<hr>
-<h2><a name="ccupdate">CCUpdate</a></h2>
+<hr/>
+<h2 id="ccupdate">CCUpdate</h2>
 <h3>Description</h3>
 Task to perform an "cleartool update" command to ClearCase.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -314,7 +310,7 @@
   <tr>
     <td>failonerr</td>
     <td>Throw an exception if the command fails. Default is true.<br>
-    Since ant 1.6.1</td>
+    <em>Since Ant 1.6.1</em></td>
     <td>No</td>
   </tr>
 </table>
@@ -333,15 +329,12 @@
 A graphical dialog will be displayed. The output will be logged to
 <i>log.log</i> and it will overwrite any hijacked files. The modified
 time will be set to the current time.</p>
-
-
-
-<hr>
-<h2><a name="ccmklbtype">CCMklbtype</a></h2>
+<hr/>
+<h2 id="ccmklbtype">CCMklbtype</h2>
 <h3>Description</h3>
 Task to perform a "mklbtype" command to ClearCase.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -351,51 +344,50 @@
     <td>typename</td>
     <td>Name of the label type to create</td>
     <td>Yes</td>
-  <tr>
+  </tr>
   <tr>
     <td>vob</td>
     <td>Name of the VOB</td>
     <td>No</td>
-  <tr>
+  </tr>
   <tr>
     <td>replace</td>
     <td>Replace an existing label definition of the same type</td>
     <td>No</td>
-  <tr>
+  </tr>
   <tr>
     <td>global</td>
     <td>Either global or ordinary can be specified, not both. Creates a label type that is global to the VOB or to VOBs that use this VOB</td>
     <td>No</td>
-  <tr>
+  </tr>
   <tr>
     <td>ordinary</td>
-    <td>Either global or ordinary can be specified, not both. Creates a label type that can be used only in the current VOB. <B>Default</B></td>
+    <td>Either global or ordinary can be specified, not both. Creates a label type that can be used only in the current VOB. <b>Default</b></td>
     <td>No</td>
-  <tr>
+  </tr>
   <tr>
     <td>pbranch</td>
     <td>Allows the label type to be used once per branch in a given element's version tree</td>
     <td>No</td>
-  <tr>
+  </tr>
   <tr>
     <td>shared</td>
     <td>Sets the way mastership is checked by ClearCase. See ClearCase documentation for details</td>
     <td>No</td>
-  <tr>
+  </tr>
   <tr>
     <td>comment</td>
-    <td>Specify a comment. Only one of comment or cfile may be used.</td>
-    <td>No</td>
-  <tr>
+    <td>Specify a comment</td>
+    <td rowspan="2">No; only one of the two may be used</td>
+  </tr>
   <tr>
     <td>commentfile</td>
-    <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
-    <td>No</td>
-  <tr></tr>
+    <td>Specify a file containing a comment</td>
+  </tr>
   <tr>
     <td>failonerr</td>
-    <td>Throw an exception if the command fails. Default is true<br>
-    Since ant 1.6.1</td>
+    <td>Throw an exception if the command fails. Default is true.<br>
+    <em>Since Ant 1.6.1</em></td>
     <td>No</td>
   </tr>
 </table>
@@ -411,14 +403,12 @@
 <p>Does a ClearCase <i>mklbtype</i> to create a label type named <i>VERSION_1</i>.
 It is created as <i>ordinary</i> so it is available only to the current VOB.
 The text <i>Development version 1</i> is added as a comment.</p>
-
-
-<hr>
-<h2><a name="ccmklabel">CCMklabel</a></h2>
+<hr/>
+<h2 id="ccmklabel">CCMklabel</h2>
 <h3>Description</h3>
 Task to perform a "mklabel" command to ClearCase.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -428,46 +418,45 @@
     <td>typename</td>
     <td>Name of the label type</td>
     <td>Yes</td>
-  <tr>
+  </tr>
   <tr>
     <td>viewpath</td>
     <td>Path to the ClearCase view file or directory that the command will operate on</td>
     <td>No</td>
-  <tr>
+  </tr>
   <tr>
     <td>replace</td>
     <td>Replace a label of the same type on the same branch</td>
     <td>No</td>
-  <tr>
+  </tr>
   <tr>
     <td>recurse</td>
     <td>Process each subdirectory under viewpath</td>
     <td>No</td>
-  <tr>
+  </tr>
   <tr>
     <td>version</td>
     <td>Identify a specific version to attach the label to</td>
     <td>No</td>
-  <tr>
+  </tr>
   <tr>
     <td>vob</td>
     <td>Name of the VOB</td>
     <td>No</td>
-  <tr>
+  </tr>
   <tr>
     <td>comment</td>
-    <td>Specify a comment. Only one of comment or cfile may be used.</td>
-    <td>No</td>
-  <tr>
+    <td>Specify a comment</td>
+    <td rowspan="2">No; only one of the two may be used</td>
+  </tr>
   <tr>
     <td>commentfile</td>
-    <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
-    <td>No</td>
-  <tr></tr>
+    <td>Specify a file containing a comment</td>
+  </tr>
   <tr>
     <td>failonerr</td>
-    <td>Throw an exception if the command fails. Default is true<br>
-    Since ant 1.6.1</td>
+    <td>Throw an exception if the command fails. Default is true.<br>
+    <em>Since Ant 1.6.1</em></td>
     <td>No</td>
   </tr>
 </table>
@@ -485,14 +474,12 @@
 <p>Does a ClearCase <i>mklabel</i> on the file <i>c:/views/viewdir/afile</i> under
 the main branch for version 2 (<i>\main\2</i>). Text <i>Some comment text</i> is added
 as a comment. It will <i>recurse</i> all subdirectories.
-
-
-<hr>
-<h2><a name="ccrmtype">CCRmtype</a></h2>
+<hr/>
+<h2 id="ccrmtype">CCRmtype</h2>
 <h3>Description</h3>
 Task to perform a "rmtype" command to ClearCase.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -501,64 +488,74 @@
   <tr>
     <td>typekind</td>
     <td>The kind of type to create. Valid types are:
-      <table border="0" width="40%">
+      <table>
         <tr>
-          <td width="15%"> </td>
-          <td><b>attype</b><br>
-              <b>brtype</b><br>
-              <b>eltype</b><br>
-              <b>hltype</b><br>
-              <b>lbtype</b><br>
-              <b>trtype</b>
-          </td>
-          <td>- <br>
-              - <br>
-              - <br>
-              - <br>
-              - <br>
-              -
-          </td>
-          <td>attribute type<br>
-              branch type<br>
-              element type<br>
-              hyperlink type<br>
-              label type<br>
-              trigger type
-          </td>
+          <td>Kind</td>
+          <td>&nbsp;</td>
+          <td>Description</td>
+        </tr>
+        <tr>
+          <td><b>attype</b></td>
+          <td>-</td>
+          <td>attribute type</td>
+        </tr>
+        <tr>
+          <td><b>brtype</b></td>
+          <td>-</td>
+          <td>branch type</td>
+        </tr>
+        <tr>
+          <td><b>eltype</b></td>
+          <td>-</td>
+          <td>element type</td>
+        </tr>
+        <tr>
+          <td><b>hltype</b></td>
+          <td>-</td>
+          <td>hyperlink type</td>
+        </tr>
+        <tr>
+          <td><b>lbtype</b></td>
+          <td>-</td>
+          <td>label type</td>
+        </tr>
+        <tr>
+          <td><b>trtype</b></td>
+          <td>-</td>
+          <td>trigger type</td>
         </tr>
       </table>
     </td>
     <td>Yes</td>
-  <tr>
+  </tr>
   <tr>
     <td>typename</td>
     <td>The name of the type to remove</td>
     <td>Yes</td>
-  <tr>
+  </tr>
   <tr>
     <td>ignore</td>
     <td>Used with trigger types only. Forces removal of trigger type even if a pre-operation trigger would prevent its removal</td>
     <td>No</td>
-  <tr>
+  </tr>
   <tr>
     <td>rmall</td>
     <td>Removes all instances of a type and the type object itself</td>
     <td>No</td>
-  <tr>
+  </tr>
   <tr>
     <td>comment</td>
-    <td>Specify a comment. Only one of comment or cfile may be used.</td>
-    <td>No</td>
-  <tr>
+    <td>Specify a comment</td>
+    <td rowspan="2">No; only one of the two may be used</td>
+  </tr>
   <tr>
     <td>commentfile</td>
-    <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
-    <td>No</td>
-  <tr></tr>
+    <td>Specify a file containing a comment</td>
+  </tr>
   <tr>
     <td>failonerr</td>
-    <td>Throw an exception if the command fails. Default is true
-    Since ant 1.6.1</td>
+    <td>Throw an exception if the command fails. Default is true.
+    <em>Since Ant 1.6.1</em></td>
     <td>No</td>
   </tr>
 </table>
@@ -575,13 +572,12 @@
 <p>Does a ClearCase <i>rmtype</i> to remove a label type (<i>lbtype</i>) named <i>VERSION_1</i>.
 Comment text from the file <i>acomment.txt</i> is added as a comment. All instances of the type
 are removed, including the type object itself.</p>
-<hr>
-
-<h2><a name="cclock">CCLock</a></h2>
+<hr/>
+<h2 id="cclock">CCLock</h2>
 <h3>Description</h3>
 Task to perform a "cleartool lock" command to ClearCase.
 <h3>Parameters</h3>
- <table border="1" cellpadding="2" cellspacing="0">
+ <table>
    <tr>
      <th>Attribute</th>
      <th>Values</th>
@@ -591,61 +587,59 @@
       <td>replace</td>
       <td>Specifies replacing an existing lock</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>nusers</td>
       <td>Specifies user(s) who can still modify the object</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>obsolete</td>
       <td>Specifies that the object should be marked obsolete</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>comment</td>
       <td>Specifies how to populate comments fields</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>pname</td>
       <td>Specifies the object pathname to be locked.</td>
       <td>No</td>
+   </tr>
    <tr>
       <td>objselect</td>
-      <td>This variable is obsolete. Should use <i>objsel</i> instead.</td>
+      <td><em>Obsolete</em>. Use <i>objsel</i> instead.</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>objsel</td>
       <td>Specifies the object(s) to be locked.<br>
-      Since ant 1.6.1</td>
+       <em>Since Ant 1.6.1</em></td>
       <td>No</td>
+   </tr>
    <tr>
-  <tr>
-    <td>failonerr</td>
-    <td>Throw an exception if the command fails. Default is true.<br>
-    Since ant 1.6.1</td>
-    <td>No</td>
-  </tr>
-
+     <td>failonerr</td>
+     <td>Throw an exception if the command fails. Default is true.<br>
+       <em>Since Ant 1.6.1</em></td>
+     <td>No</td>
+   </tr>
  </table>
 <h3>Examples</h3>
 <blockquote>
 <pre>
 &lt;cclock
-    objsel="stream:Application_Integration@\MyProject_PVOB"
-    /&gt;
+    objsel="stream:Application_Integration@\MyProject_PVOB"/&gt;
 </pre>
 </blockquote>
 <p>Does a ClearCase <i>lock</i> on the object <i>stream:Application_Integration@\MyProject_PVOB</i>.</p>
 <hr>
-
-<h2><a name="ccunlock">CCUnlock</a></h2>
+<h2 id="ccunlock">CCUnlock</h2>
 <h3>Description</h3>
 Task to perform a "cleartool unlock" command to ClearCase.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+ <table>
    <tr>
      <th>Attribute</th>
      <th>Values</th>
@@ -655,46 +649,44 @@
       <td>comment</td>
       <td>Specifies how to populate comments fields</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>pname</td>
       <td>Specifies the object pathname to be unlocked.</td>
       <td>No</td>
+   </tr>
    <tr>
       <td>objselect</td>
-      <td>This variable is obsolete. Should use <i>objsel</i> instead.</td>
+      <td><em>Obsolete</em>. Use <i>objsel</i> instead.</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>objsel</td>
       <td>Specifies the object(s) to be unlocked.<br>
-      Since ant 1.6.1</td>
+       <em>Since Ant 1.6.1</em></td>
       <td>No</td>
+   </tr>
    <tr>
-  <tr>
-    <td>failonerr</td>
-    <td>Throw an exception if the command fails. Default is true.<br>
-    Since ant 1.6.1</td>
-    <td>No</td>
-  </tr>
-
+     <td>failonerr</td>
+     <td>Throw an exception if the command fails. Default is true.<br>
+       <em>Since Ant 1.6.1</em></td>
+     <td>No</td>
+   </tr>
  </table>
- <h3>Examples</h3>
+<h3>Examples</h3>
 <blockquote>
 <pre>
 &lt;ccunlock
-    objsel="stream:Application_Integration@\MyProject_PVOB"
-    /&gt;
+    objsel="stream:Application_Integration@\MyProject_PVOB"/&gt;
 </pre>
 </blockquote>
 <p>Does a ClearCase <i>unlock</i> on the object <i>stream:Application_Integration@\MyProject_PVOB</i>.</p>
 <hr>
-
-<h2><a name="ccmkbl">CCMkbl</a></h2>
+<h2 id="ccmkbl">CCMkbl</h2>
 <h3>Description</h3>
 Task to perform a "cleartool mkbl" command to ClearCase.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
    <tr>
      <th>Attribute</th>
      <th>Values</th>
@@ -702,14 +694,12 @@
    </tr>
    <tr>
       <td>comment</td>
-      <td>Specify a comment. Only one of comment or cfile may be
-used.</td>
-      <td>No</td>
+      <td>Specify a comment</td>
+      <td rowspan="2">No; only one of the two may be used</td>
    </tr>
    <tr>
       <td>commentfile</td>
-      <td>Specify a file containing a comment. Only one of comment or
-cfile may be used.</td>
+      <td>Specify a file containing a comment</td>
       <td>No</td>
    </tr>
    <tr>
@@ -721,11 +711,11 @@
       <td>nowarn</td>
       <td>Suppress warning messages</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>identical</td>
       <td>Allows the baseline to be created even if it is identical to the
-previous baseline.</td>
+       previous baseline.</td>
       <td>No</td>
    </tr>
    <tr>
@@ -741,7 +731,7 @@
   <tr>
     <td>failonerr</td>
     <td>Throw an exception if the command fails. Default is true.<br>
-    Since ant 1.6.1</td>
+       <em>Since Ant 1.6.1</em></td>
     <td>No</td>
   </tr>
  </table>
@@ -752,21 +742,19 @@
     baselinerootname="Application_Baseline_AUTO"
     identical="yes"
     full="no"
-    viewpath="v:\ApplicationCC"
-    /&gt;
+    viewpath="v:\ApplicationCC"/&gt;
 </pre>
 </blockquote>
 <p>Does a ClearCase <i>mkbl</i> on the Integration view at <i>v:\ApplicationCC</i>
 even if it is <i>identical</i> to a previous baseline. The new baseline with be
 incremental and named "Application_Baseline_AUTO".</p>
 <hr>
-
-<h2><a name="ccmkattr">CCMkattr</a></h2>
+<h2 id="ccmkattr">CCMkattr</h2>
 <h3>Description</h3>
 Task to perform a &quot;cleartool mkattr&quot; command to ClearCase.<br>
-Since ant 1.6.1
+<em>Since Ant 1.6.1</em>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
    <tr>
      <th>Attribute</th>
      <th>Values</th>
@@ -804,12 +792,12 @@
    </tr>
    <tr>
       <td>comment</td>
-      <td>Specify a comment. Only one of comment or cfile may be used.</td>
-      <td>No</td>
+      <td>Specify a comment</td>
+      <td rowspan="2">No; only one of the two may be used</td>
    </tr>
    <tr>
       <td>commentfile</td>
-      <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+      <td>Specify a file containing a comment</td>
       <td>No</td>
    </tr>
    <tr>
@@ -823,20 +811,18 @@
 <pre>
 &lt;ccmkattr viewpath=&quot;c:/views/viewdir/afile&quot;
     typename=&quot;BugFix&quot;
-    typevalue=&quot;34445&quot;
-    /&gt;
+    typevalue=&quot;34445&quot;/&gt;
 </pre>
 </blockquote>
 <p>Does a ClearCase <i>mkattr</i> on the file <i>c:/views/viewdir/afile</i> and
 attaches the attribute <i>BugFix</i> with a value of <i>34445</i> to it.</p>
-<hr>
-
-<h2><a name="ccmkdir">CCMkdir</a></h2>
+<hr/>
+<h2 id="ccmkdir">CCMkdir</h2>
 <h3>Description</h3>
 Task to perform a &quot;cleartool mkdir&quot; command to ClearCase.<br>
-Since ant 1.6.1
+<em>Since Ant 1.6.1</em>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
    <tr>
      <th>Attribute</th>
      <th>Values</th>
@@ -849,13 +835,12 @@
    </tr>
    <tr>
       <td>comment</td>
-      <td>Specify a comment. Only one of comment or cfile may be used.</td>
-      <td>No</td>
+      <td>Specify a comment</td>
+      <td rowspan="2">No; only one of the two may be used</td>
    </tr>
    <tr>
       <td>commentfile</td>
-      <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
-      <td>No</td>
+      <td>Specify a file containing a comment</td>
    </tr>
    <tr>
       <td>nocheckout</td>
@@ -878,14 +863,13 @@
 </blockquote>
 <p>Does a ClearCase <i>mkdir</i> on the dir <i>c:/views/viewdir/adir</i> and
 does not automatically check it out.</p>
-<hr>
-
-<h2><a name="ccmkelem">CCMkelem</a></h2>
+<hr/>
+<h2 id="ccmkelem">CCMkelem</h2>
 <h3>Description</h3>
 Task to perform a &quot;cleartool mkelem&quot; command to ClearCase.<br>
-Since ant 1.6.1
+<em>Since Ant 1.6.1</em>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
    <tr>
      <th>Attribute</th>
      <th>Values</th>
@@ -895,52 +879,52 @@
       <td>viewpath</td>
       <td>Path to the ClearCase view file or directory that the command will operate on</td>
       <td>Yes</td>
-   <tr>
+   </tr>
    <tr>
       <td>comment</td>
-      <td>Specify a comment. Only one of comment or cfile may be used.</td>
-      <td>No</td>
-   <tr>
+      <td>Specify a comment</td>
+      <td rowspan="2">No; only one of the two may be used</td>
+   </tr>
    <tr>
       <td>commentfile</td>
-      <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+      <td>Specify a file containing a comment</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>nowarn</td>
       <td>Suppress warning messages</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>nocheckout</td>
       <td>Do not checkout after element creation</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>checkin</td>
       <td>Checkin element after creation</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>preservetime</td>
       <td>Preserve the modification time (for checkin)</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>master</td>
       <td>Assign mastership of the main branch to the current site</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>eltype</td>
       <td>Element type to use during element creation</td>
       <td>No</td>
-   <tr>
+   </tr>
    <tr>
       <td>failonerr</td>
       <td>Throw an exception if the command fails. Default is true</td>
       <td>No</td>
-   <tr>
+   </tr>
  </table>
 <h3>Examples</h3>
 <blockquote>
diff --git a/manual/Tasks/common.html b/manual/Tasks/common.html
index 6fa3418..d1c37ae 100644
--- a/manual/Tasks/common.html
+++ b/manual/Tasks/common.html
@@ -24,10 +24,10 @@
 
 <body>
 
-<h2><a name="javac">Common Attributes of all Tasks</a></h2>
+<h2 id="javac">Common Attributes of all Tasks</h2>
 <p>All tasks share the following attributes:</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -52,8 +52,5 @@
   </tr>
 </table>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/componentdef.html b/manual/Tasks/componentdef.html
index e28e681..7c2fe6d 100644
--- a/manual/Tasks/componentdef.html
+++ b/manual/Tasks/componentdef.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="componentdef">componentdef</a></h2>
+<h2 id="componentdef">componentdef</h2>
 <h3>Description</h3>
   <p>
     Adds a component definition to the current project.
@@ -54,9 +54,8 @@
     classname="com.apache.tools.ant.types.resources.selectors.Or"/&gt;</pre>
   <p>
     defines two components with the same name "or"; one is a condition
-    (see <a href="conditions.html">conditions</a>) and one is 
+    (see <a href="conditions.html">conditions</a>) and one is
     a selector (see <a href="../Types/selectors.html">selectors</a>).
   </p>
 </body>
 </html>
-
diff --git a/manual/Tasks/concat.html b/manual/Tasks/concat.html
index 11372d0..1bdbd5a 100644
--- a/manual/Tasks/concat.html
+++ b/manual/Tasks/concat.html
@@ -19,26 +19,26 @@
     <head>
       <meta http-equiv="Content-Language" content="en-us">
       <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
-<title>Concat</title>
+      <title>Concat</title>
     </head>
 
     <body>
 
-      <h2><a name="Concat">Concat</a></h2>
+      <h2 id="concat">Concat</h2>
 
       <h3>Description</h3>
 
       <p>
-        Concatenates one or more 
+        Concatenates one or more
         <a href="../Types/resources.html">resource</a>s
         to a single file or to the console. The destination
         file will be created if it does not exist unless the resource
         list is empty and ignoreempty is true.
       </p>
 
-      <p><strong>Since Apache Ant 1.7.1</strong>, this task can be used as a
+      <p><em>Since Apache Ant 1.7.1</em>, this task can be used as a
         <a href="../Types/resources.html#collection">Resource Collection</a>
-        that will return exactly one 
+        that will return exactly one
         <a href="../Types/resources.html">resource</a>.
       </p>
 
@@ -51,7 +51,7 @@
 
       <h3>Parameters</h3>
 
-      <table border="1" cellpadding="2" cellspacing="0">
+      <table>
 
         <tr>
           <td valign="top"><b>Attribute</b></td>
@@ -93,7 +93,7 @@
           <td valign="top">
             Specifies whether or not the file specified by 'destfile'
             should be written to even if it is newer than all source files.
-            <em>since Ant 1.8.2</em>.
+            <em>Since Ant 1.8.2</em>.
             Defaults to &quot;yes&quot;.
           </td>
           <td valign="top" align="center">No</td>
@@ -102,7 +102,7 @@
         <tr>
           <td valign="top">forceReadOnly</td>
           <td valign="top">Overwrite read-only destination
-            files.  <em>since Ant 1.8.2</em></td>
+            files.  <em>Since Ant 1.8.2</em></td>
           <td valign="top" align="center">No; defaults to false.</td>
         </tr>
 
@@ -120,8 +120,8 @@
         <tr>
           <td valign="top">outputencoding</td>
           <td valign="top">
-            The encoding to use when writing the output file
-            <em>since Ant 1.6</em>.
+            The encoding to use when writing the output file.
+            <em>Since Ant 1.6</em>.
             Defaults to the value of the encoding attribute
             if given or the default JVM encoding otherwise.
           </td>
@@ -135,7 +135,7 @@
             a new line. If this attribute is &quot;yes&quot;
             a new line will be appended to the stream if
             the file did not end in a new line.
-            <em>since Ant 1.6</em>.
+            <em>Since Ant 1.6</em>.
             Defaults to &quot;no&quot;.
             This attribute does not apply to embedded text.
           </td>
@@ -146,7 +146,7 @@
           <td valign="top">
             Specifies what the end of line character are
             for use by the fixlastline attribute.
-            <em>since Ant 1.6</em>
+            <em>Since Ant 1.6</em>
             Valid values for this property are:
             <ul>
               <li>cr: a single CR</li>
@@ -167,7 +167,7 @@
         <tr>
           <td valign="top">binary</td>
           <td valign="top">
-            <em>since Ant 1.6.2</em>
+            <em>Since Ant 1.6.2</em>
             If this attribute is set to true, the task concatenates the files
             in a byte by byte fashion. If this attribute is false, concat will
             not normally work for binary files due to character encoding
@@ -221,7 +221,7 @@
         <p><em>since Ant 1.6</em>.</p>
       <p>Used to prepend or postpend text into the concatenated stream.</p>
       <p>The text may be in-line or be in a file.</p>
-      <table border="1" cellpadding="2" cellspacing="0">
+      <table>
         <tr>
           <td valign="top"><b>Attribute</b></td>
           <td valign="top"><b>Description</b></td>
@@ -232,25 +232,25 @@
           <td valign="top">
             Whether to filter the text provided by this sub element,
             default is "yes".
-          <td valign="top" align = "center">No</td>
+          <td valign="top" align="center">No</td>
         </tr>
         <tr>
           <td valign="top">file</td>
           <td valign="top">A file to place at the head or tail of the
                            concatenated text.
-          <td valign="top" align = "center">No</td>
+          <td valign="top" align="center">No</td>
         </tr>
         <tr>
           <td valign="top">trim</td>
           <td valign="top">Whether to trim the value, default is "no"</td>
-          <td valign="top" align = "center">No</td>
+          <td valign="top" align="center">No</td>
         </tr>
         <tr>
           <td valign="top">trimleading</td>
           <td valign="top">
             Whether to trim leading white space on each line, default is "no"
           </td>
-          <td valign="top" align = "center">No</td>
+          <td valign="top" align="center">No</td>
         </tr>
       </table>
 
@@ -292,7 +292,7 @@
   &lt;/concat&gt;
       </pre>
 
-      <p><b>Concatenate a series of files, expanding ant properties</b></p>
+      <p><b>Concatenate a series of files, expanding Ant properties</b></p>
         <pre>
    &lt;concat destfile="${build.dir}/subs"&gt;
       &lt;path&gt;
@@ -330,8 +330,5 @@
    &lt;/concat&gt;
         </pre>
 
-      
-
     </body>
-
-  </html>
+</html>
diff --git a/manual/Tasks/condition.html b/manual/Tasks/condition.html
index 405f95e..8505b81 100644
--- a/manual/Tasks/condition.html
+++ b/manual/Tasks/condition.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="Condition">Condition</a></h2>
+<h2 id="condition">Condition</h2>
 <h3>Description</h3>
 <p>Sets a property if a certain condition holds true - this is a
 generalization of <a href="available.html">Available</a> and <a
@@ -36,7 +36,7 @@
 <p>Conditions are specified as <a href="#nested">nested elements</a>,
 you must specify exactly one condition.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -62,7 +62,7 @@
     <td valign="top" align="center">No</td>
   </tr>
 </table>
-<h3><a name="nested">Parameters specified as nested elements</a></h3>
+<h3 id="nested">Parameters specified as nested elements</h3>
 <p>All conditions to test are specified as nested elements, for a
 complete list see <a href="conditions.html">here</a>.</p>
 
@@ -83,10 +83,8 @@
   &lt;condition property=&quot;isMacOsButNotMacOsX&quot;&gt;
     &lt;and&gt;
       &lt;os family=&quot;mac&quot;/&gt;
-
       &lt;not&gt;
         &lt;os family=&quot;unix&quot;/&gt;
-
       &lt;/not&gt;
     &lt;/and&gt;
   &lt;/condition&gt;
@@ -98,13 +96,10 @@
 <pre>
   &lt;condition property=&quot;isSunOSonSparc&quot;&gt;
     &lt;os name=&quot;SunOS&quot; arch=&quot;sparc&quot;/&gt;
-
   &lt;/condition&gt;
 </pre>
 <p>sets the property <code>isSunOSonSparc</code> if the current
 operating system is SunOS and if it is running on a sparc architecture.</p>
 
-
-
 </body>
 </html>
diff --git a/manual/Tasks/conditions.html b/manual/Tasks/conditions.html
index 35216cd..312437e 100644
--- a/manual/Tasks/conditions.html
+++ b/manual/Tasks/conditions.html
@@ -24,8 +24,8 @@
 
 <body>
 
-<h2><a name="Conditions">Conditions</a></h2>
-  <p>Conditions are nested elements of the 
+<h2 id="conditions">Conditions</h2>
+  <p>Conditions are nested elements of the
 <a href="condition.html"><code>&lt;condition&gt;</code></a> and
 <a href="waitfor.html"><code>&lt;waitfor&gt;</code></a> tasks.
     There are core conditions and custom conditions. Custom
@@ -34,39 +34,40 @@
       Custom Conditions</a>.
     Core Conditions are described below.
   </p>
-  <h3><a name="coreconditions">Core Conditions</a></h3>
+<h3 id="coreconditions">Core Conditions</h3>
 
 <p>These are the nested elements that can be used as conditions in the
 <a href="condition.html"><code>&lt;condition&gt;</code></a> and
 <a href="waitfor.html"><code>&lt;waitfor&gt;</code></a> tasks.</p>
 
-<h4><a name="not">not</a></h4>
+<h4 id="not">not</h4>
 <p>The <code>&lt;not&gt;</code> element expects exactly one other
 condition to be nested into this element, negating the result of the
 condition.  It doesn't have any attributes and accepts all nested
 elements of the condition task as nested elements as well.</p>
 
-<h4><a name="and">and</a></h4> <p>
-The <code>&lt;and&gt;</code> element doesn't have any attributes and
+<h4 id="and">and</h4>
+<p>The <code>&lt;and&gt;</code> element doesn't have any attributes and
 accepts an arbitrary number of conditions as nested elements - all
 nested elements of the condition task are supported.  This condition
 is true if all of its contained conditions are, conditions will be
 evaluated in the order they have been specified in the build file.</p>
 <p>The <code>&lt;and&gt;</code> condition has the same shortcut
-semantics as the Java &amp;&amp; operator, as soon as one of the
+semantics as the Java <code>&amp;&amp;</code> operator, as soon as one of the
 nested conditions is false, no other condition will be evaluated.</p>
 
-<h4><a name="or">or</a></h4> <p>
-The <code>&lt;or&gt;</code> element doesn't have any attributes and
+<h4 id="or">or</h4>
+<p>The <code>&lt;or&gt;</code> element doesn't have any attributes and
 accepts an arbitrary number of conditions as nested elements - all
 nested elements of the condition task are supported.  This condition
 is true if at least one of its contained conditions is, conditions
 will be evaluated in the order they have been specified in the build
-file.</p> <p>The <code>&lt;or&gt;</code> condition has the same
-shortcut semantics as the Java || operator, as soon as one of the
+file.</p>
+<p>The <code>&lt;or&gt;</code> condition has the same
+shortcut semantics as the Java <code>||</code> operator, as soon as one of the
 nested conditions is true, no other condition will be evaluated.</p>
 
-<h4><a name="xor">xor</a></h4>
+<h4 id="xor">xor</h4>
 <p>The <code>&lt;xor&gt;</code> element performs an exclusive
 or on all nested elements, similar to the <code>^</code> operator
 in Java. It only evaluates to true if an odd number of nested conditions
@@ -75,24 +76,24 @@
 It doesn't have any attributes and accepts all nested
 elements of the condition task as nested elements as well.</p>
 
-<h4><a name="available">available</a></h4>
+<h4 id="available">available</h4>
 <p>This condition is identical to the <a
 href="available.html">Available</a> task, all attributes and nested
 elements of that task are supported, the property and value attributes
 are redundant and will be ignored.</p>
 
-<h4><a name="uptodate">uptodate</a></h4>
+<h4 id="uptodate">uptodate</h4>
 <p>This condition is identical to the <a
 href="uptodate.html">Uptodate</a> task, all attributes and nested
 elements of that task are supported, the property and value attributes
 are redundant and will be ignored.</p>
 
-<h4><a name="os">os</a></h4>
+<h4 id="os">os</h4>
 <p>Test whether the current operating system is of a given type.  Each
 defined attribute is tested and the result is true only if <i>all</i>
 the tests succeed.
 </p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -124,8 +125,9 @@
   <li>windows (for all versions of Microsoft Windows)</li>
   <li>dos (for all Microsoft DOS based operating systems including
     Microsoft Windows and OS/2)</li>
-  <li>mac (for all Apple Macintosh systems)</li>
-  <li>unix (for all Unix and Unix-like operating systems)</li>
+  <li>mac (for all Apple Macintosh systems prior to Mac OS X)</li>
+  <li>unix (for all Unix and Unix-like operating systems, including Linux and
+      Mac OS X/macOS)</li>
   <li>netware (for Novell NetWare)</li>
   <li>os/2 (for OS/2)</li>
   <li>tandem (for HP's NonStop Kernel - formerly Tandem)</li>
@@ -137,9 +139,9 @@
   <li>openvms for OpenVMS</li>
 </ul>
 
-<h4><a name="equals">equals</a></h4>
+<h4 id="equals">equals</h4>
 <p>Tests whether the two given values are equal.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -176,9 +178,9 @@
   </tr>
 </table>
 
-<h4><a name="isset">isset</a></h4>
+<h4 id="isset">isset</h4>
 <p>Test whether a given property has been set in this project.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -191,17 +193,17 @@
   </tr>
 </table>
 
-<h4><a name="checksum">checksum</a></h4>
+<h4 id="checksum">checksum</h4>
 <p>This condition is identical to the <a href="checksum.html">Checksum</a>
 task, all attributes and nested elements of that task are supported,
 the property and overwrite attributes are redundant and will be
 ignored.</p>
 
-<h4><a name="http">http</a></h4>
+<h4 id="http">http</h4>
 <p>The <code>http</code> condition checks for a valid response from a
 web server of the specified url. By default, HTTP responses errors
 of 400 or greater are viewed as invalid.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td width="12%" valign="top"><b>Attribute</b></td>
     <td width="78%" valign="top"><b>Description</b></td>
@@ -223,9 +225,8 @@
   <tr>
     <td valign="top">requestMethod</td>
     <td valign="top">The HTTP method to be used when issuing the request.
-    Any of GET, POST, HEAD, OPTIONS, PUT, DELETEm and TRACE
-    are valid, subject to protocol restrictions. The default if not
-    specified is &quot;GET&quot;.<br/>
+    Any of GET, POST, HEAD, OPTIONS, PUT, DELETE and TRACE
+    are valid, subject to protocol restrictions. The default is &quot;GET&quot;.<br/>
       <em>since Ant 1.8.0</em></td>
     <td align="center">No</td>
   </tr>
@@ -238,10 +239,10 @@
   </tr>
 </table>
 
-<h4><a name="socket">socket</a></h4>
+<h4 id="socket">socket</h4>
 <p>The <code>socket</code> condition checks for the existence of a
 TCP/IP listener at the specified host and port.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td width="12%" valign="top"><b>Attribute</b></td>
     <td width="78%" valign="top"><b>Description</b></td>
@@ -259,15 +260,15 @@
   </tr>
 </table>
 
-<h4><a name="filesmatch">filesmatch</a></h4>
+<h4 id="filesmatch">filesmatch</h4>
 <p>Test two files for matching. Nonexistence of one file results in "false",
 although if neither exists they are considered equal in terms of content.
 This test does a byte for byte comparison, so test time scales with
-byte size. NB: if the files are different sizes, one of them is missing
+byte size. <strong>Note</strong>: if the files are different sizes, one of them is missing
 or the filenames match the answer is so obvious the detailed test is omitted.
 
 </p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td width="12%" valign="top"><b>Attribute</b></td>
     <td width="78%" valign="top"><b>Description</b></td>
@@ -287,15 +288,15 @@
     <td valign="top">textfile</td>
     <td valign="top">Whether to ignore line endings when comparing
         files; defaults to <i>false</i> which triggers a binary
-        comparison. <b>Since Ant 1.7</b>
+        comparison. <em>Since Ant 1.7</em>
     </td>
     <td align="center">No</td>
   </tr>
 </table>
 
-<h4><a name="contains">contains</a></h4>
+<h4 id="contains">contains</h4>
 <p>Tests whether a string contains another one.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -319,10 +320,10 @@
   </tr>
 </table>
 
-<h4><a name="istrue">istrue</a></h4>
-<p>Tests whether a string equals any of the ant definitions of true,
+<h4 id="istrue">istrue</h4>
+<p>Tests whether a string equals any of the Ant definitions of true,
 that is "true","yes", or "on"</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -339,10 +340,10 @@
 &lt;istrue value=&quot;false&quot;/&gt;
 </pre></blockquote>
 
-<h4><a name="isfalse">isfalse</a></h4>
+<h4 id="isfalse">isfalse</h4>
 <p>Tests whether a string is not true, the negation of &lt;istrue&gt;
 </p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -359,14 +360,13 @@
 &lt;isfalse value=&quot;false&quot;/&gt;
 </pre></blockquote>
 
-<h4><a name="isreference">isreference</a></h4>
-
+<h4 id="isreference">isreference</h4>
 <p>Test whether a given reference has been defined in this project and
 - optionally - is of an expected type.</p>
 
-<p>This condition has been added in Apache Ant 1.6.</p>
+<p><em>Since Apache Ant 1.6</em>.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -385,7 +385,7 @@
   </tr>
 </table>
 
-<h4><a name="issigned">issigned</a></h4>
+<h4 id="issigned">issigned</h4>
   <p>
     Test whether a jarfile is signed.
     If the name of the
@@ -395,9 +395,9 @@
     signature validation; it only looks for the presence of a signature.
   </p>
   <p>
-    This condition was added in Apache Ant 1.7.
+    <em>Since Apache Ant 1.7</em>.
   </p>
-  <table border="1" cellpadding="2" cellspacing="0">
+  <table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -418,15 +418,15 @@
   </tr>
   </table>
 
-<h4><a name="isfileselected">isfileselected</a></h4>
+<h4 id="isfileselected">isfileselected</h4>
   <p>
     Test whether a file passes an embedded
     <a href="../Types/selectors.html">selector</a>.
   </p>
   <p>
-    This condition was added in Apache Ant 1.6.3.
+    <em>Since Apache Ant 1.6.3</em>.
   </p>
-  <table border="1" cellpadding="2" cellspacing="0">
+  <table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -455,15 +455,15 @@
 &lt;/isfileselected&gt;
 </pre></blockquote>
 
-<h4><a name="typefound">typefound</a></h4>
+<h4 id="typefound">typefound</h4>
 
 <p>Test whether a given type is defined, and that
 its implementation class can be loaded. Types include
 tasks, datatypes, scriptdefs, macrodefs and presetdefs.</p>
 
-<p>This condition was added in Apache Ant 1.7.</p>
+<p><em>Since Apache Ant 1.7</em>.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -471,7 +471,7 @@
   </tr>
   <tr>
     <td valign="top">name</td>
-    <td valign="top">name of the type</td>
+    <td valign="top">Name of the type</td>
     <td valign="top" align="center">Yes</td>
   </tr>
   <tr>
@@ -491,7 +491,7 @@
 &lt;typefound uri="antlib:org.apache.maven.artifact.ant" name="artifact"/&gt;
 </pre></blockquote>
 
-<h4><a name="scriptcondition">scriptcondition</a></h4>
+<h4 id="scriptcondition">scriptcondition</h4>
 
 <p>Evaluate a condition based on a script in any
 <a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a>
@@ -504,9 +504,9 @@
 an explanation of scripts and dependencies.
 </p>
 
-<p>This condition was added in Apache Ant 1.7.</p>
+<p><em>Since Apache Ant 1.7</em>.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -529,14 +529,19 @@
   <tr>
     <td valign="top">value</td>
     <td valign="top">default boolean value</td>
-    <td valign="top" align="center">No -default is "false"</td>
-  </tr>  
+    <td valign="top" align="center">No - default is "false"</td>
+  </tr>
   <tr>
     <td valign="top">src</td>
     <td valign="top">filename of script source</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
+    <td valign="top">encoding</td>
+    <td valign="top">The encoding of the script source. <em>Since Ant 1.10.2</em>.</td>
+    <td valign="top" align="center">No - defaults to default JVM encoding</td>
+  </tr>
+  <tr>
     <td valign="top">setbeans</td>
     <td valign="top">whether to have all properties, references and targets as
       global variables in the script.  <em>since Ant 1.8.0</em></td>
@@ -580,18 +585,18 @@
 &lt;/scriptcondition&gt;
 </pre></blockquote>
 
-Sets the default value of the condition to true, then in the script, 
+Sets the default value of the condition to true, then in the script,
 sets the value to false. This condition always evaluates to "false"
 
-<h4><a name="parsersupports">parsersupports</a></h4>
+<h4 id="parsersupports">parsersupports</h4>
 
 <p>Tests whether Ant's XML parser supports a given
 feature or property, as per the SAX/JAXP specifications, by
 attempting to set the appropriate property/feature/</p>
 
-<p>This condition was added in Apache Ant 1.7.</p>
+<p><em>Since Apache Ant 1.7</em>.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -600,12 +605,11 @@
   <tr>
     <td valign="top">property</td>
     <td valign="top">property to set</td>
-    <td valign="top" align="center">one of property or feature</td>
+    <td valign="top" align="center" rowspan="2">Exactly one of the two</td>
   </tr>
   <tr>
     <td valign="top">feature</td>
     <td valign="top">feature to set</td>
-    <td valign="top" align="center">one of property or feature</td>
   </tr>
   <tr>
     <td valign="top">value</td>
@@ -637,12 +641,12 @@
 
 Check for Xerces-specific definition of the location of the no namespace schema.
 
-<h4><a name="isreachable">isreachable</a></h4>
+<h4 id="isreachable">isreachable</h4>
 
-<p>Uses Java1.5+ networking APIs to probe for a (remote) system being
+<p>Uses Java 5+ networking APIs to probe for a (remote) system being
 reachable. Exactly what probe mechanisms are used is an implementation
 feature of the JVM. They may include ICMP "ping" packets, UDP or TCP connections
-to port 7 "echo service" or other means. On Java1.4 and earlier, being able
+to port 7 "echo service" or other means. On Java 1.4 and earlier, being able
 to resolve the hostname is considered success. This means that if DNS is not
 working or a URL/hostname is bad, the test will fail, but otherwise succeed
 even if the remote host is actually absent.
@@ -663,11 +667,9 @@
 on the floor. Similarly, a host may detected as reachable with ICMP, but
 not reachable on other ports (i.e. port 80), because of firewalls.
 </p>
-<p>
+<p><em>Since Apache Ant 1.7</em>.</p>
 
-This condition was added in Apache Ant 1.7.</p>
-
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -676,12 +678,11 @@
   <tr>
     <td valign="top">host</td>
     <td valign="top">host to check for</td>
-    <td valign="top" align="center">one of url or host</td>
+    <td valign="top" align="center" rowspan="2">Exactly one of the two</td>
   </tr>
   <tr>
     <td valign="top">url</td>
     <td valign="top">URL containing hostname</td>
-    <td valign="top" align="center">one of url or host</td>
   </tr>
   <tr>
     <td valign="top">timeout</td>
@@ -710,10 +711,10 @@
 Probe for the maven repository being reachable using the hostname, ten second timeout..
 </p>
 
-<h4><a name="length">length</a></h4>
+<h4 id="length">length</h4>
 <p>This condition is a facet of the <a href="length.html">Length</a> task.
   It is used to test the length of a string or one or more files.
-  <b>Since Ant 1.6.3</b>
+  <em>Since Ant 1.6.3</em>
 </p>
 
 <blockquote><pre>
@@ -726,12 +727,12 @@
 </pre></blockquote>
 <p>Verify that file <i>foo</i> is not empty.</p>
 
-<h4><a name="isfailure">isfailure</a></h4>
+<h4 id="isfailure">isfailure</h4>
 
 <p>Test the return code of an executable (see the
-<a href="exec.html">Exec</a> task) for failure. <b>Since Ant 1.7</b></p>
+<a href="exec.html">Exec</a> task) for failure. <em>Since Ant 1.7</em></p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -744,12 +745,12 @@
   </tr>
 </table>
 
-<h4><a name="resourcecount">resourcecount</a></h4>
+<h4 id="resourcecount">resourcecount</h4>
 <p>This condition is a facet of the
   <a href="resourcecount.html">ResourceCount</a> task.
-  It is used to test the size of a 
+  It is used to test the size of a
   <a href="../Types/resources.html#collection">resource collection</a>.
-  <b>Since Ant 1.7</b>
+  <em>Since Ant 1.7</em>
 </p>
 
 <blockquote><pre>
@@ -757,18 +758,18 @@
 </pre></blockquote>
 <p>Verify that a resource collection is not empty.</p>
 
-<h4><a name="resourcesmatch">resourcesmatch</a></h4>
+<h4 id="resourcesmatch">resourcesmatch</h4>
 <p>Test resources for matching. Nonexistence of one or more resources results in
 "false", although if none exists they are considered equal in terms of content.
 By default this test does a byte for byte comparison, so test time scales with
-byte size. NB: if the files are different sizes, one of them is missing
+byte size. <strong>Note</strong>: if the files are different sizes, one of them is missing
 or the filenames match the answer is so obvious the detailed test is omitted.
 The resources to check are specified as nested
 <a href="../Types/resources.html#collection">resource collections</a>,
 meaning that more than two resources can be checked; in this case all resources
-must match. <b>Since Ant 1.7</b>
+must match. <em>Since Ant 1.7</em>
 </p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td width="12%" valign="top"><b>Attribute</b></td>
     <td width="78%" valign="top"><b>Description</b></td>
@@ -784,12 +785,12 @@
   </tr>
 </table>
 
-<h4><a name="resourcecontains">resourcecontains</a></h4>
+<h4 id="resourcecontains">resourcecontains</h4>
 <p>Tests whether a resource contains a given (sub)string.</p>
 <p>The resources to check are specified via references or - in the
-  case of file resources via the resource attribute.  <b>Since Ant 1.7.1</b>
+  case of file resources via the resource attribute.  <em>Since Ant 1.7.1</em>
 </p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td width="12%" valign="top"><b>Attribute</b></td>
     <td width="78%" valign="top"><b>Description</b></td>
@@ -799,7 +800,7 @@
     <td valign="top">resource</td>
     <td valign="top">Name of a file that is the resource to test.
     </td>
-    <td align="center" rowspan="2">One of the two</td>
+    <td align="center" rowspan="2">Exactly one of the two</td>
   </tr>
   <tr>
     <td valign="top">refid</td>
@@ -818,15 +819,16 @@
   </tr>
 </table>
 
-<h4><a name="hasmethod">hasmethod</a></h4>
+<h4 id="hasmethod">hasmethod</h4>
 
-<p> Tests for a class having a method or field. If the class is not found 
-    or fails to load, the build fails. 
-    
-    <b>Since Ant 1.7</b>
+<p>
+    Tests for a class having a method or field. If the class is not found
+    or fails to load, the build fails.
+
+    <em>Since Ant 1.7</em>
 </p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
     <tr>
         <td width="12%" valign="top"><b>Attribute</b></td>
         <td width="78%" valign="top"><b>Description</b></td>
@@ -840,18 +842,17 @@
     <tr>
         <td valign="top">field</td>
         <td valign="top">name of a field to look for</td>
-        <td align="center">one of field or method</td>
+        <td align="center" rowspan="2">Exactly one of the two</td>
     </tr>
     <tr>
         <td valign="top">method</td>
         <td valign="top">name of a method to look for</td>
-        <td align="center">one of field or method</td>
     </tr>
-    
+
     <tr>
         <td valign="top">ignoreSystemClasses</td>
         <td valign="top">should system classes be ignored?</td>
-        <td align="center">No -default is false</td>
+        <td align="center">No - default is false</td>
     </tr>
     <tr>
         <td valign="top">classpath</td>
@@ -866,7 +867,7 @@
 </table>
 
 <p>
-    There is also a nested &lt;classpath&gt; element, which can be used to specify 
+    There is also a nested &lt;classpath&gt; element, which can be used to specify
     a classpath.
 </p>
 <blockquote><pre>
@@ -875,14 +876,14 @@
 
 <p>Looks for the method trimToSize in the ArrayList class.</p>
 
-<h4><a name="matches">matches</a></h4>
+<h4 id="matches">matches</h4>
 
 <p>
   Test if the specified string matches the specified regular
   expression pattern.
-  <b>Since Ant 1.7</b></p>
+  <em>Since Ant 1.7</em></p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -981,18 +982,18 @@
 &lt;/au:assertFalse&gt;
 </pre></blockquote>
 
-<h4><a name="antversion">antversion</a></h4>
+<h4 id="antversion">antversion</h4>
 <p>This condition is identical to the <a
 href="antversion.html">Antversion</a> task, all attributes are supported, the property attribute
 is redundant and will be ignored.</p>
 
 
-<h4><a name="hasfreespace">hasfreespace</a></h4>
+<h4 id="hasfreespace">hasfreespace</h4>
 
 <p>
   Tests a partition to see if there is enough space.
-  <b>Since Ant 1.7.0</b></p>
-  <p>Needed attribute can be specified using standard computing terms:<br/>
+  <em>Since Ant 1.7.0</em></p>
+  <p>Needed attribute can be specified using standard computing terms:</p>
     <ul>
       <li>K : Kilobytes (1024 bytes)</li>
       <li>M : Megabytes (1024 K)</li>
@@ -1000,9 +1001,8 @@
       <li>T : Terabytes (1024 G)</li>
       <li>P : Petabytes (1024 T)</li>
     </ul>
-  </p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -1026,12 +1026,12 @@
 &lt;hasfreespace partition="c:" needed="100M"/&gt;
 </pre></blockquote>
 
-<h4><a name="islastmodified">islastmodified</a></h4>
+<h4 id="islastmodified">islastmodified</h4>
 
 <p>Tests the last modified date of a resource.  <em>Since Ant
 1.8.0</em></p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td width="12%" valign="top"><b>Attribute</b></td>
     <td width="78%" valign="top"><b>Description</b></td>
@@ -1042,7 +1042,7 @@
     <td valign="top">Specifies the expected modification time of the resource
       in milliseconds since midnight Jan 1 1970.</td>
     <td valign="center" align="center" rowspan="2">Exactly one of the
-      two.</td>
+      two</td>
   </tr>
   <tr>
     <td valign="top">datetime</td>
@@ -1076,7 +1076,7 @@
 &lt;/islastmodified&gt;
 </pre></blockquote>
 
-<h4><a name="resourceexists">resourceexists</a></h4>
+<h4 id="resourceexists">resourceexists</h4>
 
 <p>Tests a resource for existence.  <em>since Ant 1.8.0</em></p>
 
@@ -1091,12 +1091,12 @@
 &lt;/resourceexists&gt;
 </pre></blockquote>
 
-<h4><a name="javaversion">javaversion</a></h4>
+<h4 id="javaversion">javaversion</h4>
 
 <p>Tests the version of the JVM executing Ant.  <em>Since Ant
-1.9.10</em></p>
+1.10.2</em></p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td width="12%" valign="top"><b>Attribute</b></td>
     <td width="78%" valign="top"><b>Description</b></td>
@@ -1105,15 +1105,14 @@
   <tr>
     <td valign="top">atleast</td>
     <td valign="top">The version that this JVM is at least.
-      The format is major.minor.point. Starting with Java9 really
+      The format is major.minor.point. Starting with Java 9 really
       only the major number is determined.</td>
-    <td valign="top" align="center">No</td>
-    <td valign="top" rowspan="2" align="center">One of these.</td>
+    <td valign="top" rowspan="2" align="center">Exactly one of the two</td>
   </tr>
   <tr>
     <td valign="top">exactly</td>
     <td valign="top">The version that this JVM is exactly.
-      The format is <tt>major.minor.point</tt>. Starting with Java9 really
+      The format is <tt>major.minor.point</tt>. Starting with Java 9 really
       only the major number is determined.</td>
     <td valign="top" align="center">No</td>
   </tr>
@@ -1127,7 +1126,7 @@
 &lt;javaversion atleast=&quot;9&quot;/&gt;
 </pre></blockquote>
 
-<p>will evaluate to true if the current JVM is Java9 or above.</p>
+<p>will evaluate to true if the current JVM is Java 9 or above.</p>
 
 </body>
 </html>
diff --git a/manual/Tasks/copy.html b/manual/Tasks/copy.html
index d1b8ff2..06a88a3 100644
--- a/manual/Tasks/copy.html
+++ b/manual/Tasks/copy.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="copy">Copy</a></h2>
+<h2 id="copy">Copy</h2>
 <h3>Description</h3>
 <p>Copies a file or resource collection to a new file or directory.  By default, files are
 only copied if the source file is newer than the destination file,
@@ -41,7 +41,7 @@
 expect.</p>
 
 <p>
-<strong>Note: </strong>If you employ filters in your copy operation,
+<strong>Note</strong>: If you employ filters in your copy operation,
 you should limit the copy to text files. Binary files will be corrupted
 by the copy operation.
 This applies whether the filters are implicitly defined by the
@@ -50,7 +50,7 @@
   <em>See <a href="#encoding">encoding note</a></em>.
 </p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -80,8 +80,8 @@
       specified in the <code>&lt;fileset&gt;</code>, or if the
       <code>file</code> attribute is also specified, then only
       <code>todir</code> is allowed.<br/>
-      <em>Prior to Apache Ant 1.8.2</em> the <code>tofile</code> attribute
-      only supported filesystem resources top copy from.</td>
+      Prior to Apache Ant 1.8.2, the <code>tofile</code> attribute
+      only supported <a href="../Types/resources.html#file">file resources</a> to copy from.</td>
   </tr>
   <tr>
     <td valign="top">todir</td>
@@ -103,7 +103,7 @@
     <td valign="top">filtering</td>
     <td valign="top">Indicates whether token filtering using the <a href="../using.html#filters">global
         build-file filters</a> should take place during the copy.
-      <em>Note</em>: Nested <code>&lt;filterset&gt;</code> elements will
+      <strong>Note</strong>: Nested <code>&lt;filterset&gt;</code> elements will
       always be used, even if this attribute is not specified, or its value is
       <code>false</code> (<code>no</code>, or <code>off</code>).</td>
     <td valign="top" align="center">No; defaults to false.</td>
@@ -186,7 +186,7 @@
 <p><a href="../Types/resources.html#collection">Resource
 Collection</a>s are used to select groups of files to copy.  To use a
 resource collection, the <code>todir</code> attribute must be set.</p>
-<p>Prior to Ant 1.7 only <code>&lt;fileset&gt;</code> has been
+<p>Prior to Ant 1.7, only <code>&lt;fileset&gt;</code> has been
 supported as a nested element.</p>
 
 <h4>mapper</h4>
@@ -317,7 +317,7 @@
 <p>The paragraph following the previous example applies to this
   example as well.</p>
 
-<p><strong>Unix Note:</strong> File permissions are not retained when files
+<p><strong>Unix Note</strong>: File permissions are not retained when files
 are copied; they end up with the default <code>UMASK</code> permissions
 instead. This
 is caused by the lack of any means to query or set file permissions in the
@@ -325,14 +325,14 @@
 use <code>&lt;exec executable="cp" ... &gt;</code> instead.
 </p>
 
-<p><strong>Windows Note:</strong> If you copy a file to a directory
+<p><strong>Windows Note</strong>: If you copy a file to a directory
 where that file already exists, but with different casing,
 the copied file takes on the case of the original. The workaround is to
 <a href="delete.html">delete</a>
 the file in the destination directory before you copy it.
 </p>
-  <p>
-    <strong><a name="encoding">Important Encoding Note:</a></strong>
+  <p id="encoding">
+    <strong>Important Encoding Note</strong>:
     The reason that binary files when filtered get corrupted is that
     filtering involves reading in the file using a Reader class. This
     has an encoding specifying how files are encoded. There are a number
@@ -360,7 +360,7 @@
     There is not much that Ant can do. It cannot figure out which
     files are binary - a UTF-8 version of Korean will have lots of
     bytes with the top bit set. It is not informed about illegal
-    character sequences by current Sun Java implementions.
+    character sequences by current Sun Java implementations.
   </p>
   <p>
     One trick for filtering containing only US-ASCII is to
@@ -369,8 +369,6 @@
     Another trick is to change the LANG environment variable from
     something like "us.utf8" to "us".
   </p>
-    
 
-
-
-</body></html>
+</body>
+</html>
diff --git a/manual/Tasks/copydir.html b/manual/Tasks/copydir.html
index 9e9e60e..564d647 100644
--- a/manual/Tasks/copydir.html
+++ b/manual/Tasks/copydir.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="copydir">Copydir</a></h2>
+<h2 id="copydir">Copydir</h2>
 <h3><i>Deprecated</i></h3>
 <p><i>This task has been deprecated.  Use the Copy task instead.</i></p>
 <h3>Description</h3>
@@ -44,7 +44,7 @@
 <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
 <code>&lt;patternset&gt;</code> elements.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -112,14 +112,12 @@
 </table>
 <h3>Examples</h3>
 <pre>  &lt;copydir src=&quot;${src}/resources&quot;
-           dest=&quot;${dist}&quot;
-  /&gt;</pre>
+           dest=&quot;${dist}&quot;/&gt;</pre>
 <p>copies the directory <code>${src}/resources</code> to <code>${dist}</code>.</p>
 <pre>  &lt;copydir src=&quot;${src}/resources&quot;
            dest=&quot;${dist}&quot;
            includes=&quot;**/*.java&quot;
-           excludes=&quot;**/Test.java&quot;
-  /&gt;</pre>
+           excludes=&quot;**/Test.java&quot;/&gt;</pre>
 <p>copies the directory <code>${src}/resources</code> to <code>${dist}</code>
 recursively. All java files are copied, except for files with the name <code>Test.java</code>.</p>
 <pre>  &lt;copydir src=&quot;${src}/resources&quot;
@@ -130,7 +128,5 @@
 recursively. All java files are copied, except for the files under the <code>mypackage/test</code>
 directory.</p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/copyfile.html b/manual/Tasks/copyfile.html
index e204a7e..80306ae 100644
--- a/manual/Tasks/copyfile.html
+++ b/manual/Tasks/copyfile.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="copyfile">Copyfile</a></h2>
+<h2 id="copyfile">Copyfile</h2>
 <h3><i>Deprecated</i></h3>
 <p><i>This task has been deprecated.  Use the Copy task instead.</i></p>
 <h3>Description</h3>
@@ -32,7 +32,7 @@
 the source file is newer than the destination file, or when the destination file
 does not exist.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -67,7 +67,5 @@
   <p><code>&lt;copyfile src=&quot;${src}/index.html&quot; dest=&quot;${dist}/help/index.html&quot;/&gt;</code></p>
 </blockquote>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/cvs.html b/manual/Tasks/cvs.html
index e941ed6..6c2b375 100644
--- a/manual/Tasks/cvs.html
+++ b/manual/Tasks/cvs.html
@@ -24,20 +24,20 @@
 
 <body>
 
-<h2><a name="cvs">Cvs</a></h2>
+<h2 id="cvs">Cvs</h2>
 <h3>Description</h3>
 <p>Handles packages/modules retrieved from a
 <a href="http://www.nongnu.org/cvs/" target="_top">CVS</a> repository.</p>
 <p><b>Important:</b> This task needs &quot;<code>cvs</code>&quot; on the path. If it isn't, you will get
-an error (such as error <code>2</code> on windows). If <code>&lt;cvs&gt;</code> doesn't work, try to execute <code>cvs.exe</code>
+an error (such as error <code>2</code> on Windows). If <code>&lt;cvs&gt;</code> doesn't work, try to execute <code>cvs.exe</code>
 from the command line in the target directory in which you are working.
 Also note that this task assumes that the cvs executable is compatible
-with the Unix version from cvshome.org, this is not completely true
-for certain other cvs clients - like CVSNT for example - and some
+with the Unix version, this is not completely true
+for certain other CVS clients - like CVSNT for example - and some
 operation may fail when using such an incompatible client.
 </p>
 
-<p><b>CVSNT Note</b>: CVSNT prefers users to store the passwords
+<p><strong>CVSNT Note</strong>: CVSNT prefers users to store the passwords
 inside the registry.  If the <a href="cvspass.html">cvspass task</a>
 and the passfile attribute don't seem to work for you, the most likely
 reason is that CVSNT ignores your .cvspass file completely.  See <a
@@ -45,7 +45,7 @@
 report 21657</a> for recommended workarounds.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -90,7 +90,7 @@
   </tr>
   <tr>
     <td valign="top">package</td>
-    <td valign="top">the package/module to check out.  <b>Note:</b>
+    <td valign="top">the package/module to check out.  <strong>Note</strong>:
       multiple attributes can be split using spaces.  Use a nested
       &lt;module&gt; element if you want to specify a module with
       spaces in its name.</td>
@@ -163,7 +163,7 @@
   modules specified using this attribute can contain spaces in their
   name.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -179,8 +179,7 @@
 <h3>Examples</h3>
 <pre>  &lt;cvs cvsRoot=&quot;:pserver:anoncvs@cvs.apache.org:/home/cvspublic&quot;
        package=&quot;ant&quot;
-       dest=&quot;${ws.dir}&quot;
-  /&gt;</pre>
+       dest=&quot;${ws.dir}&quot;/&gt;</pre>
 <p>checks out the package/module &quot;ant&quot; from the CVS
 repository pointed to by the <code>cvsRoot</code> attribute, and stores the files in &quot;<code>${ws.dir}</code>&quot;.</p>
 <pre>  &lt;cvs dest=&quot;${ws.dir}&quot; command=&quot;update&quot;/&gt;</pre>
@@ -211,7 +210,7 @@
 &lt;/cvs&gt;
 </pre>
 <p>
-You may include as many <code>&lt;commandline&gt;</code> elements as you like. 
+You may include as many <code>&lt;commandline&gt;</code> elements as you like.
 Each will inherit the <code>failonerror</code>, <code>compression</code>, and other &quot;global&quot; parameters
 from the <code>&lt;cvs&gt;</code> element.
 </p>
@@ -224,7 +223,5 @@
 above. See <a href="http://ximbiot.com/cvs/wiki/index.php?title=Category:User_Documentation" target="_top">the cvs manual</a> for details,
 specifically the <a href="http://ximbiot.com/cvs/wiki/index.php?title=CVS--Concurrent_Versions_System_v1.12.12.1:_Guide_to_CVS_commands#SEC116" target="_top">Guide to CVS commands</a></p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/cvspass.html b/manual/Tasks/cvspass.html
index 185dde7..7e0819e 100644
--- a/manual/Tasks/cvspass.html
+++ b/manual/Tasks/cvspass.html
@@ -24,11 +24,11 @@
 
 <body>
 
-<h2><a name="cvs">cvspass</a></h2>
+<h2 id="cvs">cvspass</h2>
 <h3>Description</h3>
 <p>Adds entries to a .cvspass file. Adding entries to this file has the same affect as a cvs login command.</p>
 
-<p><b>CVSNT Note</b>: CVSNT prefers users to store the passwords
+<p><strong>CVSNT Note</strong>: CVSNT prefers users to store the passwords
 inside the registry.  If the task doesn't seem to work for you, the
 most likely reason is that CVSNT ignores your .cvspass file
 completely.  See <a
@@ -36,7 +36,7 @@
 zilla report 21657</a> for recommended workarounds.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -60,11 +60,8 @@
 </table>
 <h3>Examples</h3>
 <pre>  &lt;cvspass cvsroot=&quot;:pserver:anoncvs@cvs.apache.org:/home/cvspublic&quot;
-       password=&quot;anoncvs&quot;
-  /&gt;</pre>
+       password=&quot;anoncvs&quot;/&gt;</pre>
 <p>Adds an entry into the ~/.cvspass password file.</p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/cvstagdiff.html b/manual/Tasks/cvstagdiff.html
index 5350d8e..eb70bd7 100644
--- a/manual/Tasks/cvstagdiff.html
+++ b/manual/Tasks/cvstagdiff.html
@@ -21,20 +21,20 @@
 <title>CvsTagDiff Task</title>
 </head>
 <body>
-<h2><a name="cvstagdiff">CvsTagDiff</a></h2>
+<h2 id="cvstagdiff">CvsTagDiff</h2>
 <h3>Description</h3>
 <p>Generates an XML-formatted report file of the changes between two tags or dates recorded in a
-<a href="http://www.nongnu.org/cvs/" target="_top">CVS</a> repository. </p>
+<a href="http://www.nongnu.org/cvs/" target="_top">CVS</a> repository.</p>
 <p><b>Important:</b> This task needs &quot;<code>cvs</code>&quot; on the path. If it isn't, you will get
-an error (such as error <code>2</code> on windows). If <code>&lt;cvs&gt;</code> doesn't work, try to execute <code>cvs.exe</code>
+an error (such as error <code>2</code> on Windows). If <code>&lt;cvs&gt;</code> doesn't work, try to execute <code>cvs.exe</code>
 from the command line in the target directory in which you are working.
 Also note that this task assumes that the cvs executable is compatible
-with the Unix version from cvshome.org, this is not completely true
-for certain other cvs clients - like CVSNT for example - and some
+with the Unix version, this is not completely true
+for certain other CVS clients - like CVSNT for example - and some
 operation may fail when using such an incompatible client.
 </p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -44,7 +44,7 @@
     <td valign="top">startTag</td>
     <td valign="top">The earliest tag from which diffs are to be
      included in the report.</td>
-    <td align="center" valign="top" rowspan="2">exactly one of the two.</td>
+    <td align="center" valign="top" rowspan="2">Exactly one of the two</td>
   </tr>
   <tr>
     <td valign="top">startDate</td>
@@ -56,7 +56,7 @@
     <td valign="top">endTag</td>
     <td valign="top">The latest tag from which diffs are to be
      included in the report.</td>
-    <td align="center" valign="top" rowspan="2">exactly one of the two.</td>
+    <td align="center" valign="top" rowspan="2">Exactly one of the two</td>
   </tr>
   <tr>
     <td valign="top">endDate</td>
@@ -77,7 +77,7 @@
 </table>
 
 <h3>Parameters inherited from the <code>cvs</code> task</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -101,15 +101,13 @@
   <tr>
     <td valign="top">package</td>
     <td valign="top">the package/module to analyze.<br>
-    Since Ant 1.6
+    <em>Since Ant 1.6</em>
     multiple packages separated by spaces are possible.
-    aliases corresponding to different modules are also possible
+    aliases corresponding to different modules are also possible.
     Use a nested &lt;module&gt; element if you want to specify a module with
     spaces in its name.</td>
     <td align="center" valign="top">No</td>
   </tr>
-    <td align="center" valign="top">Yes</td>
-  </tr>
   <tr>
     <td valign="top">quiet</td>
     <td valign="top">suppress informational messages.</td>
@@ -141,7 +139,7 @@
   modules specified using this attribute can contain spaces in their
   name.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -159,8 +157,7 @@
                 destfile=&quot;tagdiff.xml&quot;
                 package=&quot;ant&quot;
                 startTag=&quot;ANT_14&quot;
-                endTag=&quot;ANT_141&quot;
-  /&gt;</pre>
+                endTag=&quot;ANT_141&quot;/&gt;</pre>
 
 <p>Generates a tagdiff report for all the changes that have been made
 in the <code>ant</code> module between the tags <code>ANT_14</code> and <code>ANT_141</code>.
@@ -170,8 +167,7 @@
                 destfile=&quot;tagdiff.xml&quot;
                 package=&quot;ant&quot;
                 startDate=&quot;2002-01-01&quot;
-                endDate=&quot;2002-31-01&quot;
-  /&gt;</pre>
+                endDate=&quot;2002-31-01&quot;/&gt;</pre>
 
 <p>Generates a tagdiff report for all the changes that have been made
 in the <code>ant</code> module in january 2002. In this example <code>cvsRoot</code>
@@ -183,8 +179,7 @@
                 destfile=&quot;tagdiff.xml&quot;
                 package=&quot;ant jakarta-gump&quot;
                 startDate=&quot;2003-01-01&quot;
-                endDate=&quot;2003-31-01&quot;
-  /&gt;</pre>
+                endDate=&quot;2003-31-01&quot;/&gt;</pre>
 
 <p>Generates a tagdiff report for all the changes that have been made
 in the <code>ant</code> and <code>jakarta-gump</code> modules in january 2003.
@@ -194,13 +189,13 @@
 It writes these changes into the file <code>tagdiff.xml</code>.</p>
 
 <h4>Generate Report</h4>
-<p>Ant includes a basic XSLT stylesheet that you can use to generate 
+<p>Ant includes a basic XSLT stylesheet that you can use to generate
 a HTML report based on the xml output. The following example illustrates
 how to generate a HTML report from the XML report.</p>
 
 <pre>
-        &lt;style in="tagdiff.xml" 
-               out="tagdiff.html" 
+        &lt;style in="tagdiff.xml"
+               out="tagdiff.html"
                style="${ant.home}/etc/tagdiff.xsl"&gt;
           &lt;param name="title" expression="Ant Diff"/&gt;
           &lt;param name="module" expression="ant"/&gt;
@@ -210,19 +205,19 @@
 
 <h4>Output</h4>
 <p>
-The cvsroot and package attributes of the tagdiff element are new in ant 1.6.<br>
-Notes on entry attributes :
-<table border="1">
+The cvsroot and package attributes of the tagdiff element are new in Ant 1.6.<br>
+Notes on entry attributes:
+</p>
+<table>
 <tr><th>Attribute</th><th>Comment</th></tr>
 <tr><td>name</td><td>when reporting on one package, the package name is removed from the output</td></tr>
 <tr><td>revision</td><td>supplied for files which exist at the end of the reporting period</td></tr>
 <tr><td>prevrevision</td><td>supplied for files which exist at the beginning of the reporting period.<br>
 Old CVS servers do not supply it for deleted files. CVS 1.12.2 supplies it.</td></tr>
 </table>
-</p>
 <pre>
 &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
-&lt;tagdiff startTag=&quot;ANT_14&quot; endTag=&quot;ANT_141&quot; 
+&lt;tagdiff startTag=&quot;ANT_14&quot; endTag=&quot;ANT_141&quot;
 cvsroot=&quot;:pserver:anoncvs@cvs.apache.org:/home/cvspublic&quot; package=&quot;ant&quot;&gt;
   &lt;entry&gt;
     &lt;file&gt;
@@ -234,8 +229,5 @@
 &lt;/tagdiff&gt;
 </pre>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/cvsversion.html b/manual/Tasks/cvsversion.html
index 09e7cee..9081f3ed 100644
--- a/manual/Tasks/cvsversion.html
+++ b/manual/Tasks/cvsversion.html
@@ -24,14 +24,14 @@
 
 <body>
 
-<h2><a name="cvs">CvsVersion</a></h2>
+<h2 id="cvs">CvsVersion</h2>
 <h3>Description</h3>
 <p>
 This task allows to retrieve a CVS client and server version.
-  <i>Since Apache Ant 1.6.1.</i>
+  <em>Since Apache Ant 1.6.1</em>.
 </p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -96,13 +96,9 @@
 <pre>  &lt;cvsversion cvsRoot=&quot;:pserver:anoncvs@cvs.apache.org:/home/cvspublic&quot;
        passfile=&quot;/home/myself/.cvspass&quot;
        serverversionproperty=&quot;apachecvsversion&quot;
-       clientversionproperty=&quot;localcvsversion&quot;
-  /&gt;</pre>
+       clientversionproperty=&quot;localcvsversion&quot;/&gt;</pre>
 <p>finds out the cvs client and server versions and stores the versions in the
 properties called apachecvsversion and localcvsversion</p>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/defaultexcludes.html b/manual/Tasks/defaultexcludes.html
index 5511b90..42a6c45 100644
--- a/manual/Tasks/defaultexcludes.html
+++ b/manual/Tasks/defaultexcludes.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="echo">DefaultExcludes</a></h2>
+<h2 id="echo">DefaultExcludes</h2>
 
 <p><em>since Apache Ant 1.6</em></p>
 
@@ -33,7 +33,7 @@
 build, and prints out the current default excludes if desired.
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -86,10 +86,10 @@
 </pre>
 
 <h3>Notes</h3>
-By default the pattern <tt>**/.svn</tt> and <tt>**/.svn/**</tt> are set as default 
-excludes. With version 1.3 Subversion supports the 
+By default the pattern <tt>**/.svn</tt> and <tt>**/.svn/**</tt> are set as default
+excludes. With version 1.3 Subversion supports the
 <a target="_blank" href="http://subversion.apache.org/docs/release-notes/1.3.html#_svn-hack">&quot;_svn hack&quot;</a>.
-That means, that the svn-libraries evaluate environment variables and use <i>.svn</i> 
+That means, that the svn-libraries evaluate environment variables and use <i>.svn</i>
 or <i>_svn</i> directory regarding to that value. We had chosen not to evaluate environment variables to
 get a more reliable build. Instead you have to change the settings by yourself by changing
 the exclude patterns:
@@ -100,8 +100,5 @@
   &lt;defaultexcludes add=&quot;**/_svn/**&quot;/&gt;
 </pre>
 
-
-
-
 </body>
 </html>
diff --git a/manual/Tasks/delete.html b/manual/Tasks/delete.html
index 635b10f..3ddc82a 100644
--- a/manual/Tasks/delete.html
+++ b/manual/Tasks/delete.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="delete">Delete</a></h2>
+<h2 id="delete">Delete</h2>
 <h3>Description</h3>
 <p>Deletes a single file, a specified directory and all its files and
 subdirectories, or a set of files specified by one or more
@@ -53,7 +53,7 @@
   control, use a nested <code>&lt;fileset&gt;</code>.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -71,10 +71,10 @@
     <td valign="top">dir</td>
     <td valign="top">The directory to delete, including all its files and
      subdirectories.<br>
-     <b>Note:</b> <code>dir</code> is <em>not</em> used
+     <strong>Note</strong>: <code>dir</code> is <em>not</em> used
      to specify a directory name for <code>file</code>; <code>file</code>
      and <code>dir</code> are independent of each other.<br>
-     <b>WARNING:</b> Do <b>not</b> set <code>dir</code> to
+     <strong>Warning</strong>: Do <b>not</b> set <code>dir</code> to
      <code>&quot;.&quot;</code>, <code>&quot;${basedir}&quot;</code>,
      or the full-pathname equivalent unless you truly <em>intend</em> to
      recursively remove the entire contents of the current base directory
@@ -84,7 +84,7 @@
   <tr>
     <td valign="top">verbose</td>
     <td valign="top">Whether to show the name of each deleted file.</td>
-    <td align="center" valign="top">No, default &quot;false&quot;</i></td>
+    <td align="center" valign="top">No, default &quot;false&quot;</td>
   </tr>
   <tr>
     <td valign="top">quiet</td>
@@ -116,7 +116,7 @@
   </tr>
   <tr>
     <td valign="top">includes</td>
-    <td valign="top"><em>Deprecated.</em>  Use resource collections.
+    <td valign="top"><em>Deprecated</em>.  Use resource collections.
       Comma- or space-separated list of patterns of
       files that must be deleted. All files are relative to the directory
       specified in <code>dir</code>.</td>
@@ -124,14 +124,14 @@
   </tr>
   <tr>
     <td valign="top">includesfile</td>
-    <td valign="top"><em>Deprecated.</em>  Use resource collections.
+    <td valign="top"><em>Deprecated</em>.  Use resource collections.
       The name of a file. Each line of
       this file is taken to be an include pattern.</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
     <td valign="top">excludes</td>
-    <td valign="top"><em>Deprecated.</em>  Use resource collections.
+    <td valign="top"><em>Deprecated</em>.  Use resource collections.
       Comma- or space-separated list of patterns of
       files that must be excluded from the deletion list.
       All files are relative to the directory specified in <code>dir</code>.
@@ -140,14 +140,14 @@
   </tr>
   <tr>
     <td valign="top">excludesfile</td>
-    <td valign="top"><em>Deprecated.</em>  Use resource collections.
+    <td valign="top"><em>Deprecated</em>.  Use resource collections.
       The name of a file. Each line of
       this file is taken to be an exclude pattern</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
     <td valign="top">defaultexcludes</td>
-    <td valign="top"><em>Deprecated.</em>  Use resource collections.
+    <td valign="top"><em>Deprecated</em>.  Use resource collections.
       Whether to use <a href="../dirtasks.html#defaultexcludes">
       default excludes.</a></td>
     <td align="center" valign="top">No, default &quot;true&quot;</td>
@@ -219,10 +219,8 @@
   &lt;/delete&gt;
 </pre>
 <p>deletes the subversion metadata directories under <code>src</code>. Because <code>.svn</code>
-is on of the <a href="../dirtasks.html#defaultexcludes">default excludes</a> you have to use the 
+is on of the <a href="../dirtasks.html#defaultexcludes">default excludes</a> you have to use the
 <code>defaultexcludes</code> flag, otherwise Ant wont delete these directories and the files in it.</p>
 
-
-
 </body>
 </html>
diff --git a/manual/Tasks/deltree.html b/manual/Tasks/deltree.html
index 98adf4f..eeb976f 100644
--- a/manual/Tasks/deltree.html
+++ b/manual/Tasks/deltree.html
@@ -24,13 +24,13 @@
 
 <body>
 
-<h2><a name="deltree">Deltree</a></h2>
+<h2 id="deltree">Deltree</h2>
 <h3><i>Deprecated</i></h3>
 <p><i>This task has been deprecated.  Use the Delete task instead.</i></p>
 <h3>Description</h3>
 <p>Deletes a directory with all its files and subdirectories.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -50,7 +50,5 @@
 <p>deletes the directory <code>${dist}</code>, including its files and
 subdirectories.</p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/depend.html b/manual/Tasks/depend.html
index a094319..1272e1d 100644
--- a/manual/Tasks/depend.html
+++ b/manual/Tasks/depend.html
@@ -36,79 +36,90 @@
 classes which depend on the out-of-date classes.
 </p>
 
-<p> To determine the class dependencies, the depend task analyzes the class 
-files of all class files passed to it. Depend does not parse your source code in 
-any way but relies upon the class references encoded into the class files by the 
+<p>
+To determine the class dependencies, the depend task analyzes the class
+files of all class files passed to it. Depend does not parse your source code in
+any way but relies upon the class references encoded into the class files by the
 compiler. This is generally faster than parsing the Java source.</p>
 
 <p>
-To learn more about how this information is obtained from the class files, 
+To learn more about how this information is obtained from the class files,
 please refer to <a href="http://docs.oracle.com/javase/specs/">the Java
 Virtual Machine Specification</a>
 </p>
 
-<p> Since a class' dependencies only change when the class itself changes, the 
-depend task is able to cache dependency information. Only those class files 
-which have changed will have their dependency information re-analysed. Note that 
-if you change a class' dependencies by changing the source, it will be 
-recompiled anyway. You can examine the dependency files created to understand 
-the  dependencies of your classes. Please do not rely, however, on the format of 
-the information, as it may change in a later release. </p>
+<p>
+Since a class' dependencies only change when the class itself changes, the
+depend task is able to cache dependency information. Only those class files
+which have changed will have their dependency information re-analysed. Note that
+if you change a class' dependencies by changing the source, it will be
+recompiled anyway. You can examine the dependency files created to understand
+the  dependencies of your classes. Please do not rely, however, on the format of
+the information, as it may change in a later release.
+</p>
 
-<p> Once depend discovers all of the class dependencies, it &quot;inverts&quot; 
-this relation to determine, for each class, which other classes are dependent 
-upon it. This &quot;affects&quot; list is used to discover which classes are 
-invalidated by the out of date class. The class files of the invalidated 
-classes are removed, triggering the compilation of the affected classes. </p>
+<p>
+Once depend discovers all of the class dependencies, it &quot;inverts&quot;
+this relation to determine, for each class, which other classes are dependent
+upon it. This &quot;affects&quot; list is used to discover which classes are
+invalidated by the out of date class. The class files of the invalidated
+classes are removed, triggering the compilation of the affected classes.
+</p>
 
-<p> The depend task supports an attribute, &quot;closure&quot; which controls 
-whether depend will only consider direct class-class relationships or whether it 
-will also consider transitive, indirect relationships. For example, say there 
-are three classes, A, which depends on B, which in-turn depend on C. Now say 
-that class C is out of date. Without closure, only class B would be removed by 
-depend. With closure set, class A would also be removed. Normally direct 
-relationships are sufficient - it is unusual for a class to depend on another 
-without having a direct relationship. With closure set, you will notice that 
-depend typically removes far more class files. </p>
+<p>
+The depend task supports an attribute, &quot;closure&quot; which controls
+whether depend will only consider direct class-class relationships or whether it
+will also consider transitive, indirect relationships. For example, say there
+are three classes, A, which depends on B, which in-turn depend on C. Now say
+that class C is out of date. Without closure, only class B would be removed by
+depend. With closure set, class A would also be removed. Normally direct
+relationships are sufficient - it is unusual for a class to depend on another
+without having a direct relationship. With closure set, you will notice that
+depend typically removes far more class files.
+</p>
 
-<p>The classpath attribute for <code>&lt;depend&gt;</code> is optional. If it is present, 
+<p>The classpath attribute for <code>&lt;depend&gt;</code> is optional. If it is present,
 depend will check class dependencies against classes and jars on this classpath.
-Any classes which depend on an element from this classpath and which are older 
-than that element will be deleted. A typical example where you would use this 
-facility would be where you are building a utility jar and want to make sure 
+Any classes which depend on an element from this classpath and which are older
+than that element will be deleted. A typical example where you would use this
+facility would be where you are building a utility jar and want to make sure
 classes which are out of date with respect to this jar are rebuilt. You should
-<b>not</b> include jars in this classpath which you do not expect to change, 
-such as the JDK runtime jar or third party jars, since doing so will just slow 
-down the dependency check. This means that if you do use a classpath for the 
-depend task it may be different from the classpath necessary to actually 
+<b>not</b> include jars in this classpath which you do not expect to change,
+such as the JDK runtime jar or third party jars, since doing so will just slow
+down the dependency check. This means that if you do use a classpath for the
+depend task it may be different from the classpath necessary to actually
 compile your code.</p>
 
-<h3>Performance</h3> 
+<h3>Performance</h3>
 
-<p> The performance of the depend task is dependent on a 
-number of factors such as class relationship complexity and how many class files 
-are out of date. The decision about whether it is cheaper to just recompile all 
-classes or to use the depend task will depend on the size of your project and 
-how interrelated your classes are. </p>
+<p>
+The performance of the depend task is dependent on a
+number of factors such as class relationship complexity and how many class files
+are out of date. The decision about whether it is cheaper to just recompile all
+classes or to use the depend task will depend on the size of your project and
+how interrelated your classes are.
+</p>
 
 
 <h3>Limitations</h3>
 
-<p> There are some source dependencies which depend will not detect. </p>
+<p>
+There are some source dependencies which depend will not detect.
+</p>
 
 <ul>
-<li>If the Java compiler optimizes away a class relationship, 
-    there can be a source dependency without a class dependency. </li>
-    
+<li>If the Java compiler optimizes away a class relationship,
+    there can be a source dependency without a class dependency.</li>
+
 <li>Non public classes cause two problems. Firstly depend cannot relate
     the class file to a source file. In the future this may be addressed
-    using the source file attribute in the classfile. Secondly, neither 
+    using the source file attribute in the classfile. Secondly, neither
     depend nor the compiler tasks can detect when a non public class is
     missing. Inner classes are handled by the depend task.</li>
 </ul>
 
 The most obvious example of these limitations is that the task can't tell
-which classes to recompile when a constant primitive data type exported 
+which classes to recompile when a constant primitive data type exported
 by other classes is changed. For example, a change in the definition of
 something like
 <pre>
@@ -118,7 +129,7 @@
 </pre> will not be picked up by other classes.
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -141,7 +152,7 @@
     <td valign="top">cache</td>
     <td valign="top">This is a directory in which depend can store and
 retrieve dependency information. If this is not present, depend will not
-use a cache </td>
+use a cache</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -154,8 +165,7 @@
   </tr>
   <tr>
     <td valign="top">dump</td>
-    <td valign="top">If true the dependency information will be written to the debug level log
-                     </td>
+    <td valign="top">If true the dependency information will be written to the debug level log</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -167,13 +177,13 @@
   <tr>
     <td valign="top">warnOnRmiStubs</td>
     <td valign="top">Flag to disable warnings about files that look like rmic generated stub/skeleton
-    classes, and which have no .java source. Useful when doing rmi development. </td>
+        classes and have no .java source. Useful when doing RMI development.</td>
     <td valign="top" align="center">No, default=true</td>
   </tr>
 </table>
 
 <h3>Parameters specified as nested elements</h3>
-<p>The <code>depend</code> task's <code>classpath</code> attribute is a 
+<p>The <code>depend</code> task's <code>classpath</code> attribute is a
 <a href="../using.html#path">PATH-like structure</a> and can also be set
 via a nested <code>&lt;classpath&gt;</code> element.</p>
 
@@ -192,11 +202,12 @@
         closure=&quot;yes&quot;/&gt;</pre>
 
 <p>removes any classes in the <code>${build.classes}</code> directory
-that depend on out-of-date classes. Classes are considered out-of-date with 
+that depend on out-of-date classes. Classes are considered out-of-date with
 respect to the source in the <code>${java.dir}</code> directory, using the same
 mechanism as the <code>&lt;javac&gt;</code> task. In this example, the
-<code>&lt;depend&gt;</code> task caches its dependency 
-information in the <code>depcache</code> directory. </p>
+<code>&lt;depend&gt;</code> task caches its dependency
+information in the <code>depcache</code> directory.
+</p>
 
 <pre>
 &lt;depend srcdir=&quot;${java.dir}&quot; destdir=&quot;${build.classes}&quot;
@@ -209,8 +220,5 @@
 <code>.java</code> files, except those that match the list given
 in <code>${java.dir}/build_excludes</code>.</p>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/dependset.html b/manual/Tasks/dependset.html
index 34ec238..cb8a841 100644
--- a/manual/Tasks/dependset.html
+++ b/manual/Tasks/dependset.html
@@ -59,7 +59,7 @@
 
 <h3>Parameters</h3>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -69,7 +69,7 @@
     <td valign="top">verbose</td>
     <td valign="top">Makes the task list all deleted targets files
       and the reason why they get deleted.</td>
-    <td align="center" valign="top" rowspan="2">No</td>
+    <td align="center" valign="top">No</td>
   </tr>
 </table>
 
@@ -79,7 +79,7 @@
 
 <p>The <code>&lt;sources&gt;</code> element is a
 <a href="../Types/resources.html#union">Union</a> into which
-arbitrary resource collections can be nested. <b>Since Apache Ant 1.7</b>
+arbitrary resource collections can be nested. <em>Since Apache Ant 1.7</em>
 </p>
 
 <h4>srcfileset</h4>
@@ -97,7 +97,7 @@
 <p>
 The nested <code>&lt;srcfilelist&gt;</code> element specifies a <a
 href="../Types/filelist.html">FileList</a>. All files included in
-this filelist will be compared against all files included in all of the 
+this filelist will be compared against all files included in all of the
 <code>&lt;targetfileset&gt;</code> filesets and <code>&lt;targetfilelist&gt;</code>
 filelists.  Multiple <code>&lt;srcfilelist&gt;</code> filelists may be specified.
 </p>
@@ -106,7 +106,7 @@
 
 <p>The <code>&lt;targets&gt;</code> element is a
 <a href="../using.html#path">Path</a> and thus can
-include any filesystem-based resource. <b>Since Ant 1.7</b>
+include any filesystem-based resource. <em>Since Ant 1.7</em>
 </p>
 
 <h4>targetfileset</h4>
@@ -146,11 +146,11 @@
        &lt;targetfileset
            dir      = &quot;${output.dir}&quot;
            includes = &quot;**/*.html&quot;/&gt;
-    &lt;/dependset&gt;  </pre>
+    &lt;/dependset&gt;</pre>
 </blockquote>
 
-<p> 
-In this example derived HTML files in the ${output.dir} directory 
+<p>
+In this example derived HTML files in the ${output.dir} directory
 will be removed if any are out-of-date with respect to:</p>
 <ol>
 <li>the DTD of their source XML files</li>
@@ -165,7 +165,5 @@
 use filesets instead of filelists for the sources.
 </p>
 
-
-
 </body>
 </html>
diff --git a/manual/Tasks/diagnostics.html b/manual/Tasks/diagnostics.html
index cdb1693..57d08db 100644
--- a/manual/Tasks/diagnostics.html
+++ b/manual/Tasks/diagnostics.html
@@ -24,15 +24,14 @@
 
 <body>
 
-<h2><a name="diagnostics">Diagnostics</a></h2>
-<h3>Diagnostics</h3>
+<h2 id="diagnostics">Diagnostics</h2>
+<h3>Description</h3>
 <p>
-Runs Apache Ant's <code>-diagnostics</code> code inside Ant itself. This is good for 
-debugging Ant's configuration under an IDE. 
-<b>Since Ant 1.7.0</b>
+Runs Apache Ant's <code>-diagnostics</code> code inside Ant itself. This is good for
+debugging Ant's configuration under an IDE.
+<em>Since Ant 1.7.0</em>
 </p>
 
-
 <h3>Examples</h3>
 
 <pre>
@@ -44,6 +43,5 @@
     Prints out the current diagnostics dump.
 </p>
 
-
 </body>
 </html>
diff --git a/manual/Tasks/dirname.html b/manual/Tasks/dirname.html
index 03227b4..3a7b75a 100644
--- a/manual/Tasks/dirname.html
+++ b/manual/Tasks/dirname.html
@@ -24,12 +24,12 @@
 
 <body>
 
-<h2><a name="echo">Dirname</a></h2>
+<h2 id="echo">Dirname</h2>
 <h3>Description</h3>
 <p>
 Task to determine the directory path of a specified file.
 </p>
-<p> 
+<p>
 When this task executes, it will set the specified property to the
 value of the specified file (or directory) up to, but not including,
 the last path element. If the specified file is a path that ends in a
@@ -37,12 +37,12 @@
 a filename, the directory will be the current directory.
 </p>
   <p>
-    <em>Note:</em> This is not the same as the UNIX dirname command, which is
+    <strong>Note</strong>: This is not the same as the UNIX dirname command, which is
     defined as "strip non-directory suffix from filename". &lt;dirname&gt;
     determines the full directory path of the specified file.
   </p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -65,10 +65,7 @@
 will set <code>antfile.dir</code> to the directory path for
 <code>${ant.file}</code>.
 <pre>  &lt;dirname property=&quot;foo.dirname&quot; file=&quot;foo.txt&quot;/&gt;</pre>
-will set <code>foo.dirname</code> to the project's basedir.</p>
-
-
+will set <code>foo.dirname</code> to the project's basedir.
 
 </body>
 </html>
-
diff --git a/manual/Tasks/ear.html b/manual/Tasks/ear.html
index de4a962..a7b2462 100644
--- a/manual/Tasks/ear.html
+++ b/manual/Tasks/ear.html
@@ -24,11 +24,11 @@
 
 <body>
 
-<h2><a name="ear">Ear</a></h2>
+<h2 id="ear">Ear</h2>
 <h3>Description</h3>
 <p>An extension of the <a href="jar.html">Jar</a> task with special
 treatment for files that should end up in an Enterprise Application archive.</p>
-<p>(The Ear task is a shortcut for specifying the particular layout of a EAR file. 
+<p>(The Ear task is a shortcut for specifying the particular layout of a EAR file.
 The same thing can be accomplished by using the <i>prefix</i> and <i>fullpath</i>
 attributes of zipfilesets in a Zip or Jar task.)</p>
 <p>The extended zipfileset element from the zip task (with attributes <i>prefix</i>, <i>fullpath</i>, and <i>src</i>) is available in the Ear task.</p>
@@ -40,7 +40,7 @@
 to a value other than its default, <code>&quot;add&quot;</code>.</b></p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -74,7 +74,7 @@
     <td valign="top">For entries coming from existing archives (like
     nested <em>zipfileset</em>s or while updating the archive), keep
     the compression as it has been originally instead of using the
-    <em>compress</em> attribute.  Defaults false.  <em>Since Apache Ant
+    <em>compress</em> attribute.  Defaults to false.  <em>Since Apache Ant
     1.6</em></td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -146,9 +146,9 @@
   </tr>
   <tr>
     <td valign="top">index</td>
-    <td valign="top">whether to create an <A
-    HREF="http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#JAR_Index">index
-    list</A> to speed up classloading.  This is a JDK 1.3+ specific
+    <td valign="top">whether to create an <a
+    href="http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#JAR_Index">index
+    list</a> to speed up classloading.  This is a JDK 1.3+ specific
     feature.  Unless you specify additional jars with nested <a
     href="jar.html#indexjars"><code>indexjars</code></a> elements, only the
     contents of this jar will be included in the index.  Defaults to
@@ -165,8 +165,8 @@
       <a href="https://bugs.openjdk.java.net/browse/JDK-4408526">Java
       5</a>.  In order to avoid problems with Ant generated jars on
       Java 1.4 or earlier Ant will not include META-INF unless
-      explicitly asked to.<br/>
-      <em>Ant 1.8.0</em> - Defaults to false.</td>
+      explicitly asked to. Defaults to false<br/>
+      <em>Since Ant 1.8.0</em>.</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -209,7 +209,7 @@
     that the permissions haven't been stored at all rather than real
     permissions and will instead apply its own default values.<br/>
     Set this attribute to true if you really want to preserve the
-      original permission field.<em>since Ant 1.8.0</em>
+      original permission field. <em>Since Ant 1.8.0</em>
     </td>
     <td valign="top" align="center">No, default is false</td>
   </tr>
@@ -294,8 +294,5 @@
     &lt;/ear&gt;
 </pre>
 
-
 </body>
 </html>
-
-
diff --git a/manual/Tasks/echo.html b/manual/Tasks/echo.html
index bcf804e..49f5bc6 100644
--- a/manual/Tasks/echo.html
+++ b/manual/Tasks/echo.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="echo">Echo</a></h2>
+<h2 id="echo">Echo</h2>
 <h3>Description</h3>
 <p>Echoes a message to the current loggers and listeners which
 means <tt>System.out</tt> unless overridden. A <tt>level</tt>
@@ -35,7 +35,7 @@
 than overwrite the file is available, and the <tt>level</tt> option is
 ignored</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -45,19 +45,19 @@
     <td valign="top">message</td>
     <td valign="top">the message to echo.</td>
     <td valign="top" align="center">No.  Text may also be included in a
-      character section within this element.  If neither is included a 
+      character section within this element.  If neither is included a
       blank line will be emitted in the output.</td>
   </tr>
   <tr>
     <td valign="top">file</td>
     <td valign="top">the file to write the message to.</td>
-    <td valign="top" align="center" rowspan="2">Optionally one of these may be specified.</td>
+    <td valign="top" align="center" rowspan="2">No; only one of these may be used.</td>
   </tr>
   <tr>
     <td valign="top">output</td>
     <td valign="top">the <a href="../Types/resources.html">Resource</a>
       to write the message to (see <a href="../develop.html#set-magic">note</a>).
-      <b>Since Apache Ant 1.8</b></td>
+      <em>Since Apache Ant 1.8</em></td>
   </tr>
   <tr>
     <td valign="top">append</td>
@@ -136,7 +136,7 @@
 <tr>
   <th>Ant-Statement</th>
   <th>-quiet, -q</th>
-  <th><i>no statement</th>
+  <th><i>no statement</i></th>
   <th>-verbose, -v</th>
   <th>-debug, -d</th>
 </tr>
@@ -184,10 +184,5 @@
 </tr>
 </table>
 
-
-
-
-
-
 </body>
 </html>
diff --git a/manual/Tasks/echoproperties.html b/manual/Tasks/echoproperties.html
index ec1e4b4..96864c2 100644
--- a/manual/Tasks/echoproperties.html
+++ b/manual/Tasks/echoproperties.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="echoproperties">echoproperties</a></h2>
+<h2 id="echoproperties">echoproperties</h2>
 <h3>Description</h3>
 
 <p>Displays all the current properties (or a subset of them specified
@@ -35,7 +35,7 @@
 files.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -52,9 +52,8 @@
   <tr>
     <td valign="top">prefix</td>
     <td valign="top">
-        a prefix which is used to filter the properties
-        only those properties starting with this prefix will be echoed.
-        <P>
+        a prefix which is used to filter the properties:
+        only properties whose names start with this prefix will be echoed.
     </td>
     <td valign="top" align="center">No</td>
   </tr>
@@ -62,11 +61,11 @@
     <td valign="top">regex</td>
     <td valign="top">
         a regular expression which is used to filter the
-        properties
+        properties:
         only those properties whose names match it will be echoed.
     </td>
     <td valign="top" align="center">No</td>
-  </tr>   
+  </tr>
   <tr>
     <td valign="top">failonerror</td>
     <td valign="top">By default, the "failonerror" attribute is enabled.
@@ -139,8 +138,5 @@
   &lt;/echoproperties&gt;
 </pre></blockquote>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/echoxml.html b/manual/Tasks/echoxml.html
index 74cbf7f..c0dec59 100644
--- a/manual/Tasks/echoxml.html
+++ b/manual/Tasks/echoxml.html
@@ -26,9 +26,9 @@
 
 <h2>EchoXML</h2>
 <h3>Description</h3>
-<p>Echo nested XML to the console or a file. <b>Since Apache Ant 1.7</b></p>
+<p>Echo nested XML to the console or a file. <em>Since Apache Ant 1.7</em></p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -50,7 +50,7 @@
     <td valign="top">Sets the namespace policy as defined
       by <code>org.apache.tools.ant.util.DOMElementWriter.XmlNamespacePolicy</code>.
       Valid values are <code>ignore</code>, <code>elementsOnly</code>, or <code>all</code>.
-      <strong>Since Apache Ant 1.8</strong>
+      <em>Since Apache Ant 1.8</em>
     </td>
     <td valign="top" align="center">No, default <code>ignore</code></td>
   </tr>
@@ -71,4 +71,3 @@
 
 </body>
 </html>
-
diff --git a/manual/Tasks/ejb.html b/manual/Tasks/ejb.html
index 8c18f27..c08d940 100644
--- a/manual/Tasks/ejb.html
+++ b/manual/Tasks/ejb.html
@@ -39,36 +39,37 @@
   <li>Rob van Oostrum(<a href="mailto:rob@springwellfarms.ca">rob@springwellfarms.ca</a>)</li>
 </ul>
 
-<hr>
+<hr/>
 <h2>Table of Contents</h2>
 <ul>
   <li><a href="#introduction">Introduction</a></li>
   <li><a href="#ejbtasks">EJB Tasks</a></li>
 </ul>
 
-<hr>
-<h2><a name="introduction">Introduction</a></h2>
+<hr/>
+<h2 id="introduction">Introduction</h2>
 <p>Ant provides a number of optional tasks for developing 1.x and 2.x
 <a href="http://www.oracle.com/technetwork/java/index-jsp-140203.html" target="_top">Enterprise Java Beans (EJBs)</a>.
 In general these tasks are specific to the particular vendor's EJB Server.</p>
 
-<p> The tasks support:<br>
+<p>The tasks support:</p>
 
 <ul>
-  <li><a href="http://www.borland.com">Borland </a>
+  <li><a href="http://www.borland.com">Borland</a>
   Application Server 4.5</li>
-  <li><a href="http://www.iplanet.com">iPlanet </a>
+  <li><a href="http://www.iplanet.com">iPlanet</a>
   Application Server 6.0</li>
   <li><a href="http://www.jboss.org/" target="_top">
   JBoss 2.1</a> and above EJB servers</li>
   <li><a href="http://web.archive.org/web/20080516210506/http://www.ironflare.com/">
-  Orion Application Server</a> 2.0 <em>since 1.9.10</em></li>
+  Orion Application Server</a> 2.0 <em>since 1.10.2</em></li>
   <li><a href="http://www.bea.com" target="_top">Weblogic</a>
    4.5.1 through to 7.0 EJB servers</li>
   <li><a href="http://www.objectweb.org/jonas/" target="_top">JOnAS</a>
    2.4.x and 2.5 Open Source EJB server</li>
   <li><a href="http://www.ibm.com/websphere">IBM WebSphere</a> 4.0</li>
 </ul>
+<p>
     Vendors such as BEA and IBM now provide custom Ant tasks to work with their
     particular products. More importantly, EJB3.0 renders this whole process obsolete.
     Accordingly, development of these tasks is effectively frozen. Bug reports
@@ -77,9 +78,9 @@
     and definitely not new EJB2.x servers.
 </p>
 
-<hr>
-<h2><a name="ejbtasks">EJB Tasks</a></h2>
-<table border="1" cellpadding="5">
+<hr/>
+<h2 id="ejbtasks">EJB Tasks</h2>
+<table>
  <tr><td>Task</td><td colspan="2">Application Servers</td></tr>
  <tr><td><a href="BorlandGenerateClient.html">blgenclient</a></td><td colspan="2">Borland Application Server 4.5 and 5.x</td></tr>
  <tr><td><a href="#iplanet-ejbc">iplanet-ejbc</a></td><td colspan="2">iPlanet Application Server 6.0</td></tr>
@@ -94,8 +95,8 @@
 
 </table>
 
-<hr>
-<h2><a name="ddcreator">ddcreator</a></h2>
+<hr/>
+<h2 id="ddcreator">ddcreator</h2>
 <h3><b>Description:</b></h3>
 <p>ddcreator will compile a set of Weblogic text-based deployment descriptors into a serialized
 EJB deployment descriptor. The selection of which of the text-based descriptors are to be compiled
@@ -103,7 +104,7 @@
 </p>
 
 <h3>Parameters:</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -135,8 +136,8 @@
 &lt;/ddcreator&gt;
 </pre>
 
-<hr>
-<h2><a name="ejbc">ejbc</a></h2>
+<hr/>
+<h2 id="ejbc">ejbc</h2>
 <h3><b>Description:</b></h3>
 <p>The ejbc task will run Weblogic's ejbc tool. This tool will take a serialized deployment descriptor,
 examine the various EJB interfaces and bean classes and then generate the required support classes
@@ -144,9 +145,9 @@
 as well as the classes which implement the bean's home and remote interfaces.</p>
 <p>
 The ant task which runs this tool is able to compile several beans in a single operation. The beans to be
-compiled are selected by including their serialized deployment descriptors. The standard ant
+compiled are selected by including their serialized deployment descriptors. The standard Ant
 <code>include</code> and <code>exclude</code> constructs can be used to select the deployment descriptors
-to be included. </p>
+to be included.</p>
 <p>
 Each descriptor is examined to determine whether the generated classes are out of date and need to be
 regenerated. The deployment descriptor is de-serialized to discover the home, remote and
@@ -155,7 +156,7 @@
 compared with the modification time of the generated classes. If the generated classes are not present
 or are out of date, the ejbc tool is run to generate new versions.</p>
 <h3>Parameters:</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -208,9 +209,8 @@
 &lt;/ejbc&gt;
 </pre>
 
-<hr>
-<h2>
-<a NAME="iplanet-ejbc"></a>iplanet-ejbc</h2>
+<hr/>
+<h2 id="iplanet-ejbc">iplanet-ejbc</h2>
 
 <h3>
 <b>Description:</b></h3>
@@ -231,7 +231,7 @@
 <h3>
 Parameters:</h3>
 
-<table border="1" cellspacing="0" cellpadding="2">
+<table>
 <tr>
 <td valign="top"><b>Attribute</b></td>
 
@@ -281,7 +281,7 @@
 
 <td valign="top">Indicates whether or not the Java source files which are
 generated by ejbc will be saved or automatically deleted. If "yes", the
-source files will be retained. If omitted, it defaults to "no". </td>
+source files will be retained. If omitted, it defaults to "no".</td>
 
 <td align="center" valign="top">No</td>
 </tr>
@@ -291,7 +291,7 @@
 
 <td>Indicates whether or not the ejbc utility should log additional debugging
 statements to the standard output. If "yes", the additional debugging statements
-will be generated.  If omitted, it defaults to "no". </td>
+will be generated.  If omitted, it defaults to "no".</td>
 
 <td align="center" valign="top">
 <center>No</center>
@@ -304,7 +304,7 @@
 <td>May be used to specify the "home" directory for this iAS installation.
 This is used to find the ejbc utility if it isn't included in the user's
 system path. If specified, it should refer to the "[install-location]/iplanet/ias6/ias"
-directory. If omitted, the ejbc utility must be on the user's system path. </td>
+directory. If omitted, the ejbc utility must be on the user's system path.</td>
 
 <td align="center" valign="top">No</td>
 </tr>
@@ -331,21 +331,19 @@
                   &lt;pathelement path="${build.classpath}"/&gt;
               &lt;/classpath&gt;
 &lt;/iplanet-ejbc&gt;
-
-
 </pre>
 
-<hr>
-<h2><a name="wlrun">wlrun</a></h2>
+<hr/>
+<h2 id="wlrun">wlrun</h2>
 <h3><b>Description:</b></h3>
 
 <p>The <code>wlrun</code> task is used to start a weblogic server. The task runs
 a weblogic instance in a separate Java Virtual Machine. A number of parameters
 are used to control the operation of the weblogic instance. Note that the task,
-and hence ant, will not complete until the weblogic instance is stopped.</p>
+and hence Ant, will not complete until the weblogic instance is stopped.</p>
 
 <h3>Parameters:</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -476,21 +474,21 @@
            beahome=&quot;${bea.home}&quot;/&gt;
 </pre>
 
-<hr>
-<h2><a name="wlstop">wlstop</a></h2>
+<hr/>
+<h2 id="wlstop">wlstop</h2>
 <h3><b>Description:</b></h3>
 
 <p>The <code>wlstop</code> task is used to stop a weblogic instance which is
 currently running. To shut down an instance you must supply both a username and
 a password. These will be stored in the clear in the build script used to stop
 the instance. For security reasons, this task is therefore only appropriate in a
-development environment. </p>
+development environment.</p>
 
 <p>This task works for most version of Weblogic, including 6.0. You need to
 specify the BEA Home to have this task work correctly under 6.0</p>
 
 <h3>Parameters:</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -547,16 +545,15 @@
             beahome=&quot;${bea.home}&quot;/&gt;
 </pre>
 
-<hr>
-
-<h2><a name="ejbjar">ejbjar</a></h2>
+<hr/>
+<h2 id="ejbjar">ejbjar</h2>
 <h3><b>Description:</b></h3>
 
 <p>This task is designed to support building of EJB jar files (EJB 1.1 &amp; 2.0).
 Support is currently provided for 'vanilla' EJB jar files - i.e. those containing only
 the user generated class files and the standard deployment descriptor. Nested
 elements provide support for vendor specific deployment tools. These currently
-include: </p>
+include:</p>
 <ul>
   <li>Borland Application Server 4.5</li>
   <li>iPlanet Application Server 6.0</li>
@@ -584,7 +581,7 @@
 simply generate a generic EJB jar. Such jars are typically used as the input to
 vendor-specific deployment tools. For each nested deployment element, a vendor
 specific deployment tool is run to generate a jar file ready for deployment in
-that vendor's EJB container. </p>
+that vendor's EJB container.</p>
 
 <p>The jar files are only built if they are out of date.  Each deployment tool
 element will examine its target jar file and determine if it is out of date with
@@ -606,10 +603,10 @@
 conventions to determine the name of the generated EJB jars. The naming convention
 that is used is controlled by the &quot;naming&quot; attribute. It supports the
 following values
-<ul>
+<dl>
 
-<li>descriptor</li>
-<p>This is the default naming scheme. The name of the generated bean is derived from the
+<dt>descriptor</dt>
+<dd><p>This is the default naming scheme. The name of the generated bean is derived from the
 name of the deployment descriptor.  For an Account bean, for example, the deployment
 descriptor would be named <code>Account-ejb-jar.xml</code>. Vendor specific descriptors are
 located using the same naming convention. The weblogic bean, for example, would be named
@@ -619,29 +616,29 @@
 </p>
 
 <p>This scheme is useful when you are using one bean per EJB jar and where you may be
-deploying the same bean classes in different beans, with different deployment characteristics.
+    deploying the same bean classes in different beans, with different deployment characteristics.</p></dd>
 
-<li>ejb-name</li>
-<p> This naming scheme uses the <code>&lt;ejb-name&gt;</code> element from the deployment descriptor to
+<dt>ejb-name</dt>
+<dd><p>This naming scheme uses the <code>&lt;ejb-name&gt;</code> element from the deployment descriptor to
 determine the bean name. In this situation, the descriptors normally use the generic
 descriptor names, such as <code>ejb-jar.xml</code> along with any associated vendor specific descriptor
 names. For example, If the value of the <code>&lt;ejb-name&gt;</code> were to be given in the deployment descriptor
-as follows:
-<pre>
-&lt;ejb-jar&gt;
+as follows:</p>
+<pre>&lt;ejb-jar&gt;
     &lt;enterprise-beans&gt;
         &lt;entity&gt;
             &lt;ejb-name&gt;Sample&lt;/ejb-name&gt;
             &lt;home&gt;org.apache.ant.ejbsample.SampleHome&lt;/home&gt;
 </pre>
-
+<p>
 then the name of the generated bean would be <code>Sample.jar</code>
 </p>
-<p> This scheme is useful where you want to use the standard deployment descriptor names, which may be more
-compatible with other EJB tools. This scheme must have one bean per jar.
-</p>
-<li>directory</li>
 <p>
+This scheme is useful where you want to use the standard deployment descriptor names, which may be more
+compatible with other EJB tools. This scheme must have one bean per jar.
+</p></dd>
+<dt>directory</dt>
+<dd><p>
 In this mode, the name of the generated bean jar is derived from the directory
 containing the deployment descriptors. Again the deployment descriptors typically use
 the standard filenames. For example, if the path to the deployment descriptor is
@@ -652,10 +649,10 @@
 This scheme is also useful when you want to use standard style descriptor names. It is often
 most useful when the  descriptors are located in the same directory as the bean source code,
 although that is not mandatory. This scheme can handle multiple beans per jar.
-</p>
+</p></dd>
 
-<li>basejarname</li>
-<p>
+<dt>basejarname</dt>
+<dd><p>
 The final scheme supported by the <code>&lt;ejbjar&gt;</code> task is used when you want to specify the generated
 bean jar name directly. In this case the name of the generated jar is specified by the
 &quot;basejarname&quot; attribute. Since all generated beans will have the same name, this task should
@@ -666,11 +663,11 @@
 This scheme is most appropriate when you are using multiple beans per jar and only process a single
 deployment descriptor. You typically want to specify the name of the jar and not derive it from the
 beans in the jar.
-</p>
+</p></dd>
 
-</ul>
+</dl>
 
-<a name="ejbjar_deps"><h3>Dependencies</h3></a>
+<h3 id="ejbjar_deps">Dependencies</h3>
 <p>In addition to the bean classes, ejbjar is able to ad additional classes to the generated
 ejbjar. These classes are typically the support classes which are used by the bean's classes or as
 parameters to the bean's methods.</p>
@@ -681,7 +678,7 @@
 </p>
 
 <p>The ejbjar task in Ant releases 1.5 and later uses the
-<a href="http://commons.apache.org/bcel/"> BCEL </a> library
+<a href="http://commons.apache.org/bcel/">BCEL</a> library
 to analyze the bean's class
 files directly, rather than loading them into the JVM. This also allows ejbjar to add all
 of the required support classes for a bean and not just super classes.
@@ -699,12 +696,12 @@
 are added to the jar</li>
 </ul>
 <p>The <code>super</code> and <code>full</code> values require the
-<a href="http://commons.apache.org/bcel/"> BCEL </a> library
+<a href="http://commons.apache.org/bcel/">BCEL</a> library
 to be available. If it is not, ejbjar will drop back to the behaviour corresponding to
 the value <code>none</code>.</p>
 
 <h3>Parameters:</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -819,7 +816,7 @@
 <h3>Nested Elements</h3>
 
 <p>In addition to the vendor specific nested elements, the ejbjar task provides
-three nested elements. </p>
+three nested elements.</p>
 
 <h4>Classpath</h4>
 
@@ -827,7 +824,7 @@
 to be set. It is useful when setting the classpath from a reference path. In all
 other respects the behaviour is the same as the classpath attribute.</p>
 
-<a name="ejbjar-dtd"><h4>dtd</h4></a>
+<h4 id="ejbjar-dtd">dtd</h4>
 
 <p>The <code>&lt;dtd&gt;</code> element is used to specify the local location of DTDs to be
 used when parsing the EJB deployment descriptor. Using a local DTD is much
@@ -840,7 +837,7 @@
 requiring the vendor classes in the classpath, you would need to use a
 <code>&lt;dtd&gt;</code> element.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -877,24 +874,23 @@
 deployment element are detailed here.
 
 
-<h3><a name="ejbjar_jboss">Jboss element</a></h3>
+<h3 id="ejbjar_jboss">Jboss element</h3>
 
 <p>The jboss element searches for the JBoss specific deployment descriptors and adds them
-to the final ejb jar file. JBoss has two deployment descriptors:
+to the final ejb jar file. JBoss has two deployment descriptors:</p>
 <ul><li>jboss.xml</li>
 <li>for container manager persistence:<br>
-<table border="1">
+<table>
 <tr><td><b>CMP version</b></td><td><b>File name</b></td></tr>
 <tr><td>CMP 1.0</td><td>jaws.xml</td></tr>
 <tr><td>CMP 2.0</td><td>jbosscmp-jdbc.xml</td></tr>
 </table>
 </li>
 </ul>
-<br>
-. The JBoss server uses hot deployment and does
+<p>The JBoss server uses hot deployment and does
 not require compilation of additional stubs and skeletons.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -905,7 +901,7 @@
     <td valign="top">The base directory into which the generated weblogic ready
                      jar files are deposited. Jar files are deposited in
                      directories corresponding to their location within the
-                     descriptordir namespace. </td>
+                     descriptordir namespace.</td>
     <td valign="top" align="center">Yes</td>
   </tr>
   <tr>
@@ -934,7 +930,7 @@
 </table>
 
 
-<h3><a name="ejbjar_weblogic">Weblogic element</a></h3>
+<h3 id="ejbjar_weblogic">Weblogic element</h3>
 
 <p>The weblogic element is used to control the weblogic.ejbc compiler for
 generating weblogic EJB jars. Prior to Ant 1.3, the method of locating CMP
@@ -957,7 +953,7 @@
 descriptor's <code>&lt;type-storage&gt;</code> element. In the above example, you would
 define this as META-INF/Customer-weblogic-cmp-rdbms-jar.xml.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -968,7 +964,7 @@
     <td valign="top">The base directory into which the generated weblogic ready
                      jar files are deposited. Jar files are deposited in
                      directories corresponding to their location within the
-                     descriptordir namespace. </td>
+                     descriptordir namespace.</td>
     <td valign="top" align="center">Yes</td>
   </tr>
   <tr>
@@ -1153,7 +1149,7 @@
 is derived from the standard weblogic element so it supports the same set of attributes plus these
 additional attributes</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -1279,11 +1275,11 @@
 </pre>
 
 
-<h3><a name="ejbjar_websphere">WebSphere element</a></h3>
+<h3 id="ejbjar_websphere">WebSphere element</h3>
 
 <p>The websphere element searches for the websphere specific deployment descriptors and
 adds them to the final ejb jar file. Websphere has two specific descriptors for session
-beans:
+beans:</p>
 <ul>
    <li>ibm-ejb-jar-bnd.xmi</li>
    <li>ibm-ejb-jar-ext.xmi</li>
@@ -1293,11 +1289,12 @@
    <li>Map.mapxmi</li>
    <li>Schema.dbxmi</li>
 </ul>
+<p>
 In terms of WebSphere, the generation of container code and stubs is called <code>deployment</code>.
 This step can be performed by the websphere element as part of the jar generation process. If the
 switch <code>ejbdeploy</code> is on, the ejbdeploy tool from the websphere toolset is called for
 every ejb-jar. Unfortunately, this step only works, if you use the ibm jdk. Otherwise, the rmic
-(called by ejbdeploy) throws a ClassFormatError. Be sure to switch ejbdeploy off, if run ant with
+(called by ejbdeploy) throws a ClassFormatError. Be sure to switch ejbdeploy off, if Ant runs with
 Oracle JDK or OpenJDK.
 </p>
 
@@ -1307,7 +1304,7 @@
 the classpath of the ejbdeploy tool and set the <i>websphere.home</i> property (look at the examples below).
 </p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -1318,13 +1315,13 @@
     <td valign="top">The base directory into which the generated weblogic ready
                      jar files are deposited. Jar files are deposited in
                      directories corresponding to their location within the
-                     descriptordir namespace. </td>
+                     descriptordir namespace.</td>
     <td valign="top" align="center">Yes</td>
   </tr>
   <tr>
     <td valign="top">ejbdeploy</td>
     <td valign="top">Decides whether ejbdeploy is called. When you set this to true,
-                     be sure, to run ant with the ibm jdk.</td>
+                     be sure, to run Ant with the IBM JDK.</td>
     <td valign="top" align="center">No, defaults to true</td>
   </tr>
   <tr>
@@ -1358,7 +1355,7 @@
   </tr>
   <tr>
     <td valign="top">dbVendor</td>
-    <td valign="top">This option is passed to ejbdeploy. 
+    <td valign="top">This option is passed to ejbdeploy.
                    <p>
                    Valid options can be obtained by running the following command:
                    <code>
@@ -1415,7 +1412,7 @@
     &lt;/ejbjar&gt;
 </pre>
 
-<h3><a name="ejbjar_iplanet">iPlanet Application Server (iAS) element</a></h3>
+<h3 id="ejbjar_iplanet">iPlanet Application Server (iAS) element</h3>
 
 The &lt;iplanet&lt; nested element is used to build iAS-specific stubs and
 
@@ -1436,10 +1433,9 @@
 in the ejbjar task (for example, basejarname, basenameterminator, and flatdestdir)
 as well as the iplanet element (for example, suffix).  Refer to the
 appropriate documentation for more details.</p>
-<h3>
-Parameters:</h3>
+<h3>Parameters:</h3>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
 <td valign="top"><b>Attribute</b></td>
 
@@ -1475,7 +1471,7 @@
 
 <td valign="top">Indicates whether or not the Java source files which are
 generated by ejbc will be saved or automatically deleted. If "yes", the
-source files will be retained.  If omitted, it defaults to "no". </td>
+source files will be retained.  If omitted, it defaults to "no".</td>
 
 <td align="center" valign="top">No</td>
 </tr>
@@ -1485,7 +1481,7 @@
 
 <td>Indicates whether or not the ejbc utility should log additional debugging
 statements to the standard output. If "yes", the additional debugging statements
-will be generated.  If omitted, it defaults to "no". </td>
+will be generated.  If omitted, it defaults to "no".</td>
 
 <td align="center" valign="top">No</td>
 </tr>
@@ -1497,7 +1493,7 @@
 This is used to find the ejbc utility if it isn't included in the user's
 system path.  If specified, it should refer to the [install-location]/iplanet/ias6/ias
 directory.  If omitted, the ejbc utility must be on the user's system
-path. </td>
+path.</td>
 
 <td align="center" valign="top">No</td>
 </tr>
@@ -1506,7 +1502,7 @@
 <td valign="top">suffix</td>
 
 <td>String value appended to the JAR filename when creating each JAR.
-If omitted, it defaults to ".jar". </td>
+If omitted, it defaults to ".jar".</td>
 
 <td align="center" valign="top">No</td>
 </tr>
@@ -1582,7 +1578,7 @@
                  location="${ias.home}/APPS/IASEjb_jar_1_0.dtd"/&gt;
     &lt;/ejbjar&gt;</pre>
 
-<h3><a name="ejbjar_jonas">JOnAS (Java Open Application Server) element</a></h3>
+<h3 id="ejbjar_jonas">JOnAS (Java Open Application Server) element</h3>
 
 <p>The <code>&lt;jonas&gt;</code> nested element is used to build JOnAS-specific stubs and
 skeletons thanks to the <code>GenIC</code> specific tool, and construct a JAR
@@ -1615,70 +1611,70 @@
 
 <h3> Parameters:</h3>
 
-<table border="1" cellspacing="0" cellpadding="2">
+<table>
   <tbody>
     <tr>
-      <td valign="Top"><b>Attribute</b></td>
-      <td valign="Top"><b>Description</b></td>
-      <td align="Center" valign="Top"><b>Required</b></td>
+      <td valign="top"><b>Attribute</b></td>
+      <td valign="top"><b>Description</b></td>
+      <td align="center" valign="top"><b>Required</b></td>
     </tr>
     <tr>
-      <td valign="Top">destdir</td>
-      <td valign="Top">The base directory into which the generated JAR files
+      <td valign="top">destdir</td>
+      <td valign="top">The base directory into which the generated JAR files
       will be written. Each JAR file is written in directories which correspond
       to their location within the "<code>descriptordir</code>" namespace.</td>
-      <td align="Center" valign="Top">Yes</td>
+      <td align="center" valign="top">Yes</td>
     </tr>
     <tr>
-      <td valign="Top">jonasroot</td>
-      <td valign="Top">The root directory for JOnAS.</td>
-      <td valign="Top" align="Center">Yes</td>
+      <td valign="top">jonasroot</td>
+      <td valign="top">The root directory for JOnAS.</td>
+      <td valign="top" align="center">Yes</td>
     </tr>
     <tr>
-      <td valign="Top">classpath</td>
-      <td valign="Top">The classpath used when generating EJB stubs and
+      <td valign="top">classpath</td>
+      <td valign="top">The classpath used when generating EJB stubs and
       skeletons. If omitted, the classpath specified in the "ejbjar" parent
       task will be used. If specified, the classpath elements will be prepended
       to the classpath specified in the parent "ejbjar" task (see also the ORB
       attribute documentation below). Note that nested "classpath" elements may
       also be used.</td>
-      <td valign="Top" align="Center">No</td>
+      <td valign="top" align="center">No</td>
     </tr>
     <tr>
-      <td valign="Top">keepgenerated</td>
-      <td valign="Top"><code>true</code> if the intermediate Java
+      <td valign="top">keepgenerated</td>
+      <td valign="top"><code>true</code> if the intermediate Java
       source files generated by GenIC must be deleted or not. If
       omitted, it defaults to <code>false</code>.</td>
-      <td align="Center" valign="Top">No</td>
+      <td align="center" valign="top">No</td>
     </tr>
     <tr>
-      <td valign="Top">nocompil</td>
-      <td valign="Top"><code>true</code> if the generated source files
+      <td valign="top">nocompil</td>
+      <td valign="top"><code>true</code> if the generated source files
       must not be compiled via the java and rmi compilers. If omitted,
       it defaults to <code>false</code>.</td>
-      <td align="Center" valign="Top">No</td>
+      <td align="center" valign="top">No</td>
     </tr>
     <tr>
-      <td valign="Top">novalidation</td>
-      <td valign="Top"><code>true</code> if the XML deployment descriptors must
+      <td valign="top">novalidation</td>
+      <td valign="top"><code>true</code> if the XML deployment descriptors must
       be parsed without validation. If omitted, it defaults to <code>false</code>.</td>
-      <td align="Center" valign="Top">No</td>
+      <td align="center" valign="top">No</td>
     </tr>
     <tr>
-      <td valign="Top">javac</td>
-      <td valign="Top">Java compiler to use. If omitted, it defaults
+      <td valign="top">javac</td>
+      <td valign="top">Java compiler to use. If omitted, it defaults
       to the value of <code>build.compiler</code> property.</td>
-      <td align="Center" valign="Top">No</td>
+      <td align="center" valign="top">No</td>
     </tr>
     <tr>
-      <td valign="Top">javacopts</td>
-      <td valign="Top">Options to pass to the java compiler.</td>
-      <td align="Center" valign="Top">No</td>
+      <td valign="top">javacopts</td>
+      <td valign="top">Options to pass to the java compiler.</td>
+      <td align="center" valign="top">No</td>
     </tr>
     <tr>
-      <td valign="Top">rmicopts</td>
-      <td valign="Top">Options to pass to the rmi compiler.</td>
-      <td align="Center" valign="Top">No</td>
+      <td valign="top">rmicopts</td>
+      <td valign="top">Options to pass to the rmi compiler.</td>
+      <td align="center" valign="top">No</td>
     </tr>
     <tr>
       <td valign="top">secpropag</td>
@@ -1689,42 +1685,42 @@
       <td valign="top" align="center">No</td>
     </tr>
     <tr>
-      <td valign="Top">verbose</td>
-      <td valign="Top">Indicates whether or not to use -verbose switch. If
+      <td valign="top">verbose</td>
+      <td valign="top">Indicates whether or not to use -verbose switch. If
       omitted, it defaults to <code>false</code>.</td>
-      <td align="Center" valign="Top">No</td>
+      <td align="center" valign="top">No</td>
     </tr>
     <tr>
-      <td valign="Top">additionalargs</td>
-      <td valign="Top">Add additional args to GenIC.</td>
-      <td align="Center" valign="Top">No</td>
+      <td valign="top">additionalargs</td>
+      <td valign="top">Add additional args to GenIC.</td>
+      <td align="center" valign="top">No</td>
     </tr>
     <tr>
-      <td valign="Top">keepgeneric</td>
-      <td valign="Top"><code>true</code> if the generic JAR file used as input
+      <td valign="top">keepgeneric</td>
+      <td valign="top"><code>true</code> if the generic JAR file used as input
       to GenIC must be retained. If omitted, it defaults to <code>false</code>.</td>
-      <td align="Center" valign="Top">No</td>
+      <td align="center" valign="top">No</td>
     </tr>
     <tr>
-      <td valign="Top">jarsuffix</td>
+      <td valign="top">jarsuffix</td>
       <td>String value appended to the JAR filename when creating each JAR.  If
-      omitted, it defaults to ".jar". </td>
-      <td align="Center" valign="Top">No</td>
+      omitted, it defaults to ".jar".</td>
+      <td align="center" valign="top">No</td>
     </tr>
     <tr>
-      <td valign="Top">orb</td>
+      <td valign="top">orb</td>
       <td>Choose your ORB : RMI, JEREMIE, DAVID. If omitted, it defaults to the
       one present in classpath. If specified, the corresponding JOnAS JAR is
       automatically added to the classpath.</td>
-      <td align="Center" valign="Top">No</td>
+      <td align="center" valign="top">No</td>
     </tr>
     <tr>
-      <td valign="Top">nogenic</td>
-      <td valign="Top">If this attribute is set to <code>true</code>,
+      <td valign="top">nogenic</td>
+      <td valign="top">If this attribute is set to <code>true</code>,
       JOnAS's GenIC will not be run on the EJB JAR. Use this if you
       prefer to run GenIC at deployment time. If omitted, it defaults
       to <code>false</code>.</td>
-      <td align="Center" valign="Top">No</td>
+      <td align="center" valign="top">No</td>
     </tr>
     <tr>
   </tbody>
@@ -1774,14 +1770,14 @@
 </pre>
 
 
-<h3><a name="ejbjar_orion">Orion element</a></h3>
+<h3 id="ejbjar_orion">Orion element</h3>
 
 <p>The orion element searches for the Orion Application Server specific deployment descriptors and adds them
 to the final ejb jar file. Orion has one deployment descriptor:
 <ul><li>orion-ejb-jar.xml</li>
 </ul>
 <br>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -1792,7 +1788,7 @@
     <td valign="top">The base directory into which the generated
                      jar files are deposited. Jar files are deposited in
                      directories corresponding to their location within the
-                     descriptordir namespace. </td>
+                     descriptordir namespace.</td>
     <td valign="top" align="center">Yes</td>
   </tr>
 </table>
@@ -1812,5 +1808,4 @@
 </pre>
 
 </body>
-
 </html>
diff --git a/manual/Tasks/exec.html b/manual/Tasks/exec.html
index 8dfc6bc..bb7a17a 100644
--- a/manual/Tasks/exec.html
+++ b/manual/Tasks/exec.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="exec">Exec</a></h2>
+<h2 id="exec">Exec</h2>
 <h3>Description</h3>
 <p>Executes a system command. When the <i>os</i> attribute is specified, then
 the command is only executed when Apache Ant is run on one of the specified operating
@@ -32,7 +32,7 @@
 
 <p>Note that you cannot interact with the forked program, the only way
 to send input to it is via the input and inputstring attributes. Also note that
-since Ant 1.6, any attempt to read input in the forked program will receive an
+<em>since Ant 1.6</em>, any attempt to read input in the forked program will receive an
 EOF (-1). This is a change from Ant 1.5, where such an attempt would block.</p>
 
 <p>If you want to execute an executable using a path relative to the
@@ -40,13 +40,12 @@
   use <code>vmlauncher="false"</code> on some operating systems - but
   even this may fail (Solaris 8/9 has been reported as problematic).
   The <code>resolveexecutable</code> attribute should be more
-  reliable, as would be something like
+  reliable, as would be something like</p>
 <pre>
   &lt;property name="executable-full-path"
             location="../relative/path/to/executable"/&gt;
   &lt;exec executable="${executable-full-path}" ...
 </pre>
-</p>
 
 <h4>Windows Users</h4>
 <p>The <code>&lt;exec&gt;</code> task delegates to <code>Runtime.exec</code> which in turn
@@ -87,7 +86,7 @@
 running is a standard Windows executable and is not aware of the Cygwin
 environment (i.e., doesn't load <code>cygwin1.dll</code>).  The only
 work-around for this is to compile a JVM under Cygwin (at your own risk).
-See for instance 
+See for instance
 <a href="http://hg.openjdk.java.net/jdk7/build/raw-file/tip/README-builds.html#cygwin">
 OpenJDK build instructions for cygwin</a>.
 </p>
@@ -95,7 +94,7 @@
 <h4>OpenVMS Users</h4>
 <p>The command specified using <code>executable</code> and
 <code>&lt;arg&gt;</code> elements is executed exactly as specified
-inside a temporary DCL script.  This has some implications:
+inside a temporary DCL script.  This has some implications:</p>
 <ul>
 <li>paths have to be written in VMS style</li>
 <li>if your <code>executable</code> points to a DCL script remember to
@@ -103,7 +102,7 @@
 (e.g. <code>executable="@[FOO]BAR.COM"</code>), just as you would in a
 DCL script</li>
 </ul>
-For <code>&lt;exec&gt;</code> to work in an environment with a Java VM
+<p>For <code>&lt;exec&gt;</code> to work in an environment with a Java VM
 older than version 1.4.1-2 it is also <i>required</i> that the logical
 <code>JAVA$FORK_SUPPORT_CHDIR</code> is set to <code>TRUE</code> in
 the job table (see the <i>JDK Release Notes</i>).</p>
@@ -122,7 +121,7 @@
 href="http://listserv.uark.edu/scripts/wa.exe?A1=ind0404&L=vmesa-l#33">reported
 on the VMESA-LISTSERV</a> that shell scripts invoked via the Ant Exec
 task must have their interpreter specified, i.e., the scripts must
-start with something like:
+start with something like:</p>
 
 <blockquote>
 <pre>
@@ -130,7 +129,7 @@
 </pre>
 </blockquote>
 
-or the task will fail as follows:
+<p>or the task will fail as follows:</p>
 
 <blockquote>
 <pre>
@@ -138,10 +137,8 @@
 [exec] Result: 255
 </pre>
 </blockquote>
-</p>
 
-<h4><a name="background">Running Ant as a background process on
-    Unix(-like) systems</a></h4>
+<h4 id="background">Running Ant as a background process on Unix(-like) systems</h4>
 
 <p>If you run Ant as a background process (like <code>ant &</code>)
   and use the <code>&lt;exec&gt;</code> task with <code>spawn</code>
@@ -150,7 +147,7 @@
   from the standard input.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -161,7 +158,7 @@
     <td valign="top">the command to execute with all command line
       arguments. <b>deprecated, use executable and nested
       <code>&lt;arg&gt;</code> elements instead</b>.</td>
-    <td align="center" rowspan="2">Exactly one of the two.</td>
+    <td align="center" rowspan="2">Exactly one of the two</td>
   </tr>
   <tr>
     <td valign="top">executable</td>
@@ -171,8 +168,8 @@
   <tr>
     <td valign="top">dir</td>
     <td valign="top">the directory in which the command should be executed.</td>
-    <td align="center" valign="top">No.<br/>
-      <strong>Note:</strong> the default used when dir has not been
+    <td align="center" valign="top">No<br/>
+      <strong>Note</strong>: the default used when dir has not been
       specified depends on the <code>vmlauncher</code> attribute.  If
       <code>vmlauncher</code> is <code>true</code> the task will use
       the current working directory, otherwise it uses the project's basedir.
@@ -197,7 +194,7 @@
     <td valign="top">spawn</td>
     <td valign="top">whether or not you want the command to be spawned<br>
     Default is false.<br>
-    If you spawn a command, its output will not be logged by ant.<br>
+    If you spawn a command, its output will not be logged by Ant.<br>
     The input, output, error, and result property settings are not active when spawning a process.<br>
     <em>since Ant 1.6</em>
     </td>
@@ -278,9 +275,10 @@
   <tr>
     <td valign="top">failifexecutionfails</td>
     <td valign="top">Stop the build if we can't start the program.
-      Defaults to true. </td>
+      Defaults to true.</td>
     <td align="center" valign="top">No</td>
-  </tr>  <tr>
+  </tr>
+  <tr>
     <td valign="top">newenvironment</td>
     <td valign="top">Do not propagate old environment when new environment
       variables are specified.</td>
@@ -331,10 +329,10 @@
 <p>Command line arguments should be specified as nested
 <code>&lt;arg&gt;</code> elements. See <a
 href="../using.html#arg">Command line arguments</a>.</p>
-<h4><a name="env">env</a></h4>
+<h4 id="env">env</h4>
 <p>It is possible to specify environment variables to pass to the
 system command via nested <code>&lt;env&gt;</code> elements.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -345,15 +343,15 @@
     <td valign="top">
       The name of the environment variable.
       <br/>
-      <em>Note: (Since Ant 1.7)</em>
-      For windows, the name is case-insensitive.
+      <strong>Note</strong>: <em>since Ant 1.7</em>,
+      for Windows, the name is case-insensitive.
     </td>
     <td align="center" valign="top">Yes</td>
   </tr>
   <tr>
     <td valign="top">value</td>
     <td valign="top">The literal value for the environment variable.</td>
-    <td align="center" rowspan="3">Exactly one of these.</td>
+    <td align="center" rowspan="3">Exactly one of these</td>
   </tr>
   <tr>
     <td valign="top">path</td>
@@ -367,14 +365,14 @@
       replaced by the absolute filename of the file by Ant.</td>
   </tr>
 </table>
-<a name="redirector"><h4>redirector</h4></a>
-<i><b>Since Ant 1.6.2</b></i>
+<h4 id="redirector">redirector</h4>
+<em>Since Ant 1.6.2</em>
 <p>A nested <a href="../Types/redirector.html">I/O Redirector</a>
 can be specified.  In general, the attributes of the redirector behave
 as the corresponding attributes available at the task level.  The most
 notable peculiarity stems from the retention of the &lt;exec&gt;
 attributes for backwards compatibility.  Any file mapping is done
-using a <CODE>null</CODE> sourcefile; therefore not all
+using a <code>null</code> sourcefile; therefore not all
 <a href="../Types/mapper.html">Mapper</a> types will return
 results.  When no results are returned, redirection specifications
 will fall back to the task level attributes.  In practice this means that
@@ -448,18 +446,14 @@
 in a property of the same name.  Similarly, error output is sent to
 a file and a property, both named &quot;redirector.err&quot;.
 
-
-<p><b>Note:</b> do not try to specify arguments using
+<p><strong>Note</strong>: do not try to specify arguments using
 a simple arg-element and separate them by spaces. This results in
 only a single argument containing the entire string.</p>
 <p>
-<b>Timeouts: </b> If a timeout is specified, when it is reached the
+<b>Timeouts:</b> If a timeout is specified, when it is reached the
 sub process is killed and a message printed to the log. The return
 value of the execution will be "-1", which will halt the build if
 <tt>failonerror=true</tt>, but be ignored otherwise.
-
-
-
+</p>
 </body>
 </html>
-
diff --git a/manual/Tasks/fail.html b/manual/Tasks/fail.html
index eabe30b..f803783 100644
--- a/manual/Tasks/fail.html
+++ b/manual/Tasks/fail.html
@@ -24,14 +24,14 @@
 
 <body>
 
-<h2><a name="fail">Fail</a></h2>
+<h2 id="fail">Fail</h2>
 <h3>Description</h3>
 <p>Exits the current build (just throwing a BuildException), optionally printing additional information.</p>
 <p>The message of the Exception can be set via the message attribute
 or character data nested into the element.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -69,7 +69,7 @@
   conditional failure can be achieved using a single nested
   <code>&lt;condition&gt;</code> element, which should contain exactly one
   core or custom condition.  For information about conditions, see
-  <a href="conditions.html">here</a>.<br><b>Since Ant 1.6.2</b>
+  <a href="conditions.html">here</a>.<br><em>Since Ant 1.6.2</em>
 </p>
 
 <h3>Examples</h3>
@@ -140,4 +140,3 @@
 
 </body>
 </html>
-
diff --git a/manual/Tasks/filter.html b/manual/Tasks/filter.html
index 16ba88c..90e85a9 100644
--- a/manual/Tasks/filter.html
+++ b/manual/Tasks/filter.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="filter">Filter</a></h2>
+<h2 id="filter">Filter</h2>
 <h3>Description</h3>
 <p>Sets a token filter for this project or read multiple token filter from
 an input file and sets these as filters.
@@ -36,7 +36,7 @@
 filtersfile attribute.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -49,13 +49,13 @@
   </tr>
   <tr>
     <td valign="top">value</td>
-    <td valign="top">the string that should be put to replace the token when the 
+    <td valign="top">the string that should be put to replace the token when the
       file is copied</td>
     <td align="center" valign="top">Yes*</td>
   </tr>
   <tr>
     <td valign="top">filtersfile</td>
-    <td valign="top">The file from which the filters must be read. This file must be a formatted as a property file. </td>
+    <td valign="top">The file from which the filters must be read. This file must be a formatted as a property file.</td>
     <td align="center" valign="top">Yes*</td>
   </tr>
 </table>
@@ -64,7 +64,7 @@
 <pre>  &lt;filter token=&quot;year&quot; value=&quot;2000&quot;/&gt;
   &lt;copy todir=&quot;${dest.dir}&quot; filtering=&quot;true&quot;&gt;
     &lt;fileset dir=&quot;${src.dir}&quot;/&gt;
-  &lt;/copy&gt;</pre> 
+  &lt;/copy&gt;</pre>
 <p>will copy recursively all the files from the <i>src.dir</i> directory into
 the <i>dest.dir</i> directory replacing all the occurrences of the string <i>@year@</i>
 with <i>2000.</i></p>
@@ -72,8 +72,5 @@
 will read all property entries from the <i>deploy_env.properties</i> file
 and set these as filters.
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/fixcrlf.html b/manual/Tasks/fixcrlf.html
index 2637401..e395ea4 100644
--- a/manual/Tasks/fixcrlf.html
+++ b/manual/Tasks/fixcrlf.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="fixcrlf">FixCRLF</a></h2>
+<h2 id="fixcrlf">FixCRLF</h2>
 <h3>Description</h3>
   <p>
     Adjusts a text file to local conventions.
@@ -62,12 +62,12 @@
   </p>
 
   <p>
-    Since <b>Apache Ant 1.7</b>, this task can be used in a
+    <em>Since Apache Ant 1.7</em>, this task can be used in a
     <a href="../Types/filterchain.html">filterchain</a>.
   </p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="center" rowspan="2"><b>Attribute</b></td>
     <td valign="center" rowspan="2"><b>Description</b></td>
@@ -81,47 +81,47 @@
     <td valign="top">srcDir</td>
     <td valign="top">Where to find the files to be fixed up.</td>
     <td valign="top" align="center" rowspan="2">One of these</td>
-    <td bgcolor="#CCCCCC">&nbsp;</td>
+    <td>&nbsp;</td>
   </tr>
   <tr>
     <td valign="top">file</td>
-    <td valign="top">Name of a single file to fix. <b>Since Ant 1.7</b></td>
-    <td bgcolor="#CCCCCC">&nbsp;</td>
+    <td valign="top">Name of a single file to fix. <em>Since Ant 1.7</em></td>
+    <td>&nbsp;</td>
   </tr>
   <tr>
     <td valign="top">destDir</td>
     <td valign="top">Where to place the corrected files.  Defaults to
       srcDir (replacing the original file).</td>
     <td valign="top" align="center">No</td>
-    <td bgcolor="#CCCCCC">&nbsp;</td>
+    <td>&nbsp;</td>
   </tr>
   <tr>
     <td valign="top">includes</td>
     <td valign="top">comma- or space-separated list of patterns of files that must be
       included. All files are included when omitted.</td>
     <td valign="top" align="center">No</td>
-    <td bgcolor="#CCCCCC">&nbsp;</td>
+    <td>&nbsp;</td>
   </tr>
   <tr>
     <td valign="top">includesfile</td>
     <td valign="top">the name of a file. Each line of this file is
       taken to be an include pattern.</td>
     <td valign="top" align="center">No</td>
-    <td bgcolor="#CCCCCC">&nbsp;</td>
+    <td>&nbsp;</td>
   </tr>
   <tr>
     <td valign="top">excludes</td>
     <td valign="top">comma- or space-separated list of patterns of files that must be
       excluded. No files (except default excludes) are excluded when omitted.</td>
     <td valign="top" align="center">No</td>
-    <td bgcolor="#CCCCCC">&nbsp;</td>
+    <td>&nbsp;</td>
   </tr>
   <tr>
     <td valign="top">excludesfile</td>
     <td valign="top">the name of a file. Each line of this file is
       taken to be an exclude pattern.</td>
     <td valign="top" align="center">No</td>
-    <td bgcolor="#CCCCCC">&nbsp;</td>
+    <td>&nbsp;</td>
   </tr>
   <tr>
     <td valign="top">defaultexcludes</td>
@@ -129,27 +129,27 @@
       (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.
     </td>
     <td valign="top" align="center">No</td>
-    <td bgcolor="#CCCCCC">&nbsp;</td>
+    <td>&nbsp;</td>
   </tr>
   <tr>
     <td valign="top">encoding</td>
     <td valign="top">The encoding of the files.</td>
     <td align="center">No; defaults to default JVM encoding.</td>
-    <td bgcolor="#CCCCCC">&nbsp;</td>
+    <td>&nbsp;</td>
   </tr>
   <tr>
     <td valign="top">outputencoding</td>
     <td valign="top">The encoding to use when writing the files.
-                     <b>Since Ant 1.7</b></td>
+                     <em>Since Ant 1.7</em></td>
     <td align="center">No; defaults to the value of the encoding attribute.</td>
-    <td bgcolor="#CCCCCC">&nbsp;</td>
+    <td>&nbsp;</td>
   </tr>
   <tr>
     <td valign="top">preservelastmodified</td>
     <td valign="top">Whether to preserve the last modified
-                     date of source files. <b>Since Ant 1.6.3</b></td>
+                     date of source files. <em>Since Ant 1.6.3</em></td>
     <td align="center">No; default is <i>false</i></td>
-    <td bgcolor="#CCCCCC">&nbsp;</td>
+    <td>&nbsp;</td>
   </tr>
   <tr>
     <td valign="top">eol</td>
@@ -280,7 +280,7 @@
   <tr>
     <td valign="top">fixlast</td>
     <td valign="top">Whether to add a missing EOL to the last line
-                     of a processed file.<br/>Ignored if EOL is asis.<br/><b>Since Ant 1.6.1</b></td>
+                     of a processed file.<br/>Ignored if EOL is asis.<br/><em>Since Ant 1.6.1</em></td>
     <td align="center" colspan="2">No; default is <i>true</i></td>
   </tr>
 </table>
@@ -322,6 +322,5 @@
   DOS systems, and are removed if run on Unix systems.
   You never know what editor a user will use to browse READMEs.</p>
 
-
 </body>
 </html>
diff --git a/manual/Tasks/ftp.html b/manual/Tasks/ftp.html
index 83c18e3..1961e8c 100644
--- a/manual/Tasks/ftp.html
+++ b/manual/Tasks/ftp.html
@@ -24,12 +24,12 @@
 
 <body>
 
-<h2><a name="ftp">FTP</a></h2>
+<h2 id="ftp">FTP</h2>
 <h3>Description</h3>
 <p>The ftp task implements a basic FTP client that can send, receive,
 list, delete files, and create directories.  See below for descriptions and examples of how
 to perform each task.</p>
-<p><b>Note:</b> This task depends on external libraries not included in the Apache Ant distribution.
+<p><strong>Note</strong>: This task depends on external libraries not included in the Apache Ant distribution.
 See <a href="../install.html#commons-net">Library Dependencies</a> for more information.
 <i>Get the latest version of this library, for the best support in Ant</i>
 
@@ -48,13 +48,13 @@
 <p>
 This task does not currently use the proxy information set by the
 <a href="setproxy.html"><code>&lt;setproxy&gt;</code></a> task, and cannot go through
-a firewall via socks. 
+a firewall via socks.
 <p>
-<b>Warning: </b> there have been problems reported concerning the ftp get with the <code>newer</code> attribute.
-Problems might be due to format of ls -l differing from what is expected by commons-net,
-for instance due to specificities of language used by the ftp server in the directory listing.
+<strong>Warning:</strong> there have been problems reported concerning the ftp get with the <code>newer</code> attribute.
+Problems might be due to format of <code>ls -l</code> differing from what is expected by commons-net,
+for instance due to specifics of language used by the ftp server in the directory listing.
 If you encounter such a problem, please send an email including a sample directory listing
-coming from your ftp server (ls -l on the ftp prompt).
+coming from your ftp server (<code>ls -l</code>code> on the ftp prompt).
 </p>
 <p>
 If you can connect but not upload or download, try setting the <code>passive</code>
@@ -62,7 +62,7 @@
 try to set up a new connection.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top" width="15%"><b>Attribute</b></td>
     <td valign="top" width="65%"><b>Description</b></td>
@@ -92,8 +92,7 @@
   <tr>
     <td valign="top">account</td>
     <td valign="top">the account to use on the ftp server.
-        <em>since Ant 1.7</em>.
-    </td>
+    <em>since Ant 1.7</em>.</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -129,13 +128,13 @@
   </tr>
   <tr>
     <td valign="top">verbose</td>
-    <td valign="top">displays information on each file transferred if set 
+    <td valign="top">displays information on each file transferred if set
                      to "yes". Defaults to "no".</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
     <td valign="top">depends</td>
-    <td valign="top">transfers only new or changed files if set to 
+    <td valign="top">transfers only new or changed files if set to
                      "yes". Defaults to "no".</td>
     <td valign="top" align="center">No</td>
   </tr>
@@ -148,37 +147,34 @@
   <tr>
     <td valign="top">timediffauto</td>
     <td valign="top">set to <code>"true"</code>
-    to make ant calculate the time difference between client and server.<br>
+    to make Ant calculate the time difference between client and server.<br>
     <em>requires write access in the remote directory</em><br>
-    Since ant 1.6</td>
+    <em>Since Ant 1.6</em></td>
     <td valign="top" align="center">No</td>
   </tr>
-  <a name="timestampGranularity"/>
-  <tr>
+  <tr id="timestampGranularity">
     <td valign="top">timestampGranularity</td>
     <td valign="top">Specify either <code>MINUTE</code>, <code>NONE</code>,
      (or you may specify <code>""</code> which is equivalent to not specifying a value,
-     useful for property-file driven scripts).  Allows override of the typical situation 
-     in PUT and GET where local filesystem timestamps are <code>HH:mm:ss</code> 
-     and the typical FTP server's timestamps are <code>HH:mm</code>.  This can throw 
+     useful for property-file driven scripts).  Allows override of the typical situation
+     in PUT and GET where local filesystem timestamps are <code>HH:mm:ss</code>
+     and the typical FTP server's timestamps are <code>HH:mm</code>.  This can throw
      off uptodate calculations.  However, the default values should suffice for most
      applications.<br>
-    Since ant 1.7
-    </td>
+     <em>Since Ant 1.7</em></td>
     <td valign="top" align="center">No.  Only applies in "puts" and "gets" where the
-    default values are <code>MINUTE</code> for PUT and <code>NONE</code> for GET.  
+    default values are <code>MINUTE</code> for PUT and <code>NONE</code> for GET.
     (It is not as necessary in GET because we have the <b>preservelastmodified</b> option.)</td>
   </tr>
   <tr>
     <td valign="top">timediffmillis</td>
-    <td valign="top"><b>Deprecated</b>. Number of milliseconds to add to the time on 
-    the remote machine to get the time on the local machine.  The <b>timestampGranularity</b> 
-    attribute (for which the default values should suffice in most situations), and the 
-    <b>serverTimeZoneConfig</b> option, should make this unnecessary. 
-    <b>serverTimeZoneConfig</b> does the math for you and also knows about 
+    <td valign="top"><b>Deprecated</b>. Number of milliseconds to add to the time on
+    the remote machine to get the time on the local machine.  The <b>timestampGranularity</b>
+    attribute (for which the default values should suffice in most situations), and the
+    <b>serverTimeZoneConfig</b> option, should make this unnecessary.
+    <b>serverTimeZoneConfig</b> does the math for you and also knows about
     Daylight Savings Time.<br>
-    Since ant 1.6
-    </td>
+    <em>Since Ant 1.6</em></td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -218,18 +214,18 @@
     and get operations to be skipped with a warning and the
     remainder of the files still transferred. Default: false</td>
     <td valign="top" align="center">No</td>
-  </tr>  
+  </tr>
   <tr>
     <td valign="top">preservelastmodified</td>
     <td valign="top">Give the copied files the same last modified
       time as the original source files (applies to getting files only).
-      (<em>Note</em>: Ignored on Java 1.1)</td>
+      (<strong>Note</strong>: Ignored on Java 1.1)</td>
     <td valign="top" align="center">No; defaults to false.</td>
   </tr>
   <tr>
     <td valign="top">retriesAllowed</td>
     <td valign="top">Set the number of retries allowed on an file-transfer operation.
-    If a number > 0 specified, each file transfer can fail up to that
+    If a number &gt; 0 specified, each file transfer can fail up to that
     many times before the operation is failed.  If -1 or "forever" specified, the
     operation will keep trying until it succeeds.</td>
     <td valign="top" align="center">No; defaults to 0</td>
@@ -252,7 +248,7 @@
     connect to the same host as the control connection.  This is a
     security measure that is enabled by default, but it may be useful
     to disable it in certain firewall scenarios.
-      <em>since Ant 1.8.0</em></td>
+    <em>since Ant 1.8.0</em></td>
     <td valign="top" align="center">No, default is true</td>
   </tr>
 
@@ -262,12 +258,12 @@
     "http://commons.apache.org/net/download_net.cgi">
     jakarta-commons-net-1.4.0 or greater</a>.</b></p>
     <p>
-    Use these options when the standard options don't work, because
+    Use these options when the standard options don't work, because</p>
     <ul><li>the server is in a different timezone and you need timestamp
     dependency checking</li>
     <li>the default timestamp formatting doesn't match the server display and
     list parsing therefore fails</li></ul>
-    </p><p>
+    <p>
     If none of these is specified, the default mechanism of letting the system
     auto-detect the server OS type based on the FTP SYST command and assuming
     standard formatting for that OS type will be used.
@@ -278,7 +274,7 @@
     </p><p>
     Please understand that these options are incompatible with the autodetection
     scheme.  If any of these options is specified, (other than with a value of
-    <code>""</code> ) a system type must be chosen and if systemTypeKey is not
+    <code>""</code>) a system type must be chosen and if systemTypeKey is not
     specified, UNIX will be assumed. The philosophy behind this is that these
     options are for setting non-standard formats, and a build-script author who
     knows what system he is dealing with will know what options to need to be
@@ -293,8 +289,7 @@
       "MVS".</code>  If not specified, (or specified as <code>""</code>) and if
       no other xxxConfig attributes are specified, the autodetection mechanism
       based on the FTP SYST command will be used.<br>
-      Since ant 1.7
-    </td>
+      <em>Since Ant 1.7</em></td>
     <td valign="top" align="center">No, but if any of the following xxxConfig
         attributes is specified, UNIX will be assumed, even if <code>""</code>
         is specified here.
@@ -305,19 +300,18 @@
     <td valign="top">Specify as a Java
      <a href="http://docs.oracle.com/javase/7/docs/api//java/util/TimeZone.html">
      TimeZone</a> identifier, (e.g. <code>GMT</code>, <code>America/Chicago</code> or
-    <code>Asia/Jakarta</code>) the timezone used by the server for timestamps.  This 
-      enables timestamp dependency checking even when the server is in a different 
-      time zone from the client. Time Zones know, also, about daylight savings time, 
-      and do not require you to calculate milliseconds of difference.  If not specified, 
+    <code>Asia/Jakarta</code>) the timezone used by the server for timestamps.  This
+      enables timestamp dependency checking even when the server is in a different
+      time zone from the client. Time Zones know, also, about daylight savings time,
+      and do not require you to calculate milliseconds of difference.  If not specified,
       (or specified as <code>""</code>), the time zone of the client is assumed.<br>
-      Since ant 1.7
-    </td>
+      <em>Since Ant 1.7</em></td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
-    
+
     <td valign="top">defaultDateFormatConfig</td>
-    <td valign="top">Specify in Java 
+    <td valign="top">Specify in Java
     <a href="http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html">
      SimpleDateFormat</a> notation, (e.g.
      <code>yyyy-MM-dd</code>), the date format generally used by the FTP server
@@ -326,23 +320,21 @@
       older than a year old. (See <b>recentDateFormatConfig</b>).  If not specified,
       (or specified as <code>""</code>), the default date format for the system
       type indicated by the <b>systemTypeKey</b> attribute will be used.<br>
-      Since ant 1.7
-    </td>
+      <em>Since Ant 1.7</em></td>
     <td valign="top" align="center">
     No.
     </td>
   </tr>
   <tr>
     <td valign="top">recentDateFormatConfig</td>
-    <td valign="top">Specify in Java 
+    <td valign="top">Specify in Java
     <a href="http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html">
      SimpleDateFormat</a> notation,
       (e.g. <code>MMM dd hh:mm</code>) the date format used by the FTP server
       to parse dates less than a year old.  If not specified (or specified as
       <code>""</code>), and if the system type indicated by the system key uses
       a recent date format, its standard format will be used.<br>
-      Since ant 1.7
-    </td>
+      <em>Since Ant 1.7</em></td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -374,9 +366,7 @@
       </ul>
       If you require a language other than the above, see also the
       <b>shortMonthNamesConfig</b> attribute.<br>
-      Since ant 1.7
-    </td>
-
+      <em>Since Ant 1.7</em></td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -388,93 +378,70 @@
       <code>"jan|feb|mar|apr|ma&#xED;|j&#xFA;n|j&#xFA;l|&#xE1;g&#xFA;|sep|okt|n&#xF3;v|des"</code>.
       This attribute exists primarily to support languages not supported by
       the <b>serverLanguageCode</b> attribute.<br>
-      Since ant 1.7
-    </td>
+      <em>Since Ant 1.7</em></td>
     <td valign="top" align="center">No</td>
   </tr>
 </table>
 <h3>Note about remotedir attribute</h3>
-<table  border="1" cellpadding="2" cellspacing="0"
- >
+<table>
   <tbody>
     <tr>
-      <td style="vertical-align: top;" width="20%">Action<br>
-      </td>
-      <td style="vertical-align: top;" width="40%">meaning of <code>remotedir</code><br>
-      </td>
-      <td style="vertical-align: top;">use of nested <code>fileset</code>
-(s)<br>
-      </td>
+      <td style="vertical-align: top;" width="20%">Action</td>
+      <td style="vertical-align: top;" width="40%">meaning of <code>remotedir</code></td>
+      <td style="vertical-align: top;">use of nested <code>fileset</code>(s)</td>
     </tr>
     <tr>
-      <td style="vertical-align: top;" width="20%">send/put<br>
-      </td>
+      <td style="vertical-align: top;" width="20%">send/put</td>
       <td style="vertical-align: top;" width="40%">base directory to
-which the files are sent<br>
-      </td>
+which the files are sent</td>
       <td style="vertical-align: top;">they are used normally and
-evaluated on the local machine<br>
-      </td>
+evaluated on the local machine</td>
     </tr>
     <tr>
-      <td style="vertical-align: top;" width="20%">recv/get<br>
-      </td>
+      <td style="vertical-align: top;" width="20%">recv/get</td>
       <td style="vertical-align: top;" width="40%">base directory from
-which the files are retrieved<br>
-      </td>
+which the files are retrieved</td>
       <td style="vertical-align: top;">the remote files located under
-the <code>remotedir </code>matching the include/exclude patterns of
-the <code>fileset&nbsp;</code></td>
+the <code>remotedir</code> matching the include/exclude patterns of
+the <code>fileset</code></td>
     </tr>
     <tr>
-      <td style="vertical-align: top;" width="20%">del/delete<br>
-      </td>
+      <td style="vertical-align: top;" width="20%">del/delete</td>
       <td style="vertical-align: top;" width="40%">base directory from
-which files get deleted<br>
-      </td>
+which files get deleted</td>
       <td style="vertical-align: top;">the remote files located under
-the <code>remotedir </code>matching the include/exclude patterns of
-the <code>fileset <br>
-      </code></td>
+the <code>remotedir</code> matching the include/exclude patterns of
+the <code>fileset</code></td>
     </tr>
     <tr>
-      <td style="vertical-align: top;" width="20%">list<br>
-      </td>
+      <td style="vertical-align: top;" width="20%">list</td>
       <td style="vertical-align: top;" width="40%">base directory from
 which files are listed<br>
       </td>
       <td style="vertical-align: top;">the remote files located under
-the <code>remotedir </code>matching the include/exclude patterns of
-the <code>fileset <br>
-      </code></td>
+the <code>remotedir</code> matching the include/exclude patterns of
+the <code>fileset</code></td>
     </tr>
     <tr>
       <td style="vertical-align: top;" width="20%">mkdir</td>
-      <td style="vertical-align: top;" width="40%">directory to create<br>
-      </td>
-      <td style="vertical-align: top;">not used<br>
-      </td>
+      <td style="vertical-align: top;" width="40%">directory to create</td>
+      <td style="vertical-align: top;">not used</td>
     </tr>
     <tr>
       <td style="vertical-align: top;" width="20%">chmod</td>
       <td style="vertical-align: top;" width="40%">base directory from
-which the mode of files get changed<br>
-      </td>
+which the mode of files get changed</td>
       <td style="vertical-align: top;">the remote files located under
-the <code>remotedir </code>matching the include/exclude patterns of
-the <code>fileset <br>
-      </code></td>
+the <code>remotedir</code> matching the include/exclude patterns of
+the <code>fileset</code></td>
     </tr>
     <tr>
-      <td style="vertical-align: top;" width="20%">rmdir<br>
-      </td>
+      <td style="vertical-align: top;" width="20%">rmdir</td>
       <td style="vertical-align: top;" width="40%">base directory from
-which directories get removed<br>
-      </td>
+which directories get removed</td>
       <td style="vertical-align: top;">the remote directories located
-under the <code>remotedir </code>matching the include/exclude
-patterns of the <code>fileset <br>
-      </code></td>
+under the <code>remotedir</code> matching the include/exclude
+patterns of the <code>fileset</code></td>
     </tr>
   </tbody>
 </table><h3>Parameters specified as nested elements</h3>
@@ -485,8 +452,8 @@
 <p>
 The attribute <code>followsymlinks</code> of <code>fileset</code> is supported on
 local (put) as well as remote (get, chmod, delete) filesets.
-<em>Before ant 1.6 there was no support of symbolic links in remote filesets.
-In order to exclude symbolic links (preserve the behavior of ant 1.5.x and older),
+<em>Before Ant 1.6 there was no support of symbolic links in remote filesets.
+In order to exclude symbolic links (preserve the behavior of Ant 1.5.x and older),
 you need to explicitly set <code>followsymlinks</code> to <code>false</code>.</em>
 On remote filesets hidden files are not checked for being symbolic links. Hidden
 files are currently assumed to not be symbolic links.
@@ -501,8 +468,8 @@
     &lt;fileset dir="htdocs/manual"/&gt;
   &lt;/ftp&gt;
 </pre>
-<p>Logs in to <code>ftp.apache.org</code> as <code>anonymous</code> and 
-uploads all files in the <code>htdocs/manual</code> directory 
+<p>Logs in to <code>ftp.apache.org</code> as <code>anonymous</code> and
+uploads all files in the <code>htdocs/manual</code> directory
 to the default directory for that user.</p>
 <pre>  &lt;ftp server="ftp.apache.org"
        remotedir="incoming"
@@ -512,7 +479,7 @@
     &lt;fileset dir="htdocs/manual"/&gt;
   &lt;/ftp&gt;</pre>
 <p>Logs in to <code>ftp.apache.org</code> as <code>anonymous</code> and
-uploads all new or changed files in the <code>htdocs/manual</code> directory 
+uploads all new or changed files in the <code>htdocs/manual</code> directory
 to the <code>incoming</code> directory relative to the default directory
 for <code>anonymous</code>.</p>
 <pre>  &lt;ftp server="ftp.apache.org"
@@ -560,13 +527,13 @@
     &lt;fileset dir="htdocs/manual"&gt;
       &lt;include name="**/*.html"/&gt;
     &lt;/fileset&gt;
-  &lt;/ftp&gt;</pre><p>Logs in to the Windows-based <code>ftp.nt.org</code> as 
-<code>coder</code> with password <code>java1</code> and uploads all 
-HTML files in the <code>htdocs/manual</code> directory to the 
+  &lt;/ftp&gt;</pre><p>Logs in to the Windows-based <code>ftp.nt.org</code> as
+<code>coder</code> with password <code>java1</code> and uploads all
+HTML files in the <code>htdocs/manual</code> directory to the
 <code>c:\uploads</code> directory.  Progress messages are displayed as each
 file is uploaded.</p>
 <h3>Getting Files</h3>
-<p>Getting files from an FTP server works pretty much the same way as 
+<p>Getting files from an FTP server works pretty much the same way as
 sending them does.  The only difference is that the nested filesets
 use the remotedir attribute as the base directory for the files on the
 FTP server, and the dir attribute as the local directory to put the files
@@ -581,8 +548,8 @@
     &lt;/fileset&gt;
   &lt;/ftp&gt;
 </pre>
-<p>Logs in to <code>ftp.apache.org</code> as <code>anonymous</code> and 
-recursively downloads all .html files from default directory for that user 
+<p>Logs in to <code>ftp.apache.org</code> as <code>anonymous</code> and
+recursively downloads all .html files from default directory for that user
 into the <code>htdocs/manual</code> directory on the local machine.</p>
 <pre>
   &lt;ftp action="get"
@@ -621,8 +588,8 @@
 into the <code>htdocs/manual</code> directory on the local machine.</p>
 
 <h3>Deleting Files</h3>
-As you've probably guessed by now, you use nested fileset elements to 
-select the files to delete from the remote FTP server.  Again, the 
+As you've probably guessed by now, you use nested fileset elements to
+select the files to delete from the remote FTP server.  Again, the
 filesets are relative to the remote directory, not a local directory.  In
 fact, the dir attribute of the fileset is ignored completely.
 
@@ -669,14 +636,14 @@
 directory.  As with all other actions, the directory separator character must be correct
 according to the desires of the FTP server.</p>
 <h3>Removing Directories</h3>
-This action uses nested fileset elements to 
-select the directories to remove from the remote FTP server.  The 
-filesets are relative to the remote directory, not a local directory. 
+This action uses nested fileset elements to
+select the directories to remove from the remote FTP server.  The
+filesets are relative to the remote directory, not a local directory.
 The dir attribute of the fileset is ignored completely.
 The directories to be removed must be empty, or contain only
 other directories that have been also selected to be removed by the filesets
 patterns, otherwise a BuildException will be thrown.
-Also, if you don't have permission to remove a directory, a BuildException is 
+Also, if you don't have permission to remove a directory, a BuildException is
 thrown.
 
 <pre>
@@ -700,25 +667,22 @@
 already removed.
 Obviously all the files in the tree must have been already deleted.
 </p>
-<p>As an example suppose you want to delete everything contained into 
+<p>As an example suppose you want to delete everything contained into
 <code>/somedir</code>, so invoke first the <code>&lt;ftp&gt;</code> task with
 <code>action="delete"</code>, then with
 <code>action="rmdir"</code> specifying in both cases
-<code>remotedir="/somedir"</code> and
-
+<code>remotedir="/somedir"</code> and</p>
 <pre>
     &lt;fileset&gt;
         &lt;include name="**"/&gt;
     &lt;/fileset&gt;
 </pre>
-
+<p>
 The directory specified in the <code>remotedir</code> parameter is never
 selected for remove, so if you need to remove it, specify its parent in
-<code>remotedir</code> parameter and include it in the 
+<code>remotedir</code> parameter and include it in the
 <code>&lt;fileset&gt;</code> pattern, like <code>"somedir/**"</code>.
 </p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/genkey.html b/manual/Tasks/genkey.html
index 96959c2..5010a20 100644
--- a/manual/Tasks/genkey.html
+++ b/manual/Tasks/genkey.html
@@ -24,12 +24,12 @@
 
 <body>
 
-<h2><a name="genkey">GenKey</a></h2>
+<h2 id="genkey">GenKey</h2>
 <h3>Description</h3>
-<p>Generates a key in a keystore. </p>
+<p>Generates a key in a keystore.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -99,11 +99,11 @@
 encoded properly and commas (&quot;<code>,</code>&quot;) are replaced
 with &quot;<code>\,</code>&quot;.</p>
 
-<p>The following two examples are identical: </p>
+<p>The following two examples are identical:</p>
 
 <h3>Examples</h3>
 <blockquote><pre>
-&lt;genkey alias=&quot;apache-group&quot; storepass=&quot;secret&quot; 
+&lt;genkey alias=&quot;apache-group&quot; storepass=&quot;secret&quot;
   dname=&quot;CN=Ant Group, OU=Jakarta Division, O=Apache.org, C=US&quot;/&gt;
 </pre></blockquote>
 
@@ -119,7 +119,5 @@
 &lt;/genkey&gt;</pre>
 </blockquote>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/get.html b/manual/Tasks/get.html
index a2c9b7e..1c332e2 100644
--- a/manual/Tasks/get.html
+++ b/manual/Tasks/get.html
@@ -24,22 +24,22 @@
 
 <body>
 
-<h2><a name="get">Get</a></h2>
+<h2 id="get">Get</h2>
 <h3>Description</h3>
 <p>Gets files from URLs.  When the verbose option is &quot;on&quot;, this task
 displays a '.' for every 100 Kb retrieved. Any URL schema supported by
-the runtime is valid here, including http:, ftp: and jar:; 
+the runtime is valid here, including http:, ftp: and jar:;
 </p>
 The <i>usetimestamp</i> option enables you to control downloads so that the remote file is
-only fetched if newer than the local copy. If there is no local copy, the download always takes 
-place. When a file is downloaded, the timestamp of the downloaded file is set to the remote timestamp. 
-NB: This timestamp facility only works on downloads using the HTTP protocol. 
+only fetched if newer than the local copy. If there is no local copy, the download always takes
+place. When a file is downloaded, the timestamp of the downloaded file is set to the remote timestamp.
+<strong>Note</strong>: This timestamp facility only works on downloads using the HTTP protocol.
 <p>
 A username and password can be specified, in which case basic 'slightly encoded
 plain text' authentication is used. This is only secure over an HTTPS link.
 </p>
 
-<p><b>Proxies</b>. Since Apache Ant 1.7.0, Ant running on Java1.5 or later can
+<p><b>Proxies</b>. <em>Since Apache Ant 1.7.0</em>, Ant running on Java 5 or later can
   <a href="../proxy.html">use the proxy settings of the operating
     system</a> if enabled with the
   <code>-autoproxy</code> option. There is also the
@@ -47,9 +47,9 @@
   for earlier Java versions. With proxies turned
   on, <code>&lt;get&gt;</code> requests against localhost may not work
   as expected, if the request is relayed to the proxy.</p>
- 
+
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -91,12 +91,12 @@
     <td valign="top">username</td>
     <td valign="top">username for 'BASIC' http authentication</td>
     <td align="center" valign="top">if password is set</td>
-  </tr>  
+  </tr>
   <tr>
     <td valign="top">password</td>
-    <td valign="top">password: required </td>
+    <td valign="top">password: required</td>
     <td align="center" valign="top">if username is set</td>
-  </tr>  
+  </tr>
   <tr>
     <td valign="top">maxtime</td>
     <td valign="top">Maximum time in seconds a single download may take,
@@ -104,7 +104,7 @@
       error.  <em>Since Ant 1.8.0</em></td>
     <td align="center" valign="top">No: default 0 which means no
       maximum time</td>
-  </tr>  
+  </tr>
   <tr>
     <td valign="top">retries</td>
     <td valign="top">The number of attempts to make for opening the URI.<br/>
@@ -124,16 +124,15 @@
     <td valign="top">httpusecaches</td>
     <td valign="top">HTTP only - if true, allow caching at the
       HttpUrlConnection level.  if false, turn caching off.<br/>
-      <b>Note</b> this is only a hint to the underlying UrlConnection
+      <strong>Note</strong> this is only a hint to the underlying UrlConnection
       class, implementations and proxies are free to ignore the
       setting.</td>
     <td align="center" valign="top">No; default "true"</td>
   </tr>
   <tr>
     <td valign="top">useragent</td>
-    <td valign="top">User-Agent HTTP header to send, starting with Ant
-      1.9.3 Ant will specify a User-Agent header of "Apache Ant VERSION"
-      unless overridden by this attribute<br/>
+    <td valign="top">User-Agent HTTP header to send,
+      defaults to "Apache Ant VERSION"<br/>
       <em>since Ant 1.9.3</em></td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -170,22 +169,44 @@
   name will be skipped.  If the returned name is a relative path, it
   will be considered relative to the <em>dest</em> attribute.</p>
 
+<h4>header</h4>
+<p>Any arbitrary number of HTTP headers can be added to a request.<br/>
+  The attributes of a nested <code>&lt;header/&gt;</code> node are as follows:</p>
+
+<table>
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">name</td>
+    <td valign="top">The name or key of this header. Cannot be null or empty. Leading and trailing spaces are removed</td>
+    <td align="center" valign="top">Yes</td>
+  </tr>
+  <tr>
+    <td valign="top">value</td>
+    <td valign="top">The value to assign to the header. Cannot be null or empty. Leading and trailing spaces are removed</td>
+    <td align="center" valign="top">Yes</td>
+  </tr>
+</table>
+
 <h3>Examples</h3>
 <pre>  &lt;get src=&quot;http://ant.apache.org/&quot; dest=&quot;help/index.html&quot;/&gt;</pre>
 <p>Gets the index page of http://ant.apache.org/, and stores it in the file <code>help/index.html</code>.</p>
 
-<pre>  &lt;get src=&quot;http://www.apache.org/dist/ant/KEYS&quot; 
-    dest=&quot;KEYS&quot; 
+<pre>  &lt;get src=&quot;http://www.apache.org/dist/ant/KEYS&quot;
+    dest=&quot;KEYS&quot;
     verbose=&quot;true&quot;
     usetimestamp=&quot;true&quot;/&gt;</pre>
 <p>
 Gets the PGP keys of Ant's (current and past) release managers, if the local copy
-is missing or out of date. Uses the verbose option 
+is missing or out of date. Uses the verbose option
 for progress information.
 </p>
 
-<pre>  &lt;get src=&quot;https://insecure-bank.org/statement/user=1214&quot; 
-    dest=&quot;statement.html&quot; 
+<pre>  &lt;get src=&quot;https://insecure-bank.org/statement/user=1214&quot;
+    dest=&quot;statement.html&quot;
     username="1214";
     password="secret"/&gt;</pre>
 <p>
@@ -230,13 +251,22 @@
 
 <pre>
 &lt;get dest=&quot;downloads&quot;&gt;
-  &lt;url url=&quot;http://ant.apache.org/index.html&quot;/&gt; 
+  &lt;url url=&quot;http://ant.apache.org/index.html&quot;/&gt;
   &lt;url url=&quot;http://ant.apache.org/faq.html&quot;/&gt;
 &lt;/get&gt;
 </pre>
+
+<p>With custom HTTP headers</p>
+<pre>
+&lt;get src=&quot;http://ant.apache.org/index.html&quot; dest=&quot;downloads&quot;&gt;
+  &lt;header name=&quot;header1&quot; value=&quot;headerValue1&quot; /&gt;
+  &lt;header name=&quot;header2&quot; value=&quot;headerValue2&quot; /&gt;
+  &lt;header name=&quot;header3&quot; value=&quot;headerValue3&quot; /&gt;
+&lt;/get&gt;
+</pre>
+
 <p>Gets the index and FAQ pages of http://ant.apache.org/, and stores
   them in the directory <code>downloads</code> which will be created if
   necessary.</p>
 </body>
 </html>
-
diff --git a/manual/Tasks/gunzip.html b/manual/Tasks/gunzip.html
index 32e2cf2..aaf364b 100644
--- a/manual/Tasks/gunzip.html
+++ b/manual/Tasks/gunzip.html
@@ -23,7 +23,6 @@
 </head>
 
 <body>
-This document's new home is <A HREF="unpack.html">here</A>
+This document's new home is <a href="unpack.html">here</a>
 </body>
 </html>
-
diff --git a/manual/Tasks/gzip.html b/manual/Tasks/gzip.html
index 6054d31..8e3d0dd 100644
--- a/manual/Tasks/gzip.html
+++ b/manual/Tasks/gzip.html
@@ -23,7 +23,6 @@
 </head>
 
 <body>
-This document's new home is <A HREF="pack.html">here</A>
+This document's new home is <a href="pack.html">here</a>
 </body>
 </html>
-
diff --git a/manual/Tasks/hostinfo.html b/manual/Tasks/hostinfo.html
index 851b403..8986ebd 100644
--- a/manual/Tasks/hostinfo.html
+++ b/manual/Tasks/hostinfo.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="hostinfo">HostInfo</a></h2>
+<h2 id="hostinfo">HostInfo</h2>
 
 <h3>Description</h3>
 <p>Sets the <code>NAME</code>, <code>DOMAIN</code>, <code>ADDR4</code>, and <code>ADDR6</code>
@@ -38,10 +38,10 @@
  If the host is not found, the domain will contain the domain as provided to the task,
  or <code>localdomain</code> if no host / domain was provided.<br/>
 The <code>ADDR4</code> contains the IPv4 address of the host with the widest meaning.<br/>
-If no IPv4 address is found and a host has been provided the address <code>0.0.0.0</code> 
+If no IPv4 address is found and a host has been provided the address <code>0.0.0.0</code>
 is returned, when no host was provided the address <code>127.0.0.1</code> is returned.<br/>
-The <code>ADDR6</code> contains the IPv6 address of the host with the widest meaning.<br/> 
-If no IPv6 address is found and a host has been provided the address <code>::</code> 
+The <code>ADDR6</code> contains the IPv6 address of the host with the widest meaning.<br/>
+If no IPv6 address is found and a host has been provided the address <code>::</code>
 is returned, when no host was provided the address <code>::1</code> is returned.<br/>
 </p>
 
@@ -51,7 +51,7 @@
 The best place for this task is probably in an initialization target.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -79,18 +79,18 @@
 </pre>
 
 <p>
-Sets the <code>NAME</code>, <code>DOMAIN</code>, <code>ADDR4</code>, and 
+Sets the <code>NAME</code>, <code>DOMAIN</code>, <code>ADDR4</code>, and
 <code>ADDR6</code> for the local host, using the most &quot;global&quot; address
 available.</p>
 <pre>
   &lt;hostinfo prefix=&quot;remotehost&quot; host=&quot;www.apache.org&quot;/&gt;
 </pre>
 <p>
-Sets the properties <code>remotehost.NAME</code> to <code>eos</code>, 
-<code>remotehost.DOMAIN</code> to <code>apache.org</code>, 
-<code>remotehost.ADDR4</code> to <code>140.211.11.130</code> and 
+Sets the properties <code>remotehost.NAME</code> to <code>eos</code>,
+<code>remotehost.DOMAIN</code> to <code>apache.org</code>,
+<code>remotehost.ADDR4</code> to <code>140.211.11.130</code> and
 <code>remotehost.ADDR6</code> to <code>::</code>
-for the host with the name www.apache.org (provided the canonical name and ip 
+for the host with the name www.apache.org (provided the canonical name and ip
 addresses do not change).
 </p>
 
diff --git a/manual/Tasks/image.html b/manual/Tasks/image.html
index 077b372..20459d0 100644
--- a/manual/Tasks/image.html
+++ b/manual/Tasks/image.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="image">Image</a></h2>
+<h2 id="image">Image</h2>
 <h3>Description</h3>
 <p>Applies a chain of image operations on a set of files.</p>
 <p>Requires <a href="../install.html#librarydependencies">Java Advanced Image API</a> from Sun.</p>
@@ -33,47 +33,47 @@
 <img src="image-classdiagram.gif" border="0" alt="Class-Diagram">
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
     <td align="center" valign="top"><b>Required</b></td>
   </tr>
   <tr>
-    <td valign="top"> failonerror </td>
-    <td valign="top"> Boolean value. If false, note errors to the output but keep going. </td>
-    <td align="center"> no (defaults to <i>true</i>) </td>
+    <td valign="top">failonerror</td>
+    <td valign="top">Boolean value. If false, note errors to the output but keep going.</td>
+    <td align="center">no (defaults to <i>true</i>)</td>
   </tr>
   <tr>
-    <td valign="top"> srcdir </td>
-    <td valign="top"> Directory containing the images. </td>
-    <td align="center"> yes, unless nested fileset is used </td>
+    <td valign="top">srcdir</td>
+    <td valign="top">Directory containing the images.</td>
+    <td align="center">yes, unless nested fileset is used</td>
   </tr>
   <tr>
-    <td valign="top"> encoding </td>
-    <td valign="top"> Image encoding type. <br>
+    <td valign="top">encoding</td>
+    <td valign="top">Image encoding type.<br>
       Valid (caseinsensitive) are: jpg, jpeg, tif, tiff
     </td>
-    <td align="center"> no (defaults to <i>JPEG</i>) </td>
+    <td align="center">no (defaults to <i>JPEG</i>)</td>
   </tr>
   <tr>
-    <td valign="top"> overwrite </td>
-    <td valign="top"> Boolean value. Sets whether or not to overwrite
+    <td valign="top">overwrite</td>
+    <td valign="top">Boolean value. Sets whether or not to overwrite
       a file if there is naming conflict.
     </td>
-    <td align="center"> no (defaults to <i>false</i>) </td>
+    <td align="center">no (defaults to <i>false</i>)</td>
   </tr>
   <tr>
-    <td valign="top"> gc </td>
-    <td valign="top"> Boolean value. Enables garbage collection after
+    <td valign="top">gc</td>
+    <td valign="top">Boolean value. Enables garbage collection after
       each image processed.
     </td>
-    <td align="center"> no (defaults to <i>false</i>) </td>
+    <td align="center">no (defaults to <i>false</i>)</td>
   </tr>
   <tr>
-    <td valign="top"> destdir </td>
-    <td valign="top"> Directory where the result images are stored. </td>
-    <td align="center"> no (defaults to value of <i>srcdir</i>) </td>
+    <td valign="top">destdir</td>
+    <td valign="top">Directory where the result images are stored.</td>
+    <td align="center">no (defaults to value of <i>srcdir</i>)</td>
   </tr>
   <!-- attributes inherited from MatchingTask -->
   <tr>
@@ -89,7 +89,7 @@
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
-    <td valign="top"> excludes</td>
+    <td valign="top">excludes</td>
     <td valign="top">comma- or space-separated list of patterns of files that must be
       excluded. No files (except default excludes) are excluded when omitted.</td>
     <td valign="top" align="center">No</td>
@@ -107,14 +107,14 @@
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
-    <td valign="top"> caseSensitive </td>
-    <td valign="top"> Boolean value. Sets case sensitivity of the file system. </td>
-    <td align="center"> no (defaults to <i>false</i>) </td>
+    <td valign="top">caseSensitive</td>
+    <td valign="top">Boolean value. Sets case sensitivity of the file system.</td>
+    <td align="center">no (defaults to <i>false</i>)</td>
   </tr>
   <tr>
-    <td valign="top"> followSymlinks </td>
-    <td valign="top"> Boolean value. Sets whether or not symbolic links should be followed. </td>
-    <td align="center"> no (defaults to <i>true</i>) </td>
+    <td valign="top">followSymlinks</td>
+    <td valign="top">Boolean value. Sets whether or not symbolic links should be followed.</td>
+    <td align="center">no (defaults to <i>true</i>)</td>
   </tr>
 </table>
 
@@ -133,48 +133,52 @@
 <h4>Rotate</h4>
 <p>Adds a Rotate ImageOperation to chain.</p>
 <h5>Parameters</h5>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
     <td align="center" valign="top"><b>Required</b></td>
   </tr>
   <tr>
-    <td valign="top"> angle </td>
-    <td valign="top"> Float value. Sets the angle of rotation in degrees. </td>
-    <td align="center"> no (defaults to <i>0.0F</i>) </td>
+    <td valign="top">angle</td>
+    <td valign="top">Float value. Sets the angle of rotation in degrees.</td>
+    <td align="center">no (defaults to <i>0.0F</i>)</td>
   </tr>
 </table>
 
 <h4>Scale</h4>
 <p>Adds a Scale ImageOperation to chain.</p>
 <h5>Parameters</h5>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
     <td align="center" valign="top"><b>Required</b></td>
   </tr>
-    <td valign="top"> proportions </td>
-    <td valign="top"> Sets which dimension to control proportions from. Valid values are:<ul>
+  <tr>
+    <td valign="top">proportions</td>
+    <td valign="top">Sets which dimension to control proportions from. Valid values are:
+      <ul>
         <li>&quot;ignore&quot; -  treat the dimensions independently.</li>
         <li>&quot;height&quot; - keep proportions based on the width.</li>
         <li>&quot;width&quot; - keep proportions based on the height.</li>
         <li>&quot;cover&quot; - keep proportions and fit in the supplied dimensions.</li>
         <li>&quot;fit&quot; - keep proportions and cover the supplied dimensions.</li>
-    </ul></td>
-    <td align="center"> no (defaults to <i>ignore</i>) </td>
-  <tr>
-    <td valign="top"> width </td>
-    <td valign="top"> Sets the width of the image, either as an integer or a %. </td>
-        <!-- todo: if integer, what kind? cm, px, inches, ... -->
-    <td align="center"> no (defaults to <i>100%</i>) </td>
+      </ul>
+    </td>
+    <td align="center">no (defaults to <i>ignore</i>)</td>
   </tr>
   <tr>
-    <td valign="top"> height </td>
-    <td valign="top"> Sets the height of the image, either as an integer or a %. </td>
+    <td valign="top">width</td>
+    <td valign="top">Sets the width of the image, either as an integer or a %.</td>
         <!-- todo: if integer, what kind? cm, px, inches, ... -->
-    <td align="center"> no (defaults to <i>100%</i>) </td>
+    <td align="center">no (defaults to <i>100%</i>)</td>
+  </tr>
+  <tr>
+    <td valign="top">height</td>
+    <td valign="top">Sets the height of the image, either as an integer or a %.</td>
+        <!-- todo: if integer, what kind? cm, px, inches, ... -->
+    <td align="center">no (defaults to <i>100%</i>)</td>
   </tr>
 </table>
 
@@ -182,21 +186,21 @@
 <p>Adds a Draw ImageOperation to chain. DrawOperation DataType objects can be
 nested inside the Draw object.</p>
 <h5>Parameters</h5>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
     <td align="center" valign="top"><b>Required</b></td>
   </tr>
   <tr>
-    <td valign="top"> xloc </td>
-    <td valign="top"> X-Position where to draw nested image elements. </td>
-    <td align="center"> no (defaults to <i>0</i>) </td>
+    <td valign="top">xloc</td>
+    <td valign="top">X-Position where to draw nested image elements.</td>
+    <td align="center">no (defaults to <i>0</i>)</td>
   </tr>
   <tr>
-    <td valign="top"> yloc </td>
-    <td valign="top"> Y-Position where to draw nested image elements. </td>
-    <td align="center"> no (defaults to <i>0</i>) </td>
+    <td valign="top">yloc</td>
+    <td valign="top">Y-Position where to draw nested image elements.</td>
+    <td align="center">no (defaults to <i>0</i>)</td>
   </tr>
 </table>
 
@@ -250,12 +254,5 @@
 <p>Same as above but stores the resulting file names will be prefixed
   by "scaled-".</p>
 
-<blockquote><pre>
-</pre></blockquote>
-
-
-
 </body>
 </html>
-
-
diff --git a/manual/Tasks/import.html b/manual/Tasks/import.html
index 4cf8de0..5744bf6 100644
--- a/manual/Tasks/import.html
+++ b/manual/Tasks/import.html
@@ -14,7 +14,6 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <html>
 <head>
   <meta http-equiv="Content-Language" content="en-us">
@@ -22,7 +21,7 @@
   <title>Import Task</title>
 </head>
 <body>
-  <h2><a name="import">Import</a></h2>
+  <h2 id="import">Import</h2>
   <h3>Description</h3>
   <p>
     Imports another build file into the current project.
@@ -36,7 +35,7 @@
   </p>
 
   <p>
-    <b>Note</b> as seen above, this task heavily relies on the ProjectHelper
+    <strong>Note</strong> as seen above, this task heavily relies on the ProjectHelper
     implementation and doesn't really perform any work of its own.  If
     you have configured Apache Ant to use a ProjectHelper other than Ant's
     default, this task may or may not work.
@@ -44,7 +43,7 @@
 
   <p>
     In the common use case where only Ant's default project helper is
-    used, it basically works like the 
+    used, it basically works like the
     <a href="http://ant.apache.org/faq.html#xml-entity-include">Entity
       Includes as explained in the Ant FAQ</a>, as if the imported file was
     contained in the importing file, minus the top <code>&lt;project&gt;</code>
@@ -57,12 +56,11 @@
   </p>
   <p>
 There are two further functional aspects that pertain to this task and
-that are not possible with entity includes:
+that are not possible with entity includes:</p>
 <ul>
   <li>target overriding</li>
   <li>special properties</li>
 </ul>
-  </p>
 <h4>Target overriding</h4>
 
 <p>If a target in the main file is also present in at least one of the
@@ -165,7 +163,7 @@
 </pre>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tbody>
     <tr>
       <td valign="top"><b>Attribute</b></td>
@@ -178,8 +176,8 @@
       </td>
       <td valign="top">
         The file to import. If this is a relative file name, the file name will be resolved
-        relative to the <i>importing</i> file. <b>Note</b>, this is unlike most other
-        ant file attributes, where relative files are resolved relative to ${basedir}.
+        relative to the <i>importing</i> file. <strong>Note</strong>: this is unlike most other
+        Ant file attributes, where relative files are resolved relative to ${basedir}.
       </td>
       <td valign="top" align="center">Yes or a nested resource collection</td>
     </tr>
diff --git a/manual/Tasks/include.html b/manual/Tasks/include.html
index e210923..3b9cdb7 100644
--- a/manual/Tasks/include.html
+++ b/manual/Tasks/include.html
@@ -14,7 +14,6 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <html>
 <head>
   <meta http-equiv="Content-Language" content="en-us">
@@ -22,7 +21,7 @@
   <title>Include Task</title>
 </head>
 <body>
-  <h2><a name="include">Include</a></h2>
+  <h2 id="include">Include</h2>
   <h3>Description</h3>
   <p>
     Include another build file into the current project.
@@ -31,7 +30,7 @@
   <p><em>since Apache Ant 1.8.0</em></p>
 
   <p>
-    <b>Note</b> this task heavily relies on the ProjectHelper
+    <strong>Note</strong> this task heavily relies on the ProjectHelper
     implementation and doesn't really perform any work of its own.  If
     you have configured Ant to use a ProjectHelper other than Ant's
     default, this task may or may not work.
@@ -53,12 +52,11 @@
   </p>
   <p>
 There are two further functional aspects that pertain to this task and
-that are not possible with entity includes:
+that are not possible with entity includes:</p>
 <ul>
   <li>target rewriting</li>
   <li>special properties</li>
 </ul>
-  </p>
 <h4>Target rewriting</h4>
 
 <p>Any target in the included file will be renamed
@@ -160,7 +158,7 @@
 </pre>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tbody>
     <tr>
       <td valign="top"><b>Attribute</b></td>
@@ -173,7 +171,7 @@
       </td>
       <td valign="top">
         The file to include. If this is a relative file name, the file name will be resolved
-        relative to the <i>including</i> file. <b>Note</b>, this is unlike most other
+        relative to the <i>including</i> file. <strong>Note</strong>, this is unlike most other
         ant file attributes, where relative files are resolved relative to ${basedir}.
       </td>
       <td valign="top" align="center">Yes or a nested resource collection</td>
diff --git a/manual/Tasks/input.html b/manual/Tasks/input.html
index b04affc..b40fc01 100644
--- a/manual/Tasks/input.html
+++ b/manual/Tasks/input.html
@@ -24,11 +24,11 @@
 
 <body>
 
-<h2><a name="input">Input</a></h2>
+<h2 id="input">Input</h2>
 <h3>Description</h3>
 
 <p>Allows user interaction during the build process by prompting for
-input.  To do so, it uses the configured 
+input.  To do so, it uses the configured
 <a href="../inputhandler.html">InputHandler</a>.</p>
 
 <p>The prompt can be set via the message attribute or as character
@@ -42,7 +42,7 @@
 user. This property can then be used during the following build
 run. Input behaves according to <a href="property.html">property
 task</a> which means that existing properties cannot be overridden.
-Since Apache Ant 1.6, <code>&lt;input&gt;</code> will not prompt for input if
+<em>Since Apache Ant 1.6</em>, <code>&lt;input&gt;</code> will not prompt for input if
 a property should be set by the task that has already been set in the
 project (and the task wouldn't have any effect).</p>
 
@@ -50,8 +50,8 @@
 characters to the console, this is a critical security defect, we must fix it
 immediately, etc, etc.  This problem was due to the lack in early versions of
 Java of a (fully functional) facility for handling secure console input.
-In Java 1.6 that shortcoming in Java's API was addressed and Ant versions 1.7.1
-and 1.8 have added support for Java 1.6's secure console input feature
+In Java 6 that shortcoming in Java's API was addressed and Ant versions 1.7.1
+and 1.8 have added support for Java 6 secure console input feature
 (see <a href="#handler.type">handler type</a>).</p>
 
 <p>
@@ -60,7 +60,7 @@
 file and load in before the input task.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -99,19 +99,19 @@
 </table>
 <h3>Parameters Specified as Nested Elements</h3>
 <h4>Handler</h4>
-<p>Since <b>Ant 1.7</b>, a nested &lt;handler&gt; element can be used to
+<p><em>Since Ant 1.7</em>, a nested &lt;handler&gt; element can be used to
 specify an InputHandler, so that different InputHandlers may be used
-among different Input tasks.
+among different Input tasks.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
     <td align="center" valign="top"><b>Required</b></td>
   </tr>
-  <tr>
-    <td valign="top"><a name="handler.type" />type</td>
-    <td valign="top">one of "default","propertyfile", "greedy", or "secure" (since Ant 1.8).
+  <tr id="handler.type">
+    <td valign="top">type</td>
+    <td valign="top">one of "default","propertyfile", "greedy", or "secure" (<em>since Ant 1.8</em>).
     </td>
     <td align="center" valign="top" rowspan="3">One of these</td>
   </tr>
@@ -142,7 +142,7 @@
     <td valign="top">No</td>
   </tr>
 </table>
-<br />
+<p>
 The classpath can also be specified by means of one or more nested
 &lt;classpath&gt; elements.</p>
 
@@ -157,8 +157,7 @@
 continue...&quot; and pause the build run until return key is pressed
 (again, the concrete behavior is implementation dependent).</p>
 <pre>  &lt;input
-    message=&quot;Press Return key to continue...&quot;
-  /&gt;</pre>
+    message=&quot;Press Return key to continue...&quot;/&gt;</pre>
 <p>Will display the message &quot;Press Return key to
 continue...&quot; and pause the build run until return key is pressed
 (see above).</p>
@@ -166,8 +165,7 @@
   &lt;input
     message=&quot;All data is going to be deleted from DB continue (y/n)?&quot;
     validargs=&quot;y,n&quot;
-    addproperty=&quot;do.delete&quot;
-  /&gt;
+    addproperty=&quot;do.delete&quot;/&gt;
   &lt;condition property=&quot;do.abort&quot;&gt;
     &lt;equals arg1=&quot;n&quot; arg2=&quot;${do.delete}&quot;/&gt;
   &lt;/condition&gt;
@@ -179,20 +177,17 @@
 user.&quot;.</p>
 <pre>  &lt;input
     message=&quot;Please enter db-username:&quot;
-    addproperty=&quot;db.user&quot;
-  /&gt;</pre>
+    addproperty=&quot;db.user&quot;/&gt;</pre>
 <p>Will display the message &quot;Please enter db-username:&quot; and set the
 property <code>db.user</code> to the value entered by the user.</p>
 
 <pre>  &lt;input
     message=&quot;Please enter db-username:&quot;
     addproperty=&quot;db.user&quot;
-    defaultvalue=&quot;Scott-Tiger&quot;
-  /&gt;</pre>
+    defaultvalue=&quot;Scott-Tiger&quot;/&gt;</pre>
 <p>Same as above, but will set <code>db.user</code> to the value
 <i>Scott- Tiger</i> if the user enters no value (simply types
 &lt;return&gt;).</p>
 
-
 </body>
 </html>
diff --git a/manual/Tasks/jar.html b/manual/Tasks/jar.html
index 1df2ee0..321a586 100644
--- a/manual/Tasks/jar.html
+++ b/manual/Tasks/jar.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="jar">Jar</a></h2>
+<h2 id="jar">Jar</h2>
 <h3>Description</h3>
 <p>Jars a set of files.</p>
 <p>The <i>basedir</i> attribute is the reference directory from where to jar.</p>
@@ -90,8 +90,13 @@
 
 <p>To cryptographically sign your JAR file, use the <a href="signjar.html">SignJar task</a> on the JAR that you create from this task.</p>
 
+<p>For creating a simple version of a <a target="_blank" href="http://openjdk.java.net/jeps/238">JEP 238 multi-release jar</a>,
+you don't need any special tools. Just set the required manifest entry and place the files where required, as you could see
+in the <a href="#jep238-example">JEP 238 example</a>. If you want to tune this kind of jar, e.g. decreasing the size by deleting
+'same' classes from the versions-branches, you have to do more ...</p>
+
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -120,7 +125,7 @@
     <td valign="top">For entries coming from existing archives (like
     nested <em>zipfileset</em>s or while updating the archive), keep
     the compression as it has been originally instead of using the
-    <em>compress</em> attribute.  Defaults false.  <em>Since Ant
+    <em>compress</em> attribute.  Defaults to false.  <em>Since Ant
     1.6</em></td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -198,9 +203,9 @@
   </tr>
   <tr>
     <td valign="top">index</td>
-    <td valign="top">whether to create an <A
-    HREF="http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#JAR_Index">index
-    list</A> to speed up classloading.  This is a JDK 1.3+ specific
+    <td valign="top">whether to create an <a
+    href="http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#JAR_Index">index
+    list</a> to speed up classloading.  This is a JDK 1.3+ specific
     feature.  Unless you specify additional jars with nested <a
     href="#indexjars"><code>indexjars</code></a> elements, only the
     contents of this jar will be included in the index.  Defaults to
@@ -217,8 +222,8 @@
       <a href="https://bugs.openjdk.java.net/browse/JDK-4408526">Java
       5</a>.  In order to avoid problems with Ant generated jars on
       Java 1.4 or earlier Ant will not include META-INF unless
-      explicitly asked to.<br/>
-      <em>Ant 1.8.0</em> - Defaults to false.</td>
+      explicitly asked to.  Defaults to false.<br/>
+      <em>Since Ant 1.8.0</em></td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -258,7 +263,7 @@
     <li><b>ignore</b> = logs a message on verbose level (default)</li>
     </ul>
     <em>Since Ant 1.7.1</em></td>
-    <td valign="top" align="center">No, defaults to <tt>ignore</tt>. </td>
+    <td valign="top" align="center">No, defaults to <tt>ignore</tt>.</td>
   </tr>
   <tr>
     <td valign="top">preserve0permissions</td>
@@ -268,7 +273,7 @@
     that the permissions haven't been stored at all rather than real
     permissions and will instead apply its own default values.<br/>
     Set this attribute to true if you really want to preserve the
-      original permission field.<em>since Ant 1.8.0</em>
+      original permission field. <em>since Ant 1.8.0</em>
     </td>
     <td valign="top" align="center">No, default is false</td>
   </tr>
@@ -360,9 +365,9 @@
 appropriate.
 </p>
 
-<a name="indexjars"><h4>indexjars</h4></a>
+<h4 id="indexjars">indexjars</h4>
 
-<p><em>since ant 1.6.2</em></p>
+<p><em>since Ant 1.6.2</em></p>
 
 <p>The nested <code>indexjars</code> element specifies a <a
 href="../using.html#path">PATH like structure</a>.  Its content is
@@ -388,9 +393,9 @@
   the <code>indexmetainf</code> attribute has been set
   to <code>true</code>.</p>
 
-<a name="service"><h4>service</h4></a>
+<h4 id="service">service</h4>
 
-<p><em>since ant 1.7.0</em></p>
+<p><em>since Ant 1.7.0</em></p>
 
 <p>
   The nested <code>service</code> element specifies a service.
@@ -408,7 +413,7 @@
   "provider" nested elements.
 </p>
 <p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -434,8 +439,8 @@
     If a JAR file has more that one implementation of the service, a number of
     nested &lt;provider&gt; elements may be used.
   </p>
-  
-  
+
+
 <h3>Examples</h3>
 
 <h4>Simple</h4>
@@ -448,8 +453,7 @@
 
 <blockquote><pre>  &lt;jar destfile=&quot;${dist}/lib/app.jar&quot;
        basedir=&quot;${build}/classes&quot;
-       excludes=&quot;**/Test.class&quot;
-  /&gt;</pre></blockquote>
+       excludes=&quot;**/Test.class&quot;/&gt;</pre></blockquote>
 <p>jars all files in the <code>${build}/classes</code> directory into a file
 called <code>app.jar</code> in the <code>${dist}/lib</code> directory. Files
 with the name <code>Test.class</code> are excluded.</p>
@@ -457,8 +461,7 @@
 <blockquote><pre>  &lt;jar destfile=&quot;${dist}/lib/app.jar&quot;
        basedir=&quot;${build}/classes&quot;
        includes=&quot;mypackage/test/**&quot;
-       excludes=&quot;**/Test.class&quot;
-  /&gt;</pre></blockquote>
+       excludes=&quot;**/Test.class&quot;/&gt;</pre></blockquote>
 <p>jars all files in the <code>${build}/classes</code> directory into a file
 called <code>app.jar</code> in the <code>${dist}/lib</code> directory. Only
 files under the directory <code>mypackage/test</code> are used, and files with
@@ -467,8 +470,7 @@
 <h4>Multiple filesets</h4>
 <blockquote><pre>  &lt;jar destfile=&quot;${dist}/lib/app.jar&quot;&gt;
     &lt;fileset dir=&quot;${build}/classes&quot;
-             excludes=&quot;**/Test.class&quot;
-    /&gt;
+             excludes=&quot;**/Test.class&quot;/&gt;
     &lt;fileset dir=&quot;${src}/resources&quot;/&gt;
   &lt;/jar&gt;</pre></blockquote>
 <p>jars all files in the <code>${build}/classes</code> directory and also
@@ -537,7 +539,7 @@
   &lt;/jar&gt;</pre></blockquote>
 <p>
 This is an example of an inline manifest specification including the version of the build
-program (Implementation-Version). Note that the Built-By attribute will take the value of the Ant 
+program (Implementation-Version). Note that the Built-By attribute will take the value of the Ant
 property ${user.name}. The manifest produced by the above would look like this:
 </p>
 
@@ -557,7 +559,7 @@
 
 <p>
   The following shows how to create a jar file specifying a service
-  with an implementation of the JDK6 scripting interface:
+  with an implementation of the JDK 6 scripting interface:
 </p>
 <blockquote><pre>&lt;jar destfile="pinky.jar"&gt;
   &lt;fileset dir="build/classes"/&gt;
@@ -569,8 +571,8 @@
 
 
 <p>
-  The following shows how to create a jar file specifing a service
-  with two implementations of the JDK6 scripting interface:
+  The following shows how to create a jar file specifying a service
+  with two implementations of the JDK 6 scripting interface:
 </p>
 <blockquote><pre>
 &lt;jar destfile="pinkyandbrain.jar"&gt;
@@ -583,6 +585,35 @@
 </pre></blockquote>
 
 
+<h4 id="jep238-example">JEP 238 example: a Multi-Release JAR Files</h4>
+<p>
+  Here we want to create a <i>Multi-Release JAR File</i> according the specification
+  <a target="_blank" href="http://openjdk.java.net/jeps/238">JEP 238</a>.
+  It defines on top of a JAR the possibility to place additional or overwriting classes
+  in a jar, which are available according to the Java version you run.<br>
+  Basically it says, that you have to set the manifest entry <tt>Multi-Release: true</tt>
+  and place all additional or overwriting classes in
+  <tt>META-INF/versions/<i>number</i>/package-structure</tt>, e.g.
+  <tt>META-INF/versions/9/org/apache/ant/MyClass.class</tt>
+</p>
+<p>
+  In this example we expect that the normal classes are compiled into
+  <code>${java.classes}</code> and the Java 9 classes are compiled into
+  <code>${java9.classes}</code>.
+</p>
+<blockquote><pre>
+    &lt;jar destfile=&quot;mrjar.jar&quot;&gt;
+      &lt;manifest&gt;
+        &lt;!-- special mf-entry according to the spec --&gt;
+        &lt;attribute name=&quot;Multi-Release&quot; value=&quot;true&quot;/&gt;
+      &lt;/manifest&gt;
+      &lt;!-- directory structure according to the spec ... --&gt;
+      &lt;!-- ... default classes loadable by old (&lt;Java 9) versions --&gt;
+      &lt;fileset dir=&quot;${java.classes}&quot;/&gt;
+      &lt;!-- ... per release classes, require Java 9+ for loadable via standard ClassLoader --&gt;
+      &lt;zipfileset prefix=&quot;META-INF/versions/9/&quot; dir=&quot;${java9.classes}&quot;/&gt;
+    &lt;/jar&gt;
+</pre></blockquote>
 
 </body>
 </html>
diff --git a/manual/Tasks/jarlib-available.html b/manual/Tasks/jarlib-available.html
index adb732f..c240887 100644
--- a/manual/Tasks/jarlib-available.html
+++ b/manual/Tasks/jarlib-available.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="jarlib-available">jarlib-available</a></h2>
+<h2 id="jarlib-available">jarlib-available</h2>
 <h3>Description</h3>
 <p>Check whether an extension is present in a fileset or an extensionSet.
 If the extension is present then a property is set.</p>
@@ -39,7 +39,7 @@
 Extension and ExtensionSet documentation</a> for further details</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -53,8 +53,8 @@
   <tr>
     <td valign="top">file</td>
     <td valign="top">The file to check for extension</td>
-    <td valign="top" align="center">No, one of file, nested
-    ExtensionSet or nested fileset must be present.</td>
+    <td valign="top" align="center">Yes, unless a nested
+    extensionSet or fileset is specified</td>
   </tr>
 </table>
 <h3>Parameters specified as nested elements</h3>
@@ -127,8 +127,5 @@
   &lt;/jarlib-available&gt;
 </pre>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/jarlib-display.html b/manual/Tasks/jarlib-display.html
index 0ddbaa3..7f4b81e 100644
--- a/manual/Tasks/jarlib-display.html
+++ b/manual/Tasks/jarlib-display.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="jarlib-display">jarlib-display</a></h2>
+<h2 id="jarlib-display">jarlib-display</h2>
 <h3>Description</h3>
 <p>Display the "Optional Package" and "Package Specification" information
  contained within the specified jars.</p>
@@ -39,7 +39,7 @@
 Extension and ExtensionSet documentation</a> for further details</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -48,15 +48,14 @@
   <tr>
     <td valign="top">file</td>
     <td valign="top">The file to display extension information about.</td>
-    <td valign="top" align="center">No, but one of file or fileset must be
-    present.</td>
+    <td valign="top" align="center">Yes, unless a nested fileset is specified</td>
   </tr>
 </table>
 <h3>Parameters specified as nested elements</h3>
 
 <h4>fileset</h4>
  <p><a href="../Types/fileset.html">FileSet</a>s contain list of files to
- display Extension information  about.</p>
+ display Extension information about.</p>
 
 <h3>Examples</h3>
 <p><b>Display Extension info for a single file</b></p>
@@ -73,8 +72,5 @@
   &lt;/jarlib-display&gt;
 </pre>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/jarlib-manifest.html b/manual/Tasks/jarlib-manifest.html
index 019b554..e2f5bda 100644
--- a/manual/Tasks/jarlib-manifest.html
+++ b/manual/Tasks/jarlib-manifest.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="jarlib-manifest">jarlib-manifest</a></h2>
+<h2 id="jarlib-manifest">jarlib-manifest</h2>
 <h3>Description</h3>
 <p>Task to generate a manifest that declares all the dependencies
  in manifest. The dependencies are determined by looking in the
@@ -41,7 +41,7 @@
 Extension and ExtensionSet documentation</a> for further details</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -116,8 +116,5 @@
 &lt;/jarlib-manifest&gt;
 </pre>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/jarlib-resolve.html b/manual/Tasks/jarlib-resolve.html
index 2ef4f87..2bb2e78 100644
--- a/manual/Tasks/jarlib-resolve.html
+++ b/manual/Tasks/jarlib-resolve.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="jarlib-resolve">jarlib-resolve</a></h2>
+<h2 id="jarlib-resolve">jarlib-resolve</h2>
 <h3>Description</h3>
 <p>Try to locate a jar to satisfy an extension and place
  location of jar into property. The task allows you to
@@ -38,13 +38,13 @@
 works with extensions as defined by the "Optional Package" specification.
  For more information about optional packages, see the document
 <em>Optional Package Versioning</em> in the documentation bundle for your
-Java2 Standard Edition package, in file
+Java Standard Edition package, in file
 <code>guide/extensions/versioning.html</code> or the online
 <a target="_blank" href="http://docs.oracle.com/javase/7/docs/technotes/guides/extensions/versioning.html">
 Extension and ExtensionSet documentation</a> for further details</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -76,7 +76,7 @@
 <h4>location</h4>
  <p>The location sub element allows you to look for a library in a
  location relative to project directory.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -92,7 +92,7 @@
 <h4>url</h4>
  <p>The url resolver allows you to download a library from a URL to a
  local file.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -106,20 +106,17 @@
   <tr>
     <td valign="top">destfile</td>
     <td valign="top">The file to download URL into.</td>
-    <td valign="top" align="center">No, But one of destfile or
-    destdir must be present</td>
+    <td valign="top" align="center" rowspan="2">Exactly one of the two</td>
   </tr>
   <tr>
     <td valign="top">destdir</td>
     <td valign="top">The directory in which to place downloaded file.</td>
-    <td valign="top" align="center">No, But one of destfile or
-    destdir must be present</td>
   </tr>
 </table>
 
 <h4>ant</h4>
  <p>The ant resolver allows you to run an Apache Ant build file to generate a library.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -204,8 +201,5 @@
   &lt;/jarlib-resolve&gt;
 </pre>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/java.html b/manual/Tasks/java.html
index 36d50ce..ee49be1 100644
--- a/manual/Tasks/java.html
+++ b/manual/Tasks/java.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="java">Java</a></h2>
+<h2 id="java">Java</h2>
 <h3>Description</h3>
 <p>Executes a Java class within the running (Apache Ant) VM or forks another VM if
 specified.</p>
@@ -36,8 +36,7 @@
 sending input to it via the <code>input</code> and <code>inputstring</code>
 attributes.</p>
 
-<h4><a name="background">Running Ant as a background process on
-    Unix(-like) systems</a></h4>
+<h4 id="background">Running Ant as a background process on Unix(-like) systems</h4>
 
 <p>If you run Ant as a background process (like <code>ant &</code>)
   and use the <code>&lt;java&gt;</code> task with <code>spawn</code>
@@ -47,14 +46,14 @@
   standard input.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
     <td align="center" valign="top"><b>Required</b></td>
   </tr>
-  <tr>
-    <td valign="top"><a name="classname">classname</a></td>
+  <tr id="classname">
+    <td valign="top">classname</td>
     <td valign="top">the Java class to execute.</td>
     <td align="center" valign="top">Either <tt>jar</tt>, <tt>classname</tt> or <tt>module</tt></td>
   </tr>
@@ -92,7 +91,7 @@
   </tr>
   <tr>
     <td valign="top">spawn</td>
-    <td valign="top">if enabled allows to start a process which will outlive ant.<br>
+    <td valign="top">if enabled allows to start a process which will outlive Ant.<br>
     Requires fork=true, and not compatible
     with timeout, input, output, error, result attributes.<br>
       (disabled by default)</td>
@@ -123,12 +122,12 @@
     <td valign="top">module</td>
     <td valign="top">The initial or main module to resolve. To specify
     the module main class use the <a href="#classname">classname</a> attribute.
-    Fork must be set to true if this option is selected.<em>since Ant 1.9.7</em></td>
+    Fork must be set to true if this option is selected. <em>since Ant 1.9.7</em></td>
     <td align="center" valign="top">Either <tt>jar</tt>, <tt>classname</tt> or <tt>module</tt></td>
   </tr>
   <tr>
     <td valign="top">modulepath</td>
-    <td valign="top">Specify where to find application modules. A list of directories of modules, module files or exploded modules.<em>since Ant 1.9.7</em></td>
+    <td valign="top">Specify where to find application modules. A list of directories of modules, module files or exploded modules. <em>since Ant 1.9.7</em></td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
@@ -166,7 +165,7 @@
   <tr>
     <td valign="top">error</td>
     <td valign="top">The file to which the standard error of the command should be
-      redirected. </td>
+      redirected.</td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
@@ -284,10 +283,10 @@
 <p>When the permission RuntimePermission exitVM has not been granted (or has
 been revoked) the System.exit() call will be intercepted
 and treated like indicated in <i>failonerror</i>.</p>
-<p>Note:<br>
+<p><strong>Note</strong>:<br>
 If you do not specify permissions,
 a set of default permissions will be added to your Java invocation to make
-sure that the ant run will continue or terminated as indicated by
+sure that the Ant run will continue or terminated as indicated by
 <i>failonerror</i>. All permissions not granted per default will be
 checked by whatever security manager was already in place. exitVM will be
 disallowed.
@@ -304,22 +303,22 @@
 
 <p>Assertion statements are currently ignored in non-forked mode.</p>
 
-<p><em>since Ant 1.6.</em></p>
+<p><em>since Ant 1.6</em>.</p>
 
-<a name="redirector"><h4>redirector</h4></a>
-<i><b>Since Ant 1.6.2</b></i>
+<h4 id="redirector">redirector</h4>
+<em>Since Ant 1.6.2</em>
 <p>A nested <a href="../Types/redirector.html">I/O Redirector</a>
 can be specified.  In general, the attributes of the redirector behave
 as the corresponding attributes available at the task level.  The most
 notable peculiarity stems from the retention of the <code>&lt;java&gt;</code>
 attributes for backwards compatibility.  Any file mapping is done
-using a <CODE>null</CODE> sourcefile; therefore not all
+using a <code>null</code> sourcefile; therefore not all
 <a href="../Types/mapper.html">Mapper</a> types will return
 results.  When no results are returned, redirection specifications
 will fall back to the task level attributes.  In practice this means that
 defaults can be specified for input, output, and error output files.
 </p>
-<a name="failonerror"><h3>Errors and return codes</h3></a>
+<h3 id="failonerror">Errors and return codes</h3>
 By default the return code of a <code>&lt;java&gt;</code> is ignored.
 Alternatively, you can set <code>resultproperty</code> to the name
 of a property and have it assigned to the result code (barring immutability,
@@ -327,22 +326,21 @@
 When you set <code>failonerror="true"</code>, the only possible value for
 <code>resultproperty</code> is 0. Any non-zero response is treated as an
 error and would mean the build exits.
-<p> Similarly, if <code>failonerror="false"</code> and <code>fork="false"</code>
-, then <code>&lt;java&gt;</code> <b>must</b> return 0 otherwise the build will
+<p>Similarly, if <code>failonerror="false"</code> and <code>fork="false"</code>,
+then <code>&lt;java&gt;</code> <b>must</b> return 0 otherwise the build will
 exit, as the class was run by the build JVM.</p>
 
-<a name="modulepath"><h4>modulepath</h4>
-<i><b>Since Ant 1.9.7</b></i>
+<h4 id="modulepath">modulepath</h4>
+<em>Since Ant 1.9.7</em>
 <p><code>Java</code>'s <i>modulepath</i> attribute is a <a
 href="../using.html#path">PATH like structure</a> and can also be set via a nested
 <i>modulepath</i> element.</p>
 
-<a name="upgrademodulepath"><h4>upgrademodulepath</h4>
-<i><b>Since Ant 1.9.7</b></i>
+<h4 id="upgrademodulepath">upgrademodulepath</h4>
+<em>Since Ant 1.9.7</em>
 <p>The location of modules that replace upgradeable modules in the runtime image
 can be specified using this <a href="../using.html#path">PATH like structure</a>.</p>
 
-
 <h3>JAR file execution</h3>
 
 <p>The parameter of the <tt>jar</tt> attribute is of type <tt>File</tt>;
@@ -351,9 +349,9 @@
 task is run. If you need to locate a JAR file relative to the directory
 the task will be run in, you need to explicitly create the full path
 to the JAR file.</p>
-<p>When using the <tt>jar</tt> attribute, all classpath settings are 
+<p>When using the <tt>jar</tt> attribute, all classpath settings are
 ignored according to <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html">Oracle's
-specification</a>. 
+specification</a>.
 
 
 <h3>Examples</h3>
diff --git a/manual/Tasks/javac.html b/manual/Tasks/javac.html
index 89ec054..70f6932 100644
--- a/manual/Tasks/javac.html
+++ b/manual/Tasks/javac.html
@@ -14,7 +14,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<html lang="en-us">
+<html>
 
 <head>
 <meta http-equiv="Content-Language" content="en-us">
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="javac">Javac</a></h2>
+<h2 id="javac">Javac</h2>
 <h3>Description</h3>
 <p>Compiles a Java source tree.</p>
 <p>The source and destination directory will be recursively scanned for Java
@@ -32,7 +32,7 @@
 <code>.class</code> file
 or where the class file is older than the
 <code>.java</code> file will be compiled.</p>
-<p>Note: Apache Ant uses only the names of the source and class files to find
+<p><strong>Note</strong>: Apache Ant uses only the names of the source and class files to find
 the classes that need a rebuild. It will not scan the source and therefore
 will have no knowledge about nested classes, classes that are named different
 from the source file, and so on. See the
@@ -57,7 +57,7 @@
 <a href="../dirtasks.html#directorybasedtasks">directory-based tasks</a>,
 for information on how the
 inclusion/exclusion of files works, and how to write wildcard patterns.</p>
-<p>It is possible to use different compilers. This can be specified by
+<p id="compilervalues">It is possible to use different compilers. This can be specified by
 either setting the global <code>build.compiler</code> property, which will
 affect all <code>&lt;javac&gt;</code> tasks throughout the build, by
 setting the <code>compiler</code> attribute, specific to the current
@@ -65,9 +65,9 @@
 <a href="typedef.html">typedef</a>fed or
 <a href="componentdef.html">componentdef</a>fed type that implements
 <code>org.apache.tools.ant.taskdefs.compilers.CompilerAdapter</code>.
-<a name="compilervalues">Valid values for either the
+Valid values for either the
 <code>build.compiler</code> property or the <code>compiler</code>
-attribute are:</a></p>
+attribute are:</p>
 <ul>
   <li><code>classic</code> (the standard compiler of JDK 1.1/1.2) &ndash;
       <code>javac1.1</code> and
@@ -81,7 +81,7 @@
       <code>javac1.8</code> (<em>since Ant 1.8.3</em>) and
       <code>javac1.9</code> (<em>since Ant 1.9.5</em>) and
       <code>javac9</code> (<em>since Ant 1.9.8</em>) and
-      <code>javac10+</code> (<em>since Ant 1.9.10</em>) can be used as aliases.</li>
+      <code>javac10+</code> (<em>since Ant 1.10.2</em>) can be used as aliases.</li>
   <li><code>jikes</code> (the <a
     href="http://jikes.sourceforge.net/" target="_top">Jikes</a>
     compiler).</li>
@@ -106,7 +106,7 @@
 </p>
 <p>The fork attribute overrides the <code>build.compiler</code> property
 or <code>compiler</code> attribute setting and
-expects a JDK1.1 or higher to be set in <code>JAVA_HOME</code>.
+expects a JDK 1.1 or higher to be set in <code>JAVA_HOME</code>.
 </p>
 <p>You can also use the <code>compiler</code> attribute to tell Ant
 which JDK version it shall assume when it puts together the command
@@ -120,7 +120,7 @@
 files/directories from the classpath it passes to the compiler.</p>
 <p>The working directory for a forked executable (if any) is the
   project's base directory.</p>
-<p><strong>Windows Note:</strong>When the modern compiler is used
+<p><strong>Windows Note</strong>: When the modern compiler is used
 in unforked mode on Windows, it locks up the files present in the
 classpath of the <code>&lt;javac&gt;</code> task, and does not release them.
 The side effect of this is that you will not be able to delete or move
@@ -136,7 +136,7 @@
   corresponding <code>.java</code> file the file will not get compiled
   even if a native header file generated for it would be outdated.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -224,7 +224,7 @@
   </tr>
   <tr>
     <td valign="top">encoding</td>
-    <td valign="top">Encoding of source files. (Note: gcj doesn't support
+    <td valign="top">Encoding of source files. (<strong>Note</strong>: gcj doesn't support
       this option yet.)</td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -265,8 +265,8 @@
     <td valign="top">
       Indicates whether source should be compiled with
       optimization; defaults to <code>off</code>. <strong>Note</strong>
-      that this flag is just ignored by Sun's <code>javac</code> starting
-      with JDK 1.3 (since compile-time optimization is unnecessary).
+      that this flag is just ignored by Sun's <code>javac</code> since
+      JDK 1.3 (because compile-time optimization is unnecessary).
     </td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -282,7 +282,7 @@
     (e.g., <code>1.1</code> or <code>1.2</code>). <b>Note that the
     default value depends on the JVM that is running Ant.  In
     particular, if you use JDK 1.4+ the generated classes will not be
-    usable for a 1.1 Java VM unless you explicitly set this attribute
+    usable for a Java 1.1 VM unless you explicitly set this attribute
     to the value 1.1 (which is the default value for JDK 1.1 to
     1.3).  We highly recommend to always specify this
     attribute.</b><br>
@@ -299,7 +299,8 @@
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
-    <td valign="top">depend</td> <td valign="top">Enables dependency-tracking
+    <td valign="top">depend</td>
+    <td valign="top">Enables dependency-tracking
       for compilers that support this (<code>jikes</code> and
       <code>classic</code>).</td>
     <td align="center" valign="top">No</td>
@@ -318,7 +319,7 @@
     <td valign="top">Whether to include the default run-time
       libraries from the executing VM in the classpath;
       defaults to <code>no</code>.<br/>
-      <b>Note:</b> In some setups the run-time libraries may be part
+      <strong>Note</strong>: In some setups the run-time libraries may be part
       of the "Ant run-time libraries" so you may need to explicitly
       set includeAntRuntime to false to ensure that the Java
       run-time libraries are not included.</td>
@@ -336,7 +337,7 @@
       executable to use in case of <code>fork=&quot;yes&quot;</code>.
       Defaults to the compiler of the Java version that is currently
       running Ant.  Ignored if <code>fork=&quot;no&quot;</code>.<br>
-      Since Ant 1.6 this attribute can also be used to specify the
+      <em>Since Ant 1.6</em> this attribute can also be used to specify the
       path to the executable when using jikes, jvc, gcj or sj.</td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -424,7 +425,7 @@
   <tr>
     <td valign="top">updatedProperty</td>
     <td valign="top">
-      The property to set (to the value "true") 
+      The property to set (to the value "true")
       if compilation has taken place
       and has been successful.
       <em>Since Ant 1.7.1</em>.
@@ -460,8 +461,8 @@
       Some package level annotations in <code>package-info.java</code>
       files don't create any <code>package-info.class</code> files so
       Ant would recompile the same file every time.<br/>
-      Starting with Ant 1.8 Ant will create an
-      empty <code>package-info.class</code> for
+      <em>Since Ant 1.8</em>, an
+      empty <code>package-info.class</code> is created for
       each <code>package-info.java</code> if there isn't one created
       by the compiler.<br/>
       In some setups this additional class causes problems and it can
@@ -568,7 +569,7 @@
 Arguments</a> but have an additional attribute that can be used to
 enable arguments only if a given compiler implementation will be
 used.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -578,7 +579,7 @@
     <td valign="top">value</td>
     <td align="center" rowspan="4">See
     <a href="../using.html#arg">Command-line Arguments</a>.</td>
-    <td align="center" rowspan="4">Exactly one of these.</td>
+    <td align="center" rowspan="4">Exactly one of these</td>
   </tr>
   <tr>
     <td valign="top">line</td>
@@ -593,7 +594,7 @@
     <td valign="top">prefix</td>
     <td align="center" rowspan="2">See
     <a href="../using.html#arg">Command-line Arguments</a>.
-    <em>Since Ant 1.8.</em></td>
+    <em>Since Ant 1.8</em>.</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -611,7 +612,7 @@
   </tr>
 </table>
 
-<h4>compilerclasspath <em>since Ant 1.8.0</em></h4>
+<h4>compilerclasspath (<em>since Ant 1.8.0</em>)</h4>
 
 <p>A <a href="../using.html#path">PATH like structure</a> holding the
   classpath to use when loading the compiler implementation if a
@@ -619,7 +620,7 @@
   using one of the built-in compilers.</p>
 
 <h4>Any nested element of a type that implements CompilerAdapter
-  <em>since Ant 1.8.0</em></h4>
+  (<em>since Ant 1.8.0</em>)</h4>
 
 <p>If a defined type implements the <code>CompilerAdapter</code>
   interface a nested element of that type can be used as an
@@ -630,8 +631,7 @@
          destdir=&quot;${build}&quot;
          classpath=&quot;xyz.jar&quot;
          debug=&quot;on&quot;
-         source=&quot;1.4&quot;
-  /&gt;</pre>
+         source=&quot;1.4&quot;/&gt;</pre>
 <p>compiles all <code>.java</code> files under the <code>${src}</code>
 directory, and stores
 the <code>.class</code> files in the <code>${build}</code> directory.
@@ -643,8 +643,7 @@
          destdir=&quot;${build}&quot;
          fork=&quot;true&quot;
          source=&quot;1.2&quot;
-         target=&quot;1.2&quot;
-  /&gt;</pre>
+         target=&quot;1.2&quot;/&gt;</pre>
 <p>compiles all <code>.java</code> files under the <code>${src}</code>
 directory, and stores the <code>.class</code> files in the
 <code>${build}</code> directory.  This will fork off the javac
@@ -655,8 +654,7 @@
 <pre>  &lt;javac srcdir=&quot;${src}&quot;
          destdir=&quot;${build}&quot;
          fork=&quot;java$$javac.exe&quot;
-         source=&quot;1.5&quot;
-  /&gt;</pre>
+         source=&quot;1.5&quot;/&gt;</pre>
 <p>compiles all <code>.java</code> files under the <code>${src}</code>
 directory, and stores the <code>.class</code> files in the
 <code>${build}</code> directory.  This will fork off the javac
@@ -669,8 +667,7 @@
          includes=&quot;mypackage/p1/**,mypackage/p2/**&quot;
          excludes=&quot;mypackage/p1/testpackage/**&quot;
          classpath=&quot;xyz.jar&quot;
-         debug=&quot;on&quot;
-  /&gt;</pre>
+         debug=&quot;on&quot;/&gt;</pre>
 <p>compiles <code>.java</code> files under the <code>${src}</code>
 directory, and stores the
 <code>.class</code> files in the <code>${build}</code> directory.
@@ -686,8 +683,7 @@
          includes=&quot;mypackage/p1/**,mypackage/p2/**&quot;
          excludes=&quot;mypackage/p1/testpackage/**&quot;
          classpath=&quot;xyz.jar&quot;
-         debug=&quot;on&quot;
-  /&gt;</pre>
+         debug=&quot;on&quot;/&gt;</pre>
 
 <p>is the same as the previous example, with the addition of a second
 source path, defined by
@@ -715,10 +711,9 @@
          destdir=&quot;${build}&quot;
          fork=&quot;yes&quot;
          executable=&quot;/opt/java/jdk1.1/bin/javac&quot;
-         compiler=&quot;javac1.1&quot;
-  /&gt;</pre>
+         compiler=&quot;javac1.1&quot;/&gt;</pre>
 
-<p><a name="srcdirnote"><b>Note:</b></a>
+<p id="srcdirnote"><strong>Note</strong>:
 If you wish to compile only source files located in certain packages below a
 common root, use the <code>include</code>/<code>exclude</code> attributes
 or <code>&lt;include&gt;</code>/<code>&lt;exclude&gt;</code> nested elements
@@ -732,13 +727,13 @@
 <p>
 If you wish to compile only files explicitly specified and disable
 javac's default searching mechanism then you can unset the sourcepath
-attribute:
+attribute:</p>
 <pre>  &lt;javac sourcepath=&quot;&quot; srcdir=&quot;${src}&quot;
          destdir=&quot;${build}&quot; &gt;
     &lt;include name="**/*.java"/&gt;
     &lt;exclude name="**/Example.java"/&gt;
   &lt;/javac&gt;</pre>
-That way the javac will compile all java source files under &quot;${src}&quot;
+<p>That way the javac will compile all java source files under &quot;${src}&quot;
 directory but skip the examples. The compiler will even produce errors if some of
 the non-example files refers to them.
 </p>
@@ -746,29 +741,26 @@
 <p>
 If you wish to compile with a special JDK (another than the one Ant is currently using),
 set the <code>executable</code> and <code>fork</code> attribute. Using <code>taskname</code>
-could show in the log, that these settings are fix.
-<pre>  &lt;javac srcdir=&quot;&quot; 
+could show in the log, that these settings are fix.</p>
+<pre>  &lt;javac srcdir=&quot;&quot;
          destdir=&quot;&quot;
-         executable=&quot;path-to-java14-home/bin/javac&quot; 
+         executable=&quot;path-to-java14-home/bin/javac&quot;
          fork=&quot;true&quot;
-         taskname=&quot;javac1.4&quot; /&gt;</pre>
-</p>
+         taskname=&quot;javac1.4&quot;/&gt;</pre>
 
-
-<p><b>Note:</b> If you are using Ant on Windows and a new DOS window pops up
+<p><strong>Note</strong>: If you are using Ant on Windows and a new DOS window pops up
 for every use of an external compiler, this may be a problem of the JDK you are
 using.  This problem may occur with all JDKs &lt; 1.2.</p>
 
 
 <p>
 If you want to activate other compiler options like <i>lint</i> you could use
-the <tt>&lt;compilerarg&gt;</tt> element:
+the <tt>&lt;compilerarg&gt;</tt> element:</p>
 <pre>  &lt;javac srcdir="${src.dir}"
          destdir="${classes.dir}"
          classpathref="libraries"&gt;
     &lt;compilerarg value="-Xlint"/&gt;
-  &lt;/javac&gt; </pre>
-</p>  
+  &lt;/javac&gt;</pre>
 
 <p>If you want to use a custom
   CompilerAdapter <code>org.example.MyAdapter</code> you can either
@@ -776,8 +768,7 @@
 <pre>
 &lt;javac srcdir="${src.dir}"
        destdir="${classes.dir}"
-       compiler="org.example.MyAdapter"/&gt;
-</pre>
+       compiler="org.example.MyAdapter"/&gt;</pre>
 <p>or a define a type and nest this into the task like in:</p>
 <pre>
 &lt;componentdef classname="org.example.MyAdapter"
@@ -794,8 +785,7 @@
          destdir=&quot;${build}&quot;
          includeantruntime=&quot;false&quot;
          modulepath=&quot;modules&quot;
-         source=&quot;9&quot;
-  /&gt;</pre>
+         source=&quot;9&quot;/&gt;</pre>
 <p>compiles all <code>.java</code> files in a single module under the <code>${src}</code> directory,
   and stores the <code>.class</code> files in the <code>${build}</code> directory. The compilation uses
   application modules located in <code>modules</code> folder.The source level is <code>9</code> to enable modules.</p>
@@ -804,8 +794,7 @@
          destdir=&quot;${build}&quot;
          includeantruntime=&quot;false&quot;
          modulepath=&quot;modules&quot;
-         source=&quot;9&quot;
-  /&gt;</pre>
+         source=&quot;9&quot;/&gt;</pre>
 <p>compiles all <code>.java</code> files in <code>gen/classes</code>, <code>lin32/classes</code> and
   <code>lin64/classes</code> in all source modules under the <code>${src}</code> directory.
   Generates module directories in the <code>${build}</code> directory. Each generated module directory under
@@ -831,7 +820,7 @@
 <code>build.compiler.warnings</code> is <code>true</code>,
 while all others are <code>false</code>.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Property</b></td>
     <td valign="top"><b>Description</b></td>
@@ -893,13 +882,13 @@
 <code>build.compiler.jvc.extensions</code> to false before invoking
 <code>&lt;javac&gt;</code>.</p>
 
-<h3><a name="bootstrap">Bootstrap Options</h3>
+<h3 id="bootstrap">Bootstrap Options</h3>
 <p>
   The Sun javac compiler has a <em>bootclasspath</em> command
   line option - this corresponds to the "bootclasspath" attribute/element
   of the &lt;javac&gt; task. The Sun compiler also allows more
-  control over the boot classpath using the -X and -J-X attributes.
-  One can set these by using the &lt;compilerarg&gt;. Since Ant 1.6.0,
+  control over the boot classpath using the <code>-X</code> and <code>-J-X</code> attributes.
+  One can set these by using the &lt;compilerarg&gt;. <em>Since Ant 1.6.0</em>,
   there is a shortcut to convert path references to strings that
   can by used in an OS independent fashion (see
   <a href="../using.html#pathshortcut">pathshortcut</a>). For example:
@@ -913,9 +902,6 @@
   &lt;/javac&gt;
 </pre>
 
-  
-</p>
-
 <h3>OpenJDK Notes</h3>
 <p>
   The <a href="https://openjdk.dev.java.net/">openjdk</a>
@@ -945,10 +931,10 @@
 
   <h3>Note on package-info.java</h3>
   <p>
-    <code>package-info.java</code> files were introduced in Java5 to
+    <code>package-info.java</code> files were introduced in Java 5 to
     allow package level annotations. On compilation, if the java file
     does not contain runtime annotations, there will be no .class file
-    for the java file. Up to <b>Ant 1.7.1</b>, when the &lt;javac&gt;
+    for the java file. Prior to Ant 1.7.1, when the &lt;javac&gt;
     task is run again, the
     task will try to compile the package-info java files again.
   </p>
@@ -956,8 +942,8 @@
     involved the timestamp of the directory that would normally
     contain the .class file.  This logic turned out to lead to Ant not
     recompiling <code>package-info.java</code> in certain setup.</p>
-  <p>Starting with Ant 1.8.0 Ant will create
-    "empty" <code>package-info.class</code> files if it compiles
+<p><em>Since Ant 1.8.0</em>, an
+    "empty" <code>package-info.class</code> file is created if Ant compiles
     a <code>package-info.java</code> and
     no <code>package-info.class</code> file has been created by the
     compiler itself.</p>
diff --git a/manual/Tasks/javacc.html b/manual/Tasks/javacc.html
index 3c0dcfa..0dba9cd 100644
--- a/manual/Tasks/javacc.html
+++ b/manual/Tasks/javacc.html
@@ -24,10 +24,10 @@
 
 <body>
 
-<h2><a name="javacc">JavaCC</a></h2>
+<h2 id="javacc">JavaCC</h2>
 <h3>Description</h3>
 <p>
-  Invokes the <a HREF="http://javacc.dev.java.net/" target="_top">JavaCC</a> compiler
+  Invokes the <a href="http://javacc.dev.java.net/" target="_top">JavaCC</a> compiler
   compiler on a grammar file.
 </p>
 <p>
@@ -48,7 +48,7 @@
 </p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -194,8 +194,7 @@
     target=&quot;src/Parser.jj&quot;
     outputdirectory=&quot;build/src&quot;
     javacchome=&quot;c:/program files/JavaCC&quot;
-    static=&quot;true&quot;
-/&gt;
+    static=&quot;true&quot;/&gt;
 </pre></blockquote>
 <p>
   This invokes JavaCC on grammar file src/Parser.jj, writing the generated
@@ -203,8 +202,5 @@
   invoking JavaCC.
 </p>
 
-
 </body>
 </html>
-
-
diff --git a/manual/Tasks/javadoc.html b/manual/Tasks/javadoc.html
index 430435f..49b17c4 100644
--- a/manual/Tasks/javadoc.html
+++ b/manual/Tasks/javadoc.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="javadoc">Javadoc/<i>Javadoc2</i></a></h2>
+<h2 id="javadoc">Javadoc/<i>Javadoc2</i></h2>
 <h3>Description</h3>
 <p>Generates code documentation using the javadoc tool.</p>
 <p>The source directory will be recursively scanned for Java source files to process
@@ -35,18 +35,18 @@
 &quot;changed&quot; files, unlike the <a href="javac.html">javac</a> task. This means
 all packages will be processed each time this task is run. In general, however,
 this task is used much less frequently.</p>
-<p>NOTE: since javadoc calls System.exit(), javadoc cannot be run inside the
+<p><strong>Note</strong>: since javadoc calls System.exit(), javadoc cannot be run inside the
 same VM as Apache Ant without breaking functionality. For this reason, this task
 always forks the VM. This overhead is not significant since javadoc is normally a heavy
 application and will be called infrequently.</p>
-<p>NOTE: the packagelist attribute allows you to specify the list of packages to
+<p><strong>Note</strong>: the packagelist attribute allows you to specify the list of packages to
 document outside of the Ant file. It's a much better practice to include everything
 inside the <code>build.xml</code> file. This option was added in order to make it easier to
 migrate from regular makefiles, where you would use this option of javadoc.
 The packages listed in packagelist are not checked, so the task performs even
 if some packages are missing or broken. Use this option if you wish to convert from
 an existing makefile. Once things are running you should then switch to the regular
-notation. </p>
+notation.</p>
 
 <p><i><b>DEPRECATION:</b> the javadoc2 task simply points to the javadoc task and it's
 there for back compatibility reasons. Since this task will be removed in future
@@ -59,14 +59,14 @@
 If you specify the <code>executable</code> attribute it is up to you
 to ensure that this command supports the attributes you wish to use.</p>
 
-<p><b>Note:</b><br>When generating the JavaDocs for classes which contains annotations
+<p><strong>Note</strong>:<br>When generating the JavaDocs for classes which contains annotations
 you maybe get a <tt>java.lang.ClassCastException: com.sun.tools.javadoc.ClassDocImpl</tt>.
 This is due <a href="https://bugs.openjdk.java.net/browse/JDK-6442982" target="_blank">bug-6442982</a>. The cause is that JavaDoc cannot find the implementations of used annotations.
 The workaround is providing the jars with these implementations (like JAXBs <tt>@XmlType</tt>, ...)
 to &lt;javadoc&gt; using <tt>classpath</tt>, <tt>classpathref</tt> attributes or nested
 &lt;classpath&gt; element.</p>
 
-<p><b>Note:</b> many problems with running javadoc stem from command
+<p><strong>Note</strong>: many problems with running javadoc stem from command
   lines that have become too long - even though the error message
   doesn't give the slightest hint this may be the problem.  If you
   encounter problems with the task, try to set
@@ -81,7 +81,7 @@
   with the exclude patterns of the packageset (and vice versa).</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -208,9 +208,9 @@
     <td valign="top">Old</td>
     <td valign="top">Generate output using JDK 1.1 emulating
       doclet.<br>
-      <b>Note:</b> as of Ant 1.8.0 this attribute doesn't have any
-      effect since the javadoc of Java 1.4 (required by Ant 1.8.0)
-      doesn't support the -1.1 switch anymore.</td>
+      <strong>Note</strong>: <em>Since Ant 1.8.0</em> this attribute has no
+      effect because javadoc of Java 1.4 and later
+      does not support the -1.1 switch anymore.</td>
     <td align="center" valign="top">1.2</td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -523,8 +523,8 @@
       order to mitigate CVE-2013-1571.  Defaults to true.  <em>Since Ant
       1.9.2</em><br>
       There is a frame injection attack possible in javadocs generated by Oracle
-      JDKs prior to Java7 Update 25 (<a href="http://www.oracle.com/technetwork/java/javase/7u25-relnotes-1955741.html#jpi-upt" target="_blank">details</a>).  
-      When this flag is set to true, Ant will check whether the docs are vulnerable 
+      JDKs prior to Java 7 update 25 (<a href="http://www.oracle.com/technetwork/java/javase/7u25-relnotes-1955741.html#jpi-upt" target="_blank">details</a>).
+      When this flag is set to true, Ant will check whether the docs are vulnerable
       and will try to fix them.
     </td>
     <td align="center" valign="top">1.4</td>
@@ -532,7 +532,7 @@
   </tr>
 </table>
 
-<h4><a name="groupattribute">Format of the group attribute</a></h4>
+<h4 id="groupattribute">Format of the group attribute</h4>
 <p>The arguments are comma-delimited. Each single argument is 2
 space-delimited strings, where the first one is the group's title and
 the second one a colon delimited list of packages.</p>
@@ -588,7 +588,7 @@
 <p>Same as one entry in the list given by <code>packagenames</code>.</p>
 
 <h5>Parameters</h5>
-<table width="90%" border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -611,7 +611,7 @@
 <p>Same as one entry in the list given by <code>sourcefiles</code>.</p>
 
 <h5>Parameters</h5>
-<table width="90%" border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -651,7 +651,7 @@
 specify multiple occurrences of the arguments.</p>
 
 <h5>Parameters</h5>
-<table width="90%" border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -692,7 +692,7 @@
   </tr>
 </table>
 
-<h4><a name="groupelement">group</a></h4>
+<h4 id="groupelement">group</h4>
 <p>Separates packages on the overview page into whatever groups you
 specify, one group per table. This performs the same role as the group
 attribute. You can use either syntax (or both at once), but with the
@@ -700,7 +700,7 @@
 arguments.</p>
 
 <h5>Parameters</h5>
-<table width="90%" border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -745,14 +745,14 @@
   &lt;/javadoc&gt;
 </pre>
 
-<h4><a name="tagelement">tag</a></h4>
+<h4 id="tagelement">tag</h4>
 
 <p>If you want to specify a standard tag using a nested tag element
 because you want to determine the order the tags are output, you must
 not set the description attribute for those tags.</p>
 
 <h5>Parameters</h5>
-<table width="90%" border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -791,24 +791,24 @@
     <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#javadoctags">Javadoc reference guide</a>:
     <pre>ejb.bean:t:XDoclet EJB Tag
 todo:a:To Do</pre>
-      <b>Note:</b> The  Javadoc reference quide has double quotes around
+      <strong>Note</strong>: The Javadoc reference quide has double quotes around
 the description part of the definition. This will not work when used in
 a file, as the definition is quoted again when given to
 the javadoc program.
     <br/>
-      <b>Note:</b> If this attribute is specified, all the other attributes in this
+      <strong>Note</strong>: If this attribute is specified, all the other attributes in this
     element will be ignored.
     </td>
     <td align="center" valign="top">No</td>
   </tr>
 </table>
 
-<h4><a name="tagletelement">taglet</a></h4>
+<h4 id="tagletelement">taglet</h4>
 <p>The taglet nested element is used to specify custom
   <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/taglet/overview.html">taglets</a> beyond <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#javadoctags" target="_blank">the default taglets</a>.</p>
 
 <h5>Parameters</h5>
-<table width="90%" border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -908,8 +908,5 @@
     &lt;link href=&quot;http://docs.oracle.com/javase/7/docs/api/&quot;/&gt;
   &lt/javadoc&gt;</pre>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/javah.html b/manual/Tasks/javah.html
index d1daa7c..ac6ee3e 100644
--- a/manual/Tasks/javah.html
+++ b/manual/Tasks/javah.html
@@ -24,13 +24,13 @@
 
 <body>
 
-<h2><a name="javah">Javah</a></h2>
+<h2 id="javah">Javah</h2>
 <h3>Description</h3>
 <p>Generates JNI headers from a Java class.</p>
-<p> When this task executes, it will generate the C header and source files that
+<p>When this task executes, it will generate the C header and source files that
 are needed to implement native methods. JNI operates differently depending on
-whether <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javah.html">JDK1.2+</a>
-or <a href="http://java.sun.com/products/jdk/1.1/docs/tooldocs/win32/javah.html">pre-JDK1.2</a>
+whether <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javah.html">JDK 1.2+</a>
+or <a href="http://java.sun.com/products/jdk/1.1/docs/tooldocs/win32/javah.html">pre-1.2 JDK</a>
 systems are used.</p>
 
 <p>If you are building with Java 8 or above consider
@@ -38,34 +38,34 @@
   attribute instead which allows you to compile the classes and
   generate the native header files with a single step.</p>
 
-<p><b>Note</b> the <code>javah</code> has been deprecated as of Java 9
-  and removed as of Java 10. Trying to use it with Java10 will
+<p><strong>Note</strong>: <code>javah</code> has been deprecated as of Java 9
+  and removed as of Java 10. Trying to use it with Java 10 will
   fail.</p>
 
-<p>It is possible to use different compilers. This can be selected
-with the <code>implementation</code> attribute or a nested element.  <a
-name="implementationvalues">Here are the choices of the attribute</a>:</p>
+<p id="implementationvalues">It is possible to use different
+compilers. This can be selected with the <code>implementation</code>
+attribute or a nested element. Here are the choices of the
+attribute:</p>
 <ul>
   <li>default - the default compiler for the platform.</li>
-  <li>sun (the standard compiler of the JDK) - default when not
-    running on Kaffee or gcj/gij or Java9.</li>
-  <li>kaffeh (the native standard compiler of <a href="http://www.kaffe.org" target="_top">Kaffe</a>)</li>
-  <li>gcjh (the native standard compiler
+  <li>sun - the standard compiler of the JDK.</li>
+  <li>kaffeh - the native standard compiler of <a href="http://www.kaffe.org" target="_top">Kaffe</a>.</li>
+  <li>gcjh - the native standard compiler
   of <a href="http://gcc.gnu.org/java/"
-        target="_top">gcj and gij</a>) <em>since Apache Ant 1.8.2</em></li>
+        target="_top">gcj and gij</a>. <em>Since Apache Ant 1.8.2</em></li>
   <li>forking - runs the javah executable via its command line
-    interface in a separate process. Default when running on
-    Java9. <em>since Ant 1.9.8</em></li>
+    interface in a separate process. Default when not running on
+    Kaffe or gcj/gij <em>since Ant 1.9.8</em></li>
 </ul>
 
-<p><b>Note:</b> if you are using this task to work on multiple files
+<p><strong>Note</strong>: if you are using this task to work on multiple files
   the command line may become too long on some operating systems.
   Unfortunately the javah command doesn't support command argument
   files the way javac (for example) does, so all that can be done is
   breaking the amount of classes to compile into smaller chunks.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -89,13 +89,13 @@
   </tr>
   <tr>
     <td valign="top">force</td>
-    <td valign="top">specifies that output files should always be written (JDK1.2 only)</td>
+    <td valign="top">specifies that output files should always be written (JDK 1.2 only)</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
     <td valign="top">old</td>
-    <td valign="top">specifies that old JDK1.0-style header files should be generated
-      (otherwise output file contain JNI-style native method      function prototypes) (JDK1.2 only)</td>
+    <td valign="top">specifies that old JDK 1.0-style header files should be generated
+      (otherwise output file contain JNI-style native method function prototypes) (JDK 1.2 only)</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -144,7 +144,7 @@
 but have an additional attribute that can be used to enable arguments
 only if a given compiler implementation will be used.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -154,7 +154,7 @@
     <td valign="top">value</td>
     <td align="center" rowspan="4">See
     <a href="../using.html#arg">Command-line Arguments</a>.</td>
-    <td align="center" rowspan="4">Exactly one of these.</td>
+    <td align="center" rowspan="4">Exactly one of these</td>
   </tr>
   <tr>
     <td valign="top">line</td>
@@ -169,7 +169,7 @@
     <td valign="top">prefix</td>
     <td align="center" rowspan="2">See
     <a href="../using.html#arg">Command-line Arguments</a>.
-    <em>Since Ant 1.8.</em></td>
+    <em>Since Ant 1.8</em>.</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -186,7 +186,7 @@
   </tr>
 </table>
 
-<h4>implementationclasspath <em>since Ant 1.8.0</em></h4>
+<h4>implementationclasspath (<em>since Ant 1.8.0</em>)</h4>
 
 <p>A <a href="../using.html#path">PATH like structure</a> holding the
   classpath to use when loading the compiler implementation if a
@@ -194,7 +194,7 @@
   using one of the built-in compilers.</p>
 
 <h4>Any nested element of a type that implements JavahAdapter
-  <em>since Ant 1.8.0</em></h4>
+  (<em>since Ant 1.8.0</em>)</h4>
 
 <p>If a defined type implements the <code>JavahAdapter</code>
   interface a nested element of that type can be used as an
@@ -202,7 +202,7 @@
 
 <h3>Examples</h3>
 <pre>  &lt;javah destdir=&quot;c&quot; class=&quot;org.foo.bar.Wibble&quot;/&gt;</pre>
-<p>makes a JNI header of the named class, using the JDK1.2 JNI model. Assuming
+<p>makes a JNI header of the named class, using the JDK 1.2 JNI model. Assuming
 the directory 'c' already exists, the file <tt>org_foo_bar_Wibble.h</tt>
 is created there. If this file already exists, it is left unchanged.</p>
 <pre>  &lt;javah outputFile=&quot;wibble.h&quot;&gt;
@@ -252,5 +252,4 @@
   nested elements of its own.</p>
 
 </body>
-
 </html>
diff --git a/manual/Tasks/jdepend.html b/manual/Tasks/jdepend.html
index 7a9639d..27f60b0 100644
--- a/manual/Tasks/jdepend.html
+++ b/manual/Tasks/jdepend.html
@@ -14,97 +14,94 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-
 <html>
 <head>
    <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
-<title>JDepend Task</title>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <title>JDepend Task</title>
    <meta http-equiv="Content-Language" content="en-us">
 </head>
 
 <body>
 
-<h2><a NAME="JDepend"></a>JDepend</h2>
+<h2 id="jdepend">JDepend</h2>
 
 <h3>Description</h3>
 
-<P>Invokes the <a href="http://www.clarkware.com/software/JDepend.html">JDepend</a> parser.</P>
+<p>Invokes the <a href="http://www.clarkware.com/software/JDepend.html">JDepend</a> parser.</p>
 
-<P>This parser &quot;traverses a set of Java source file directories and generates design quality metrics for each Java package&quot;.
+<p>This parser &quot;traverses a set of Java source file directories and generates design quality metrics for each Java package&quot;.
 It allows to &quot;automatically measure the quality of a design in terms of its extensibility, reusability, and maintainability to
-effectively manage and control package dependencies.&quot;</P>
+effectively manage and control package dependencies.&quot;</p>
 
 <p>Source file directories are defined by nested
 <code>&lt;sourcespath&gt;</code>; Class file directories are defined
-by nested <code>&lt;classesespath&gt;</code>, see <a
+by nested <code>&lt;classespath&gt;</code>, see <a
 href="#nested">nested elements</a>.</p>
 
 <p>Optionally, you can also set the <code>outputfile</code> name where the output is stored. By default the task writes its report to the standard output.</P>
 
-<p> The task requires at least the JDepend 1.2 version. </p>
+<p>The task requires at least the JDepend 1.2 version.</p>
 
 <h3>Parameters</h3>
 
-<table BORDER=1 CELLSPACING=0 CELLPADDING=2 >
+<table>
   <tr>
-    <td VALIGN=TOP><b>Attribute</b></td>
-    <td VALIGN=TOP><b>Description</b></td>
-    <td ALIGN=CENTER VALIGN=TOP><b>Required</b></td>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
   </tr>
   <tr>
-    <td VALIGN=TOP>outputfile</td>
-    <td VALIGN=TOP>The output file name. If not set, the output is printed on the standard output.</td>
-    <td ALIGN=CENTER VALIGN=TOP>No</td>
+    <td valign="top">outputfile</td>
+    <td valign="top">The output file name. If not set, the output is printed on the standard output.</td>
+    <td align="center" valign="top">No</td>
   </tr>
   <tr>
-    <td VALIGN=TOP>format</td>
-    <td VALIGN=TOP>The format to write the output in. The default is "text", the alternative is "xml"</td>
-    <td ALIGN=CENTER VALIGN=TOP>No</td>
+    <td valign="top">format</td>
+    <td valign="top">The format to write the output in. The default is "text", the alternative is "xml"</td>
+    <td align="center" valign="top">No</td>
   </tr>
   <tr>
-    <td VALIGN=TOP>fork</td>
-    <td VALIGN=TOP>Run the tests in a separate VM.</td>
-    <td ALIGN=CENTER VALIGN=TOP>No, default is "off"</td>
+    <td valign="top">fork</td>
+    <td valign="top">Run the tests in a separate VM.</td>
+    <td align="center" valign="top">No, default is "off"</td>
   </tr>
   <tr>
-    <td VALIGN=TOP>haltonerror</td>
-    <td VALIGN=TOP>Stop the build process if an error occurs during the jdepend analysis.</td>
-    <td ALIGN=CENTER VALIGN=TOP>No, default is "off"</td>
+    <td valign="top">haltonerror</td>
+    <td valign="top">Stop the build process if an error occurs during the jdepend analysis.</td>
+    <td align="center" valign="top">No, default is "off"</td>
   </tr>
   <tr>
-    <td VALIGN=TOP>timeout</td>
-    <td VALIGN=TOP>Cancel the operation if it doesn't finish in the given time (measured in milliseconds). (Ignored if fork is disabled.)</td>
-    <td ALIGN=CENTER VALIGN=TOP>No</td>
+    <td valign="top">timeout</td>
+    <td valign="top">Cancel the operation if it doesn't finish in the given time (measured in milliseconds). (Ignored if fork is disabled.)</td>
+    <td align="center" valign="top">No</td>
   </tr>
   <tr>
-    <td VALIGN=TOP>jvm</td>
-    <td VALIGN=TOP>The command used to invoke the Java Virtual Machine, default is 'java'. The command is resolved by java.lang.Runtime.exec(). (Ignored if fork is disabled.)</td>
-    <td ALIGN=CENTER VALIGN=TOP>No, default "java"</td>
+    <td valign="top">jvm</td>
+    <td valign="top">The command used to invoke the Java Virtual Machine, default is 'java'. The command is resolved by java.lang.Runtime.exec(). (Ignored if fork is disabled.)</td>
+    <td align="center" valign="top">No, default "java"</td>
   </tr>
   <tr>
-    <td VALIGN=TOP>dir</td>
-    <td VALIGN=TOP>The directory to invoke the VM in. (Ignored if fork is disabled)</td>
-    <td ALIGN=CENTER VALIGN=TOP>No</td>
+    <td valign="top">dir</td>
+    <td valign="top">The directory to invoke the VM in. (Ignored if fork is disabled)</td>
+    <td align="center" valign="top">No</td>
   </tr>
   <tr>
-    <td VALIGN=TOP>includeruntime</td>
-    <td VALIGN=TOP>Implicitly add the classes required to run jdepend
-    in forked mode. (Ignored if fork is disabled). Since Apache Ant 1.6.</td>
-    <td ALIGN=CENTER VALIGN=TOP>No, default is "no".</td>
+    <td valign="top">includeruntime</td>
+    <td valign="top">Implicitly add the classes required to run jdepend
+      in forked mode. (Ignored if fork is disabled). <em>Since Apache Ant 1.6</em>.</td>
+    <td align="center" valign="top">No, default is "no".</td>
   </tr>
   <tr>
-    <td VALIGN=TOP>classpathref</td>
-    <td VALIGN=TOP>the classpath to use, given as reference to a PATH defined elsewhere.</td>
-    <td ALIGN=CENTER VALIGN=TOP>No</td>
+    <td valign="top">classpathref</td>
+    <td valign="top">the classpath to use, given as reference to a PATH defined elsewhere.</td>
+    <td align="center" valign="top">No</td>
   </tr>
 </table>
 
-<h3><a name="nested">Nested Elements</a></h3>
+<h3 id="nested">Nested Elements</h3>
 
 <p><code>jdepend</code> supports four nested elements:
-<code>&lt;classpath&gt;, &lt;classespath&gt; </code> and
+<code>&lt;classpath&gt;, &lt;classespath&gt;</code> and
 <code>&lt;sourcespath&gt;</code>, that represent <a
 href="../using.html#path">PATH like structures</a>, and
 <code>&lt;exclude&gt;</code>.</p>
@@ -127,7 +124,6 @@
 &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;pathelement location="build"/&gt;
 &nbsp;&nbsp;&nbsp; &lt;/classespath&gt;
 &lt;/jdepend&gt;
-
 </pre>
 </blockquote>
 
@@ -152,7 +148,7 @@
 <p>This invokes JDepend in a separate VM on the <code>src</code> and
 <code>testsrc</code> directories, writing the output to the
 <code>&lt;docs/jdepend.xml&gt;</code> file in xml format. The
-classpath is defined using nested elements. </p>
+classpath is defined using nested elements.</p>
 
 <blockquote>
 <pre>
@@ -170,8 +166,5 @@
 files to analyze, and will ignore all classes in the java.* and
 javax.* packages.</p>
 
-
 </body>
 </html>
-
-
diff --git a/manual/Tasks/jjdoc.html b/manual/Tasks/jjdoc.html
index 52b9225..f3721b5 100644
--- a/manual/Tasks/jjdoc.html
+++ b/manual/Tasks/jjdoc.html
@@ -14,18 +14,15 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
 <html>
 <head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta http-equiv="Content-Language" content="en-us">
    <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
 <title>JJDoc Task</title>
 </head>
 <body>
 
-<h2>
-<a NAME="jjtree"></a>JJDoc</h2>
+<h2 id="jjtree">JJDoc</h2>
 <p><em>Since Apache Ant 1.6</em></p>
 <h3>Description</h3>
 
@@ -36,7 +33,7 @@
 <p>To use the jjdoc task, set the <i>target</i> attribute to the name
 of the JavaCC grammar file to process. You also need to specify the directory
 containing the JavaCC installation using the <i>javacchome</i> attribute,
-so that ant can find the JavaCC classes. Optionally, you can also set the
+so that Ant can find the JavaCC classes. Optionally, you can also set the
 <i>outputfile</i> to write the generated BNF documentation file to a specific (directory and) file.
 Otherwise jjdoc writes the generated BNF documentation file as the JavaCC
 grammar file with a suffix .txt or .html.</p>
@@ -45,55 +42,55 @@
 
 <h3>Parameters</h3>
 
-<table BORDER CELLSPACING=0 CELLPADDING=2 >
+<table>
 <tr>
-<td VALIGN=TOP><b>Attribute</b></td>
+<td valign="top"><b>Attribute</b></td>
 
-<td VALIGN=TOP><b>Description</b></td>
+<td valign="top"><b>Description</b></td>
 
-<td ALIGN=CENTER VALIGN=TOP><b>Required</b></td>
+<td align="center" valign="top"><b>Required</b></td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>target</td>
+<td valign="top">target</td>
 
-<td VALIGN=TOP>The javacc grammar file to process.</td>
+<td valign="top">The javacc grammar file to process.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>Yes</td>
+<td align="center" valign="top">Yes</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>javacchome</td>
+<td valign="top">javacchome</td>
 
-<td VALIGN=TOP>The directory containing the JavaCC distribution.</td>
+<td valign="top">The directory containing the JavaCC distribution.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>Yes</td>
+<td align="center" valign="top">Yes</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>outputfile</td>
+<td valign="top">outputfile</td>
 
-<td VALIGN=TOP>The file to write the generated BNF documentation file to. If not set,
+<td valign="top">The file to write the generated BNF documentation file to. If not set,
 the file is written with the same name as the JavaCC grammar file but with a the suffix .html or .txt.&nbsp;</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>text</td>
+<td valign="top">text</td>
 
-<td VALIGN=TOP>Sets the TEXT BNF documentation option. This is a boolean
+<td valign="top">Sets the TEXT BNF documentation option. This is a boolean
 option.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>onetable</td>
+<td valign="top">onetable</td>
 
-<td VALIGN=TOP>Sets the ONE_TABLE BNF documentation option. This is a boolean option.</td>
+<td valign="top">Sets the ONE_TABLE BNF documentation option. This is a boolean option.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
   <tr>
@@ -108,16 +105,13 @@
 Example</h3>
 
 <blockquote>
-<pre>&lt;jjdoc&nbsp;
-&nbsp;&nbsp;&nbsp; target="src/Parser.jj"&nbsp;
+<pre>&lt;jjdoc
+&nbsp;&nbsp;&nbsp; target="src/Parser.jj"
 &nbsp;&nbsp;&nbsp; outputfile="doc/ParserBNF.html"
-&nbsp;&nbsp;&nbsp; javacchome="c:/program files/JavaCC"&nbsp;
-/&gt;</pre>
+&nbsp;&nbsp;&nbsp; javacchome="c:/program files/JavaCC"/&gt;</pre>
 </blockquote>
 This invokes JJDoc on grammar file src/Parser.jj, writing the generated
 BNF documentation file, ParserBNF.html, file to doc.
-<br>
 
 </body>
 </html>
-
diff --git a/manual/Tasks/jjtree.html b/manual/Tasks/jjtree.html
index 7fbb2a9..70529bb 100644
--- a/manual/Tasks/jjtree.html
+++ b/manual/Tasks/jjtree.html
@@ -14,21 +14,17 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
 <html>
 <head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta http-equiv="Content-Language" content="en-us">
    <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
 <title>JJTree Task</title>
 </head>
 <body>
 
-<h2>
-<a NAME="jjtree"></a>JJTree</h2>
+<h2 id="jjtree">JJTree</h2>
 
-<h3>
-Description</h3>
+<h3>Description</h3>
 <p>Invokes the <a href="http://javacc.dev.java.net/">JJTree</a> preprocessor
 for the JavaCC compiler compiler. It inserts parse tree building actions
 at various places in the JavaCC source that it generates. The output of
@@ -49,143 +45,143 @@
 
 <h3>Parameters</h3>
 
-<table BORDER CELLSPACING=0 CELLPADDING=2 >
+<table>
 <tr>
-<td VALIGN=TOP><b>Attribute</b></td>
+<td valign="top"><b>Attribute</b></td>
 
-<td VALIGN=TOP><b>Description</b></td>
+<td valign="top"><b>Description</b></td>
 
-<td ALIGN=CENTER VALIGN=TOP><b>Required</b></td>
+<td align="center" valign="top"><b>Required</b></td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>target</td>
+<td valign="top">target</td>
 
-<td VALIGN=TOP>The jjtree grammar file to process.</td>
+<td valign="top">The jjtree grammar file to process.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>Yes</td>
+<td align="center" valign="top">Yes</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>javacchome</td>
+<td valign="top">javacchome</td>
 
-<td VALIGN=TOP>The directory containing the JavaCC distribution.</td>
+<td valign="top">The directory containing the JavaCC distribution.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>Yes</td>
+<td align="center" valign="top">Yes</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>outputdirectory</td>
+<td valign="top">outputdirectory</td>
 
-<td VALIGN=TOP>The directory to write the generated JavaCC grammar and node files to.
+<td valign="top">The directory to write the generated JavaCC grammar and node files to.
 If not set, the files are written to the directory containing the grammar file.&nbsp;</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>outputfile</td>
+<td valign="top">outputfile</td>
 
-<td VALIGN=TOP>The file to write the generated JavaCC grammar file
+<td valign="top">The file to write the generated JavaCC grammar file
 to. If not set, the file is written with the same name as the JJTree
 grammar file but with a the suffix <code>.jj</code>.  This is a
 filename relative to <em>outputdirectory</em> if specified, the
 project's basedir.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>buildnodefiles</td>
+<td valign="top">buildnodefiles</td>
 
-<td VALIGN=TOP>Sets the BUILD_NODE_FILES grammar option. This is a boolean
+<td valign="top">Sets the BUILD_NODE_FILES grammar option. This is a boolean
 option.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>multi</td>
+<td valign="top">multi</td>
 
-<td VALIGN=TOP>Sets the MULTI grammar option. This is a boolean option.</td>
+<td valign="top">Sets the MULTI grammar option. This is a boolean option.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>nodedefaultvoid</td>
+<td valign="top">nodedefaultvoid</td>
 
-<td VALIGN=TOP>Sets the NODE_DEFAULT_VOID grammar option. This is a boolean
+<td valign="top">Sets the NODE_DEFAULT_VOID grammar option. This is a boolean
 option.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>nodefactory</td>
+<td valign="top">nodefactory</td>
 
-<td VALIGN=TOP>Sets the NODE_FACTORY grammar option. This is boolean option.</td>
+<td valign="top">Sets the NODE_FACTORY grammar option. This is boolean option.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>nodescopehook</td>
+<td valign="top">nodescopehook</td>
 
-<td VALIGN=TOP>Sets the NODE_SCOPE_HOOK grammar option. This is a boolean
+<td valign="top">Sets the NODE_SCOPE_HOOK grammar option. This is a boolean
 option.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>nodeusesparser</td>
+<td valign="top">nodeusesparser</td>
 
-<td VALIGN=TOP>Sets the NODE_USES_PARSER grammar option. This is a boolean
+<td valign="top">Sets the NODE_USES_PARSER grammar option. This is a boolean
 option.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>static</td>
+<td valign="top">static</td>
 
-<td VALIGN=TOP>Sets the STATIC grammar option. This is a boolean option.</td>
+<td valign="top">Sets the STATIC grammar option. This is a boolean option.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>visitor</td>
+<td valign="top">visitor</td>
 
-<td VALIGN=TOP>Sets the VISITOR grammar option. This is a boolean option.</td>
+<td valign="top">Sets the VISITOR grammar option. This is a boolean option.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>nodepackage</td>
+<td valign="top">nodepackage</td>
 
-<td VALIGN=TOP>Sets the NODE_PACKAGE grammar option. This is a string option.</td>
+<td valign="top">Sets the NODE_PACKAGE grammar option. This is a string option.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>visitorexception</td>
+<td valign="top">visitorexception</td>
 
-<td VALIGN=TOP>Sets the VISITOR_EXCEPTION grammar option. This is a string
+<td valign="top">Sets the VISITOR_EXCEPTION grammar option. This is a string
 option.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP>nodeprefix</td>
+<td valign="top">nodeprefix</td>
 
-<td VALIGN=TOP>Sets the NODE_PREFIX grammar option. This is a string option.</td>
+<td valign="top">Sets the NODE_PREFIX grammar option. This is a string option.</td>
 
-<td ALIGN=CENTER VALIGN=TOP>No</td>
+<td align="center" valign="top">No</td>
 </tr>
 
   <tr>
@@ -196,16 +192,14 @@
   </tr>
 </table>
 
-<h3>
-Example</h3>
+<h3>Example</h3>
 
 <blockquote>
 <pre>&lt;jjtree&nbsp;
-&nbsp;&nbsp;&nbsp; target="src/Parser.jjt"&nbsp;
+&nbsp;&nbsp;&nbsp; target="src/Parser.jjt"
 &nbsp;&nbsp;&nbsp; outputdirectory="build/src"
-&nbsp;&nbsp;&nbsp; javacchome="c:/program files/JavaCC"&nbsp;
-&nbsp;&nbsp;&nbsp; nodeusesparser="true"
-/&gt;</pre>
+&nbsp;&nbsp;&nbsp; javacchome="c:/program files/JavaCC"
+&nbsp;&nbsp;&nbsp; nodeusesparser="true"/&gt;</pre>
 </blockquote>
 This invokes JJTree on grammar file src/Parser.jjt, writing the generated
 grammar file, Parser.jj, file to build/src. The grammar option NODE_USES_PARSER
@@ -214,7 +208,7 @@
 
 <h3>Comparison output locations between command line JJTree and different Ant taskdef versions</h3>
 
-<table cellpadding="3" border="1">
+<table>
 <tr>
   <td><b>Command Line JJTree options</b>
     <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i>and Generated Files</i> (working directory: <code>/tmp</code>)</td>
@@ -541,23 +535,17 @@
 </tr>
 </table>
 
-<p>*) <u>Footnote</u>: When running JJTree with the Ant taskdef <i>jjtree</i> the option <code>-OUTPUT_DIRECTORY</code> must always 
-be set, because the project's basedir and the Ant working directory might differ. So even if you don't specify the jjtree taskdef 
-<i>outputdirectory</i> JJTree will be called with the <code>-OUTPUT_DIRECTORY</code> set to the project's basedirectory. 
-But when the <code>-OUTPUT_DIRECTORY</code> is set, the <code>-OUTPUT_FILE</code> setting is handled as if relative to this 
-<code>-OUTPUT_DIRECTORY</code>. Thus when the <code>-OUTPUT_FILE</code> is absolute or contains a drive letter we have a 
-problem. 
+<p>*) <u>Footnote</u>: When running JJTree with the Ant taskdef <i>jjtree</i> the option <code>-OUTPUT_DIRECTORY</code> must always
+be set, because the project's basedir and the Ant working directory might differ. So even if you don't specify the jjtree taskdef
+<i>outputdirectory</i> JJTree will be called with the <code>-OUTPUT_DIRECTORY</code> set to the project's basedirectory.
+But when the <code>-OUTPUT_DIRECTORY</code> is set, the <code>-OUTPUT_FILE</code> setting is handled as if relative to this
+<code>-OUTPUT_DIRECTORY</code>. Thus when the <code>-OUTPUT_FILE</code> is absolute or contains a drive letter we have a
+problem.
 Therefore absolute <i>outputfile</i>s (when the <i>outputdirectory</i> isn't specified) are made relative to the default directory.
 And for this reason <i>outputfile</i>s that contain a drive letter can't be supported.</p>
 
-<p>By the way: specifying a drive letter in the <code>-OUTPUT_FILE</code> when the <code>-OUTPUT_DIRECTORY</code> is set, also 
+<p>By the way: specifying a drive letter in the <code>-OUTPUT_FILE</code> when the <code>-OUTPUT_DIRECTORY</code> is set, also
 results in strange behavior when running JJTree from the command line.</p>
 
-<br>
-
-
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/jlink.html b/manual/Tasks/jlink.html
index 45ef961..5cf7b34 100644
--- a/manual/Tasks/jlink.html
+++ b/manual/Tasks/jlink.html
@@ -21,7 +21,7 @@
 </head>
 <body>
 
-<h2><a name="jlink">Jlink</a></h2>
+<h2 id="jlink">Jlink</h2>
 <h3><i>Deprecated</i></h3>
 <p><i>This task has been deprecated. Use a <a href="../Types/zipfileset.html">zipfileset</a>
  or <a href="../Tasks/zip.html#zipgroupfileset">zipgroupfileset</a> with the
@@ -31,32 +31,32 @@
 <h3><b>Description:</b></h3>
 <p>Links entries from sub-builds and libraries.</p>
 
-<p>The jlink task can be used to build jar and zip files, similar to 
+<p>The jlink task can be used to build jar and zip files, similar to
 the <i>jar</i> task.
-However, jlink provides options for controlling the way entries from 
+However, jlink provides options for controlling the way entries from
 input files
-are added to the output file. Specifically, capabilities for merging 
+are added to the output file. Specifically, capabilities for merging
 entries from
 multiple zip or jar files is available.</p>
 
-<p>If a mergefile is specified directly (eg. at the top level of a 
+<p>If a mergefile is specified directly (eg. at the top level of a
 <i>mergefiles</i>
-pathelement) <i>and</i> the mergefile ends in &quot;.zip&quot; or 
+pathelement) <i>and</i> the mergefile ends in &quot;.zip&quot; or
 &quot;.jar&quot;,
-entries in the mergefile will be merged into the outfile. A file with 
+entries in the mergefile will be merged into the outfile. A file with
 any other extension
-will be added to the output file, even if it is specified in the 
+will be added to the output file, even if it is specified in the
 mergefiles element.
-Directories specified in either the mergefiles or addfiles element 
+Directories specified in either the mergefiles or addfiles element
 are added to the
-output file as you would expect: all files in subdirectories are 
+output file as you would expect: all files in subdirectories are
 recursively added to
-the output file with appropriate prefixes in the output file 
+the output file with appropriate prefixes in the output file
 (without merging).
 </p>
 
 <p>
-In the case where duplicate entries and/or files are found among the 
+In the case where duplicate entries and/or files are found among the
 files to be merged or
 added, jlink merges or adds the first entry and ignores all subsequent entries.
 </p>
@@ -66,11 +66,11 @@
 own manifest information for the output file.
 </p>
 
-<p>It is possible to refine the set of files that are being jlinked. 
+<p>It is possible to refine the set of files that are being jlinked.
 This can be
-done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>, 
+done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>,
 <i>excludesfile</i>,
-and <i>defaultexcludes</i> attributes on the <i>addfiles</i> and 
+and <i>defaultexcludes</i> attributes on the <i>addfiles</i> and
 <i>mergefiles</i>
 nested elements. With the <i>includes</i> or <i>includesfile</i>
 attribute you specify the files you want to have included by using patterns.
@@ -85,7 +85,7 @@
 
 
 <h3>Parameters:</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
    <tr>
      <td valign="top"><b>Attribute</b></td>
      <td valign="top"><b>Description</b></td>
@@ -98,7 +98,7 @@
    </tr>
    <tr>
      <td valign="top">compress</td>
-     <td valign="top">whether or not the output should be compressed. 
+     <td valign="top">whether or not the output should be compressed.
 <i>true</i>,
                       <i>yes</i>, or <i>on</i> result in compressed output.
                       If omitted, output will be uncompressed (inflated).</td>
@@ -107,8 +107,7 @@
    <tr>
      <td valign="top">mergefiles</td>
      <td valign="top">files to be merged into the output, if possible.</td>
-     <td valign="middle" align="center" rowspan="2">At least one of 
-mergefiles or addfiles</td>
+     <td valign="middle" align="center" rowspan="2">Exactly one of the two</td>
    </tr>
    <tr>
      <td valign="top">addfiles</td>
@@ -118,7 +117,7 @@
 
 <h3>Examples</h3>
 
-<p>The following will merge the entries in mergefoo.jar and mergebar.jar 
+<p>The following will merge the entries in mergefoo.jar and mergebar.jar
 into out.jar.
 mac.jar and pc.jar will be added as single entries to out.jar.</p>
 <pre>
@@ -148,9 +147,9 @@
 &lt;/jar&gt;
 </pre>
 
-<p>Suppose the file foo.jar contains two entries: bar.class and 
+<p>Suppose the file foo.jar contains two entries: bar.class and
 barnone/myClass.zip.
-Suppose the path for file foo.jar is build/tempbuild/foo.jar. The 
+Suppose the path for file foo.jar is build/tempbuild/foo.jar. The
 following example
 will provide the entry tempbuild/foo.jar in the out.jar.</p>
 <pre>
@@ -171,7 +170,5 @@
 &lt;/jlink&gt;
 </pre>
 
-
 </body>
-
 </html>
diff --git a/manual/Tasks/jspc.html b/manual/Tasks/jspc.html
index 8836186..678d02d 100644
--- a/manual/Tasks/jspc.html
+++ b/manual/Tasks/jspc.html
@@ -24,32 +24,35 @@
 
 <body>
 
-<h2><a name="jspc">jspc (deprecated)</a></h2>
+<h2 id="jspc">jspc</h2>
+<h3><i>Deprecated</i></h3>
+<p>
+<i>If you use this task with Tomcat's Jasper JSP compiler, you should seriously
+consider using the task shipping with Tomcat instead.</i>  This task is only
+tested against Tomcat 4.x. There are known problems with Tomcat 5.x that won't
+get fixed in Ant, please use Tomcat's jspc task instead.<br/>
+Instead of relying on container specific JSP-compilers we suggest deploying the
+raw files (*.jsp) and use the container build-in functions: after deploying run
+a test suite
+(e.g. with <a href="http://attic.apache.org/projects/jakarta-cactus.html">Cactus</a>
+or <a href="http://httpunit.sourceforge.net/">HttpUnit</a>) against the deployed
+web application. So you'll get the test result <i>and</i> the compiled JSPs.
+</p>
 <h3>Description</h3>
 
-<p> Apache Ant task to run the JSP compiler and turn JSP pages into Java source.
-
-<p><b>Deprecated</b> if you use this task with Tomcat's Jasper JSP
-compiler, you should seriously consider using the task shipping with
-Tomcat instead.  This task is only tested against Tomcat 4.x. There
-are known problems with Tomcat 5.x that won't get fixed in Ant, please
-use Tomcat's jspc task instead.<br/>
-Instead of relying on container specific JSP-compilers we suggest deploying 
-the raw files (*.jsp) and use the container build-in functions: after deploying run
-a test suite (e.g. with <a href="http://attic.apache.org/projects/jakarta-cactus.html">Cactus</a> or 
-<a href="http://httpunit.sourceforge.net/">HttpUnit</a>) against the deployed web 
-application. So you'll get the test result <i>and</i> the compiled JSPs.
+<p>
+Apache Ant task to run the JSP compiler and turn JSP pages into Java source.
 </p>
 
 <p>
-
-This task can be used to precompile JSP pages for fast initial invocation
-of JSP pages, deployment on a server without the full JDK installed,
-or simply to syntax check the pages without deploying them.
-In most cases, a javac task is usually the next stage in the build process.
-The task does basic dependency checking to prevent unnecessary recompilation -this
-checking compares source and destination timestamps, and does not factor
-in class or taglib dependencies, or <code>&lt;jsp:include&gt;</code> references.
+This task can be used to precompile JSP pages for fast initial invocation of JSP
+pages, deployment on a server without the full JDK installed, or simply to
+syntax check the pages without deploying them.  In most cases, a javac task is
+usually the next stage in the build process.  The task does basic dependency
+checking to prevent unnecessary recompilation - this checking compares source
+and destination timestamps, and does not factor in class or taglib dependencies,
+or <code>&lt;jsp:include&gt;</code> references.
+</p>
 
 <p>
 By default the task uses the Jasper JSP compiler. This
@@ -60,25 +63,24 @@
 
 We recommend (in March 2003) Tomcat version 4.1.x for the most robust version
 of Jasper.
+</p>
 
 <p>
-There are many limitations with this task which partially stem from the
-many versions of Jasper, others from implementation 'issues' in the task
-(i.e. nobody's willingness to radically change large bits of it to work
-around jasper). Because of this and the fact that JSP pages do not have
-to be portable across implementations -or versions of implementations-
-this task is better used for validating JSP pages before deployment,
-rather than precompiling them. For that, just deploy and run your httpunit
-junit tests after deployment to compile and test your pages, all in one
-go.
- 
+There are many limitations with this task which partially stem from the many
+versions of Jasper, others from implementation 'issues' in the task
+(i.e. nobody's willingness to radically change large bits of it to work around
+jasper). Because of this and the fact that JSP pages do not have to be portable
+across implementations -or versions of implementations- this task is better used
+for validating JSP pages before deployment, rather than precompiling them. For
+that, just deploy and run your httpunit junit tests after deployment to compile
+and test your pages, all in one go.
 </p>
 
 
 <h3>Parameters</h3>
-The Task has the following attributes:<p>
+<p>The Task has the following attributes:</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -178,52 +180,53 @@
     <td valign="top">webinc</td>
     <td valign="top">Output file name for the fraction of web.xml that lists servlets.</td>
     <td valign="top" align="center">No</td>
-  </tr>    
+  </tr>
   <tr>
     <td valign="top">webxml</td>
     <td valign="top">File name for web.xml to be generated</td>
     <td valign="top" align="center">No</td>
-  </tr>  
+  </tr>
+</table>
 
-  </table>
-
-<P>The <tt>mapped</tt> option will, if set to true, split the JSP text content into a
+<p>The <tt>mapped</tt> option will, if set to true, split the JSP text content into a
 one line per call format.  There are comments above and below the mapped
 write calls to localize where in the JSP file each line of text comes
 from.  This can lead to a minor performance degradation (but it is bound
 by a linear complexity).  Without this options all adjacent writes are
-concatenated into a single write.</P>
+concatenated into a single write.</p>
 
-<P>The <tt>ieplugin</tt> option is used by the <tt>&lt;jsp:plugin&gt;</tt> tags.
+<p>The <tt>ieplugin</tt> option is used by the <tt>&lt;jsp:plugin&gt;</tt> tags.
 If the Java Plug-in COM Class-ID you want to use changes then it can be
-specified here.  This should not need to be altered.</P>
+specified here.  This should not need to be altered.</p>
 
-<P><tt>uriroot</tt> specifies the root of the web
+<p><tt>uriroot</tt> specifies the root of the web
 application.  This is where all absolute uris will be resolved from.
 If it is not specified then the first JSP page will be used to derive
 it.  To derive it each parent directory of the first JSP page is
 searched for a <tt>WEB-INF</tt> directory, and the directory closest to
 the JSP page that has one will be used.  If none can be found then the
 directory Jasperc was called from will be used.  This only affects pages
-translated from an explicitly declared JSP file -including references
-to taglibs</P>
+translated from an explicitly declared JSP file - including references
+to taglibs</p>
 
-<P><tt>uribase</tt> is used to establish the uri context of
+<p><tt>uribase</tt> is used to establish the uri context of
 relative URI references in the JSP pages.  If it does not exist then it
 is derived from the location of the file relative to the declared or
 derived value of <tt>uriroot</tt>. This only affects pages
-translated from an explicitly declared JSP file.</P>
+translated from an explicitly declared JSP file.</p>
 
 <h3>Parameters specified as nested elements</h3>
 
+<p>
 This task is a <a href="../dirtasks.html">directory based task</a>, like
 <strong>javac</strong>, so the jsp files to be compiled are located as java
 files are by <strong>javac</strong>. That is, elements such as <tt>includes</tt> and
 <tt>excludes</tt> can be used directly inside the task declaration.
+</p>
 
 <p>
-
-Elements specific to the jspc task are:-
+Elements specific to the jspc task are:
+</p>
 
 <h4>classpath</h4>
 
@@ -231,13 +234,15 @@
 classpath.
 
 <h4>classpathref</h4>
+
 a reference to an existing classpath
 
 <h4>webapp</h4>
+
 Instructions to jasper to build an entire web application.
 The base directory must have a WEB-INF subdirectory beneath it.
 When used, the task hands off all dependency checking to the compiler.
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -283,10 +288,11 @@
 </pre>
 Generate jsp pages then javac them down to
 bytecodes. Include lib/taglib jar in the java compilation.
- Dependency checking is used to scrub the
+Dependency checking is used to scrub the
 java files if class dependencies indicate it is needed.
 
-<p><h4>Notes</h4>
+<h4>Notes</h4>
+<p>
 Using the <code>package</code> attribute it is possible to identify the resulting
 java files and thus do full dependency checking - this task should only rebuild
 java files if their jsp file has been modified. However, this only works
@@ -295,14 +301,11 @@
 dependency checking.
 Even when it does work, changes in
 .TLD imports or in compile time includes do not get picked up.
-
+</p>
 <p>
 Jasper generates JSP pages against the JSP1.2 specification -a copy of
 version 2.3 of the servlet specification is needed on the classpath to
 compile the Java code.
-
-
-
+</p>
 </body>
 </html>
-
diff --git a/manual/Tasks/junit.html b/manual/Tasks/junit.html
index a6879a8..e53ace7 100644
--- a/manual/Tasks/junit.html
+++ b/manual/Tasks/junit.html
@@ -21,7 +21,7 @@
 </head>
 <body>
 
-<h2><a name="junit">JUnit</a></h2>
+<h2 id="junit">JUnit</h2>
 <h3>Description</h3>
 
 <p>This task runs tests from the JUnit testing framework. The latest
@@ -30,7 +30,7 @@
 This task has been tested with JUnit 3.0 up to JUnit 3.8.2; it won't
 work with versions prior to JUnit 3.0. It also works with JUnit 4.0, including
 "pure" JUnit 4 tests using only annotations and no <code>JUnit4TestAdapter</code>.</p>
-<p><strong>Note:</strong> This task depends on external libraries not included
+<p><strong>Note</strong>: This task depends on external libraries not included
 in the Apache Ant distribution.  See <a href="../install.html#librarydependencies">
 Library Dependencies</a> for more information.
 </p>
@@ -58,7 +58,7 @@
 <li>
 Leave <code>ant-junit.jar</code> in its default location in <code>ANT_HOME/lib</code>
 but include <code>junit.jar</code> in the <code>&lt;classpath&gt;</code> passed
-to <code>&lt;junit&gt;</code>. <em>(since Ant 1.7)</em>
+to <code>&lt;junit&gt;</code>. <em>Since Ant 1.7</em>
 </li>
 </ol>
 <p>
@@ -71,7 +71,7 @@
 elements</a>).</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -108,7 +108,7 @@
     <code>failureproperty</code> can share a VM, so even if you set
     <code>forkmode</code> to &quot;once&quot;, Ant may have to create
     more than a single Java VM.  This attribute is ignored for tests
-    that don't get forked into a new Java VM.  <em>since Ant 1.6.2</em></td>
+    that don't get forked into a new Java VM.  <em>Since Ant 1.6.2</em></td>
     <td align="center" valign="top">No; default is <code>perTest</code>.</td>
   </tr>
   <tr>
@@ -152,7 +152,7 @@
   <tr>
     <td valign="top">maxmemory</td>
     <td valign="top">Maximum amount of memory to allocate to the forked VM.
-      Ignored if <code>fork</code> is disabled. <strong>Note</strong>: 
+      Ignored if <code>fork</code> is disabled. <strong>Note</strong>:
       If you get <code>java.lang.OutOfMemoryError: Java heap space</code>
       in some of your tests then you need to raise the size like
       <code>maxmemory="128m"</code></td>
@@ -196,7 +196,7 @@
   <tr>
     <td valign="top">outputtoformatters</td>
     <td valign="top">
-      <em>Since Ant 1.7.0.</em><br/>
+      <em>Since Ant 1.7.0</em>.<br/>
       Send any output generated by tests to the test formatters.
       This is "true" by default.
     </td>
@@ -234,7 +234,7 @@
       formatter output to find the failing tests.
       <em>since Ant 1.8.0</em></td>
     <td align="center" valign="top">No</td>
-  </tr>    
+  </tr>
   <tr>
     <td valign="top">enableTestListenerEvents</td>
     <td valign="top">Whether Ant should send fine grained information
@@ -268,21 +268,21 @@
 stack traces before reporting them.
 It works with both the plain and XML formatters.  It filters out any lines
 that begin with the following string patterns:<pre>
-   "junit.framework.TestCase"
-   "junit.framework.TestResult"
-   "junit.framework.TestSuite"
-   "junit.framework.Assert."
-   "junit.swingui.TestRunner"
-   "junit.awtui.TestRunner"
-   "junit.textui.TestRunner"
-   "java.lang.reflect.Method.invoke("
-   "sun.reflect."
-   "org.apache.tools.ant."
-   "org.junit."
-   "junit.framework.JUnit4TestAdapter"
-   " more"</pre>
+   &quot;junit.framework.TestCase&quot;
+   &quot;junit.framework.TestResult&quot;
+   &quot;junit.framework.TestSuite&quot;
+   &quot;junit.framework.Assert.&quot;
+   &quot;junit.swingui.TestRunner&quot;
+   &quot;junit.awtui.TestRunner&quot;
+   &quot;junit.textui.TestRunner&quot;
+   &quot;java.lang.reflect.Method.invoke(&quot;
+   &quot;sun.reflect.&quot;
+   &quot;org.apache.tools.ant.&quot;
+   &quot;org.junit.&quot;
+   &quot;junit.framework.JUnit4TestAdapter&quot;
+   &quot; more&quot;</pre>
 
-<h3><a name="nested">Nested Elements</a></h3>
+<h3 id="nested">Nested Elements</h3>
 
 <p>The <code>&lt;junit&gt;</code> task
 supports a nested <code>&lt;classpath&gt;</code>
@@ -353,23 +353,23 @@
 <p><em>since Ant 1.6</em>.</p>
 
 <h4>permissions</h4>
-<p>Security permissions can be revoked and granted during the execution of the 
+<p>Security permissions can be revoked and granted during the execution of the
 class via a nested <i>permissions</i> element. For more information please
 see <a href="../Types/permissions.html">permissions</a></p>
 
 <p>Settings will be ignored if fork is enabled.</p>
 
 <p><em>since Ant 1.6</em>.</p>
- 
+
 <h4>assertions</h4>
 
 <p>You can control enablement of Java 1.4 assertions with an
 <a href="../Types/assertions.html"><tt>&lt;assertions&gt;</tt></a>
 subelement.</p>
- 
+
 <p>Assertion statements are currently ignored in non-forked mode.</p>
 
-<p><em>since Ant 1.6.</em></p>
+<p><em>Since Ant 1.6</em>.</p>
 
 <h4>modulepath</h4>
 
@@ -407,14 +407,14 @@
 that your tests have written as some characters are illegal in XML
 documents and will be dropped.</p>
 
-<p>The fourth formatter named <code>failure</code> (since Ant 1.8.0) 
+<p>The fourth formatter named <code>failure</code> (<em>since Ant 1.8.0</em>)
 collects all failing <code>testXXX()</code>
 methods and creates a new <code>TestCase</code> which delegates only these
 failing methods. The name and the location can be specified via Java System property or Ant property
-<code>ant.junit.failureCollector</code>. The value has to point to the directory and 
+<code>ant.junit.failureCollector</code>. The value has to point to the directory and
 the name of the resulting class (without suffix). It defaults to <i>java-tmp-dir</i>/FailedTests.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -424,7 +424,7 @@
     <td valign="top">type</td>
     <td valign="top">Use a predefined formatter (either
       <code>xml</code>, <code>plain</code>, <code>brief</code> or <code>failure</code>).</td>
-    <td align="center" rowspan="2">Exactly one of these.</td>
+    <td align="center" rowspan="2">Exactly one of these</td>
   </tr>
   <tr>
     <td valign="top">classname</td>
@@ -450,14 +450,14 @@
     <td valign="top">unless</td>
     <td valign="top">Only use formatter <a href="../properties.html#if+unless">if the named property is <b>not</b> set</a>.</td>
     <td align="center">No; default is <code>true</code>.</td>
-  </tr>  
+  </tr>
 </table>
 
 <h4>test</h4>
 
 <p>Defines a single test class.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -487,7 +487,7 @@
       is specified, then no test method from the suite will be executed.</p>
     </td>
     <td align="center">No; default is to run all test methods in the suite.</td>
-  </tr>  
+  </tr>
   <tr>
     <td valign="top">fork</td>
     <td valign="top">Run the tests in a separate VM.
@@ -581,7 +581,7 @@
 prior to Ant 1.7 only <code>&lt;fileset&gt;</code> has been
 supported.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -664,7 +664,7 @@
   test's <code>tearDown</code> method will never be called.  The same
   is true if the forked VM crashes for some other reason.</p>
 
-<p>Starting with Ant 1.8.0, a special formatter is distributed with
+<p><em>Since Ant 1.8.0</em>, a special formatter is distributed with
   Ant that tries to load the testcase that was in the forked VM and
   invoke that class' <code>tearDown</code> method.  This formatter has
   the following limitations:</p>
@@ -697,8 +697,7 @@
 
 <p>to your <code>junit</code> task.</p>
 
-<h3><a name="enabletestlistenerevents"><code>ant.junit.enabletestlistenerevents</code></a>
-  magic property</h3>
+<h3 id="enabletestlistenerevents"><code>ant.junit.enabletestlistenerevents</code> magic property</h3>
 
 <p><em>Since Ant 1.8.2</em> the <code>enableTestListenerEvents</code>
   attribute of the task controls whether fine grained logging messages
@@ -760,7 +759,7 @@
 <p>Runs <code>my.test.TestCase</code> in the same VM, ignoring the
 given CLASSPATH; only a warning is printed if this test fails. In
 addition to the plain text test results, for this test a XML result
-will be output to <code>result.xml</code>.  
+will be output to <code>result.xml</code>.
 Then, for each matching file in the directory defined for
 <code>${src.tests}</code> a
 test is run in a separate VM. If a test fails, the build process is
@@ -776,7 +775,7 @@
     &lt;delete&gt;
         &lt;fileset dir=&quot;${collector.dir}&quot; includes=&quot;${collector.class}*.class&quot;/&gt;
     &lt;/delete&gt;
-    &lt;!-- compile the FailedTests class if present --&gt; 
+    &lt;!-- compile the FailedTests class if present --&gt;
     &lt;javac srcdir=&quot;${collector.dir}&quot; destdir=&quot;${collector.dir}&quot;/&gt;
     &lt;available file=&quot;${collector.dir}/${collector.class}.class&quot; property=&quot;hasFailingTests&quot;/&gt;
     &lt;junit haltonerror=&quot;false&quot; haltonfailure=&quot;false&quot;&gt;
@@ -802,8 +801,8 @@
 </pre>
 <p>On the first run all tests are collected via the <code>&lt;batchtest/&gt;</code>
 element. Its <code>plain</code> formatter shows the output on the console. The
-<code>failure</code> formatter creates a java source file in 
-<code>${build.dir}/failingTests/FailedTests.java</code> which extends 
+<code>failure</code> formatter creates a java source file in
+<code>${build.dir}/failingTests/FailedTests.java</code> which extends
 <code>junit.framework.TestCase</code> and returns from a <code>suite()</code>
 method a test suite for the failing tests. <br/>
 On a second run the collector class exists and instead of the <code>&lt;batchtest/&gt;</code>
diff --git a/manual/Tasks/junitreport.html b/manual/Tasks/junitreport.html
index fea85e5..71eb1a3 100644
--- a/manual/Tasks/junitreport.html
+++ b/manual/Tasks/junitreport.html
@@ -22,13 +22,13 @@
 
 <body>
 
-<h2><a name="junitreport">JUnitReport</a></h2>
+<h2 id="junitreport">JUnitReport</h2>
 <h3>Description</h3>
 Merge the individual XML files generated by the JUnit task and eventually apply
 a stylesheet on the resulting merged document to provide a browsable report of
 the testcases results.
 
-<p><strong>Note:</strong> This task depends on external libraries not
+<p><strong>Note</strong>: This task depends on external libraries not
 included in the Apache Ant distribution. See <a href="../install.html#librarydependencies">Library Dependencies</a>
 for more information.</p>
 
@@ -36,27 +36,27 @@
 
 <p>The task needs Apache <a
 href="http://xml.apache.org/xalan-j/">Xalan 2.4.1+ or Xalan XSLTC</a>
-(JDK 1.4 contains a version of Xalan-J 2.x while JDK 1.5 ships with a
-version of XSLTC). Starting from JDK 1.4.2-01 it ships with a bundled
-Xalan-J 2.4.1+, meaning that JDK version prior to 1.4.2-01 won't work
-out of the box. The table below summarize the compatibility status. 
+(JDK 1.4 contains a version of Xalan 2.x, while JDK 1.5 ships with a
+version of XSLTC). JDK 1.4.2-01 and later ships with a bundled
+Xalan 2.4.1+, meaning that JDKs prior to version 1.4.2-01 won't work
+out of the box. The table below summarize the compatibility status.
 </p>
-<table border="1" cellpadding="2" cellspacing="0">
-<tr><th>Xalan</th><th>Sun JDK Bundle</th><th>Status<th></tr> 
+<table>
+<tr><th>Xalan</th><th>Sun JDK Bundle</th><th>Status<th></tr>
 <tr><td>2.4.1+</td><td>JDK 1.4.2-01+</td><td>OK</td></tr>
 <tr><td>XSLTC</td><td>JDK 1.5.x</td><td>OK</td></tr>
 <tr><td>2.x</td><td>JDK 1.4.x</td><td>DEPRECATED<br><i>Use ${ant.home}/etc/junit-frames-xalan1.xsl
-<br> Upgrade Xalan using the JDK endorsement mechanism</i></td></tr>
+<br>Upgrade Xalan using the JDK endorsement mechanism</i></td></tr>
 </table>
 
-<p>With Ant 1.6.2 we had to decide between supporting Xalan-J 1/Xalan J 2.4.1-
-and Xalan 2.4.1+/XSLTC, since there was no way to support both couples at the same
+<p>In Ant 1.6.2, we had to decide between supporting Xalan 1/Xalan 2.4.1-
+and Xalan 2.4.1+/XSLTC, because there was no way to support both couples at the same
 time.</p>
-<p>With Ant 1.7 we had to drop support Xalan-J 1, since Xalan-J 1 has not 
+<p><em>Since Ant 1.7</em>, we dropped support for Xalan 1, because Xalan 1 was not
 available anymore for quite some time.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td width="12%" valign="top"><b>Attribute</b></td>
     <td width="78%" valign="top"><b>Description</b></td>
@@ -75,7 +75,7 @@
     <td align="center" valign="top">No. Default to current directory</td>
   </tr>
 </table>
-<h3><a name="nested">Nested Elements</a></h3>
+<h3 id="nested">Nested Elements</h3>
 <h4>fileset</h4>
 <p><code>junitreport</code> collects individual xml files generated by the JUnit
 task using the nested <a href="../Types/fileset.html"><code>&lt;FileSet&gt;</code></a>
@@ -83,7 +83,7 @@
 <h4>report</h4>
 <p>Generate a browsable report based on the document created by the merge.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td width="12%" valign="top"><b>Attribute</b></td>
     <td width="78%" valign="top"><b>Description</b></td>
@@ -113,7 +113,7 @@
     <td align="center" valign="top">No. Default to current directory</td>
   </tr>
 </table>
-<p> Ant assumes the following concerning the <tt>frames</tt> and <tt>noframes</tt> formats :</p>
+<p>Ant assumes the following concerning the <tt>frames</tt> and <tt>noframes</tt> formats:</p>
 <p>The <tt>frames</tt> format uses
 a stylesheet which is generating output <em>only</em> by redirecting.</p>
 <p>The
@@ -126,7 +126,7 @@
 <em>Since Ant 1.7</em>the report tag supports nested param tags.
 These tags can pass XSL parameters to the stylesheet.
 <h3>Parameters</h3>
-<table width="60%" border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -156,7 +156,7 @@
 </table>
 
 <p>The built-in stylesheets support the following parameters:</p>
-<table width="60%" border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>XSL-Parameter</b></td>
     <td valign="top"><b>Description</b></td>
@@ -170,12 +170,12 @@
 </table>
 
 <h4>classpath</h4>
-<p><em>Since Ant 1.9.5.</em>
+<p><em>Since Ant 1.9.5</em>.
 Like for the <a href="../CoreTasks/style.html#classpath">XSLT task</a>,
 a nested &lt;classpath&gt; will be used to load the processor.</p>
 
 <h4>factory</h4>
-<p><em>Since Ant 1.9.5.</em>
+<p><em>Since Ant 1.9.5</em>.
 Like for the <a href="../CoreTasks/style.html#factory">XSLT task</a>,
 a nested &lt;factory&gt; can be used to specify factory settings.</p>
 
@@ -212,5 +212,4 @@
     The XSL parameters key1 and key2 will be passed to the XSL transformation.</p>
 
 </body>
-
 </html>
diff --git a/manual/Tasks/length.html b/manual/Tasks/length.html
index 18c62c7..bf577ad 100644
--- a/manual/Tasks/length.html
+++ b/manual/Tasks/length.html
@@ -29,9 +29,9 @@
 <p>Display or set a property containing length information for
    a string, a file, or one or more nested
    <a href="../Types/resources.html#collection">Resource Collection</a>s.
-   Can also be used as a condition. <b>Since Apache Ant 1.6.3</b></p>
+   Can also be used as a condition. <em>Since Apache Ant 1.6.3</em></p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -111,7 +111,7 @@
     &lt;fileset dir=&quot;.&quot; includes=&quot;foo,bar&quot;/&gt;
 &lt;/length&gt;
 </pre>
-<p>Writes the file paths of <i>foo</i> and <i>bar</i> and their length into 
+<p>Writes the file paths of <i>foo</i> and <i>bar</i> and their length into
 the property <i>length</i>.</p>
 
 <pre>
@@ -121,7 +121,5 @@
 </pre>
 <p>Adds the length of <i>foo</i> and <i>bar</i> and stores the result in property <i>length</i>.</p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/loadfile.html b/manual/Tasks/loadfile.html
index 59291ed..b62abdd 100644
--- a/manual/Tasks/loadfile.html
+++ b/manual/Tasks/loadfile.html
@@ -23,7 +23,7 @@
 <body>
 
 
-<h2><a name="loadfile">LoadFile</a></h2>
+<h2 id="loadfile">LoadFile</h2>
 <h3>Description</h3>
 <p>
 Specialization of <a href="loadresource.html">loadresource</a> that
@@ -31,12 +31,12 @@
 convenience.  Unless an encoding is specified, the encoding of the
 current locale is used.
 </p>
-<p>If the resource content is empty (maybe after processing a filterchain) 
+<p>If the resource content is empty (maybe after processing a filterchain)
 the property is not set.</p>
 
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -64,11 +64,11 @@
   </tr>
   <tr>
     <td valign="top">quiet</td>
-    <td valign="top">Do not display a diagnostic message (unless Apache Ant has been 
+    <td valign="top">Do not display a diagnostic message (unless Apache Ant has been
     invoked with the <code>-verbose</code> or <code>-debug</code>
-    switches) or modify the exit status to reflect an error. Setting this to 
+    switches) or modify the exit status to reflect an error. Setting this to
     "true" implies setting failonerror to "false".
-      <em>Since Ant 1.7.0.</em>
+      <em>Since Ant 1.7.0</em>.
     </td>
     <td align="center" valign="top">No, default "false"</td>
   </tr>
@@ -88,7 +88,6 @@
        &lt;file file="message.txt"/&gt;
     &lt;/loadresource&gt;
 </pre>
-</p>
 
 <pre>    &lt;loadfile property="encoded-file"
       srcFile="loadfile.xml"
@@ -125,9 +124,5 @@
 Load an XML file into a property, expanding all properties declared
 in the file in the process.
 
-
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/loadproperties.html b/manual/Tasks/loadproperties.html
index 69fa23a..a3a2479 100644
--- a/manual/Tasks/loadproperties.html
+++ b/manual/Tasks/loadproperties.html
@@ -23,7 +23,7 @@
 <body>
 
 
-<h2><a name="loadproperties">LoadProperties</a></h2>
+<h2 id="loadproperties">LoadProperties</h2>
 <h3>Description</h3>
 <p>
 Load a file's contents as Apache Ant properties.  This is equivalent
@@ -33,14 +33,14 @@
 than a warning being printed.
 </p>
 
-<p><strong>Note:</strong> the default value of this
+<p><strong>Note</strong>: the default value of this
 task's <code>prefixValues</code> attribute is different from the
 default value of the same attribute in
 the <a href="property.html"><code>&lt;property&gt;</code></a>
 task.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -134,7 +134,5 @@
 Load contents of http://example.org/url.properties.gz, uncompress it
 on the fly and load the contents as Ant properties.
 
-
-
 </body>
 </html>
diff --git a/manual/Tasks/loadresource.html b/manual/Tasks/loadresource.html
index f2b20c0..0e4ad77 100644
--- a/manual/Tasks/loadresource.html
+++ b/manual/Tasks/loadresource.html
@@ -23,7 +23,7 @@
 <body>
 
 
-<h2><a name="loadresource">LoadResource</a></h2>
+<h2 id="loadresource">LoadResource</h2>
 
 <p><em>Since Apache Ant 1.7</em></p>
 
@@ -41,7 +41,7 @@
   of an existing property.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -64,9 +64,9 @@
   </tr>
   <tr>
     <td valign="top">quiet</td>
-    <td valign="top">Do not display a diagnostic message (unless Ant has been 
+    <td valign="top">Do not display a diagnostic message (unless Ant has been
     invoked with the <code>-verbose</code> or <code>-debug</code>
-    switches) or modify the exit status to reflect an error. Setting this to 
+    switches) or modify the exit status to reflect an error. Setting this to
     "true" implies setting failonerror to "false".
     </td>
     <td align="center" valign="top">No, default "false"</td>
@@ -87,7 +87,5 @@
 
 <p>For more examples see the <a href="loadfile.html">loadfile</a> task.</p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/local.html b/manual/Tasks/local.html
index c7ed8fc..cc1f648 100644
--- a/manual/Tasks/local.html
+++ b/manual/Tasks/local.html
@@ -34,13 +34,13 @@
 including the global scope. Note that using the Local task at the global
 level effectively makes the property local to the "anonymous target" in which
 top-level operations are carried out; it will not be defined for other targets
-in the buildfile. <b>Since Ant 1.8</b></p>
+in the buildfile. <em>Since Ant 1.8</em></p>
 
 <p>A property is made local if the <code>&lt;local&gt;</code> task
   precedes its definition.  See the examples section.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0"> 
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -183,4 +183,3 @@
 
 </body>
 </html>
-
diff --git a/manual/Tasks/macrodef.html b/manual/Tasks/macrodef.html
index 60b3072..dd816d0 100644
--- a/manual/Tasks/macrodef.html
+++ b/manual/Tasks/macrodef.html
@@ -17,14 +17,14 @@
 <html>
 
   <head>
-    <meta http-equiv="Content-Language" content="en-us"></meta>
+    <meta http-equiv="Content-Language" content="en-us">
     <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
     <title>MacroDef Task</title>
   </head>
 
   <body>
 
-    <h2><a name="macrodef">MacroDef</a></h2>
+    <h2 id="macrodef">MacroDef</h2>
     <h3>Description</h3>
     <p>
       This defines a new task using a <code>&lt;sequential&gt;</code>
@@ -42,7 +42,7 @@
       <em>since Apache Ant 1.6</em>
     </p>
     <h3>Parameters</h3>
-    <table border="1" cellpadding="2" cellspacing="0">
+    <table>
       <tr>
         <td valign="top"><b>Attribute</b></td>
         <td valign="top"><b>Description</b></td>
@@ -88,7 +88,7 @@
     </p>
     <p>
       This attribute is placed in the body of the templated
-      task using a notation similar to the ant property notation
+      task using a notation similar to the Ant property notation
       - @{attribute name}. (May be remembered as "put the substitution
       AT this location").
     </p>
@@ -102,7 +102,7 @@
       same as @{MyAttribute}.
     </p>
     <h3>Parameters</h3>
-    <table border="1" cellpadding="2" cellspacing="0">
+    <table>
       <tr>
         <td valign="top"><b>Attribute</b></td>
         <td valign="top"><b>Description</b></td>
@@ -124,7 +124,7 @@
         <td valign="top">description</td>
         <td valign="top">
           This contains a description of the attribute.
-          <em>since ant 1.6.1</em>
+          <em>Since Ant 1.6.1</em>
         </td>
         <td valign="top" align="center">No</td>
       </tr>
@@ -133,7 +133,7 @@
         <td valign="top">
           Controls whether or not property references in the attribute are expanded twice or just once.
           See the <a href="http://ant.apache.org/faq.html#macrodef-property-expansion">FAQ</a> for details.
-          <em>since Ant 1.8.3</em>
+          <em>Since Ant 1.8.3</em>
         </td>
         <td valign="top" align="center">No; default true</td>
       </tr>
@@ -148,7 +148,7 @@
       The case of the element name is ignored.
     </p>
     <h3>Parameters</h3>
-    <table border="1" cellpadding="2" cellspacing="0">
+    <table>
       <tr>
         <td valign="top"><b>Attribute</b></td>
         <td valign="top"><b>Description</b></td>
@@ -175,7 +175,7 @@
           any nested elements of the macrodef instance will be placed
           in the element indicated by the name of this element.
           There can only be one element if an element is implicit.
-          The default value is false. <em>since ant 1.6.2</em>
+          The default value is false. <em>Since Ant 1.6.2</em>
         </td>
         <td valign="top" align="center">No</td>
       </tr>
@@ -184,7 +184,7 @@
         <td valign="top">
           This contains a description
           informing the user what the contents of the element are expected to be.
-          <em>since ant 1.6.1</em>
+          <em>Since Ant 1.6.1</em>
         </td>
         <td valign="top" align="center">No</td>
       </tr>
@@ -195,13 +195,13 @@
       If this element is not present, then any nested text in the macro invocation
       will be an error. If the text element is present, then the name
       becomes an attribute that gets set to the nested text of the macro invocation.
-      <em>Since ant 1.6.1.</em>
+      <em>Since Ant 1.6.1</em>.
     </p>
     <p>
       The case of the text name is ignored.
     </p>
     <h3>Parameters</h3>
-    <table border="1" cellpadding="2" cellspacing="0">
+    <table>
       <tr>
         <td valign="top"><b>Attribute</b></td>
         <td valign="top"><b>Description</b></td>
@@ -380,6 +380,5 @@
 </pre>
     </blockquote>
 
-
 </body>
 </html>
diff --git a/manual/Tasks/mail.html b/manual/Tasks/mail.html
index b59633d..0edc15a 100644
--- a/manual/Tasks/mail.html
+++ b/manual/Tasks/mail.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="mail">Mail</a></h2>
+<h2 id="mail">Mail</h2>
 <h3>Description</h3>
   <p>
     A task to send SMTP email.
@@ -48,14 +48,14 @@
     <code>&lt;attachments&gt;</code> container.
   </p>
   <p>
-    <strong>Note:</strong> This task may depend on external libraries
-    that are not included in the Ant distribution. 
+    <strong>Note</strong>: This task may depend on external libraries
+    that are not included in the Ant distribution.
     See <a href="../install.html#librarydependencies">Library Dependencies</a>
     for more information.
   </p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -76,7 +76,7 @@
     <td valign="top">tolist</td>
     <td valign="top">Comma-separated list of recipients.</td>
     <td align="center" valign="middle" rowspan="3">At least one of these, or the
-       equivalent elements.</td>
+       equivalent nested elements</td>
   </tr>
   <tr>
     <td valign="top">cclist</td>
@@ -149,18 +149,18 @@
   <tr>
     <td valign="top">user</td>
     <td valign="top">user name for SMTP auth</td>
-    <td valign="center">Yes, if SMTP auth is required on your SMTP server<br></br>
+    <td valign="center">Yes, if SMTP auth is required on your SMTP server<br>
     the email message will be then sent using Mime and requires JavaMail</td>
   </tr>
   <tr>
     <td valign="top">password</td>
     <td valign="top">password for SMTP auth</td>
-    <td valign="center">Yes, if SMTP auth is required on your SMTP server<br></br>
+    <td valign="center">Yes, if SMTP auth is required on your SMTP server<br>
     the email message will be then sent using Mime and requires JavaMail</td>
   </tr>
   <tr>
     <td valign="top">ssl</td>
-    <td valign="top">"true", "on" or "yes" accepted here<br></br>
+    <td valign="top">"true", "on" or "yes" accepted here<br>
     indicates whether you need TLS/SSL</td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -193,7 +193,7 @@
   </tr>
   <tr>
     <td valign="top">enableStartTLS</td>
-    <td valign="top">"true", "on" or "yes" accepted here<br></br>
+    <td valign="top">"true", "on" or "yes" accepted here<br>
       whether the STARTTLS command used to switch to an encrypted
       connection for authentication should be supported.  Requires
       JavaMail.  <em>Since Ant 1.8.0</em></td>
@@ -216,10 +216,10 @@
 
 <h3>Parameters specified as nested elements</h3>
 
-<h4>to / cc / bcc / from/ replyto </h4>
+<h4>to / cc / bcc / from/ replyto</h4>
 <p>Adds an email address element.  It takes the following attributes:</p>
 
-<table width="60%" border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -242,7 +242,7 @@
 <p>Specifies the message to include in the email body.  It takes the following
 attributes:</p>
 
-<table width="60%" border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -284,10 +284,10 @@
 the <code>&lt;message&gt;</code> element.</p>
 
 <h4>header</h4>
-<p><strong>Since Ant 1.7</strong>, arbitrary mail headers can be added by
+<p><em>Since Ant 1.7</em>, arbitrary mail headers can be added by
   specifying these attributes on one or more nested header elements:</p>
 
-<table width="60%" border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -305,8 +305,7 @@
   </tr>
 </table>
 
-<p>It is permissible to duplicate the name attribute amongst multiple headers.
-</p>
+<p>It is permissible to duplicate the name attribute amongst multiple headers.</p>
 
 <h3>Examples</h3>
 
@@ -356,7 +355,5 @@
 <p>Sends an eMail from <i>me@myisp.com</i> to <i>all@xyz.com</i> with a subject of
 <i>Test Build</i>, the message body being coded in UTF-8
 
-
-
 </body>
 </html>
diff --git a/manual/Tasks/makeurl.html b/manual/Tasks/makeurl.html
index b20f94a..f00b17b 100644
--- a/manual/Tasks/makeurl.html
+++ b/manual/Tasks/makeurl.html
@@ -14,55 +14,21 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-    
+
 <html>
 <head>
   <meta http-equiv="Content-Language" content="en-us">
+  <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
   <title>Makeurl Task</title>
 </head>
 
-<body bgcolor="#ffffff" text="#000000" link="#525D76"
-      alink="#525D76" vlink="#525D76">
+<body>
 
-<table border="0" width="100%" cellspacing="4">
-
-  <!-- PAGE HEADER -->
-  <tr>
-    <td>
-      <table border="0" width="100%"><tr>
-          <td valign="bottom">
-            <font size="+3" face="arial,helvetica,sanserif"><strong>Makeurl Task</strong></font>
-          </td>
-          <td>
-            <!-- PROJECT LOGO -->
-            <a href="http://ant.apache.org/">
-              <img src="../images/ant_logo_large.gif" align="right" alt="Apache Ant" border="0"/>
-            </a>
-          </td>
-      </tr></table>
-    </td>
-  </tr>
-
-  <!-- START RIGHT SIDE MAIN BODY -->
-  <tr>
-    <td  valign="top" align="left">
-
-          <!-- Applying task/long-description -->
-    <!-- Start Description -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-
-      <tr><td bgcolor="#525D76">
-        <font color="#ffffff" face="arial,helvetica.sanserif">
-          <a name="description">
-          <strong>Description</strong></a></font>
-      </td></tr>
-
-      <tr><td><blockquote>
+<h2>Makeurl Task</h2>
+<h3 id="description">Description</h3>
 This task takes one or more filenames and turns them into URLs, which it then assigns to a property.
 Useful when setting up RMI or JNLP codebases, for example.
 Nested filesets are supported; if present, these are turned into the URLs with the supplied separator between them (default: space).
-<p/>
 <p>Examples:</p>
 <pre>
 &lt;makeurl file="${user.home}/.m2/repository" property="m2.repository.url"/&gt;
@@ -72,163 +38,86 @@
 &lt;makeurl property="codebase"&gt;&lt;fileset dir="lib includes="*.jar"/&gt;&lt;/makeurl&gt;
 </pre>
 Set the property <code>codebase</code> to the three URLs of the files provided as nested elements.
-      </blockquote></td></tr>
-
-    </table>
-    <!-- End Description -->
-
- <!-- Ignore -->
-
-
-
-    <!-- Start Attributes -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#525D76">
-        <font color="#ffffff" face="arial,helvetica.sanserif">
-          <a name="attributes">
-          <strong>Parameters</strong></a></font>
-      </td></tr>
-      <tr><td><blockquote>
-        <table>
-          <tr>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Attribute</b></font>
-        </td>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Description</b></font>
-        </td>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Type</b></font>
-        </td>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Requirement</b></font>
-        </td>
-          </tr>
-    <!-- Attribute Group -->    
-    
-    <!-- Attribute Group -->    
-        <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">file</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">name of a file to be converted into a URL</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">File</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">optional, if a nested fileset or path is supplied</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">property</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">name of a property to set to the URL</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">required</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">separator</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">separator for the multi-URL option</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">optional</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">validate</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">validate that every named file exists</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">optional; default: true</font>
-        </td>
-    </tr>
-
-
-        </table>
-      </blockquote></td></tr>
-
-    </table>
-    <!-- End Attributes -->
-
-    <!-- Start Elements -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-
-      <tr><td bgcolor="#525D76">
-        <font color="#ffffff" face="arial,helvetica.sanserif">
-          <a name="elements">
-          <strong>Parameters as nested elements</strong></a></font>
-      </td></tr>
-
-      <tr><td><blockquote>
-    <!-- Start Element -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#828DA6">
-        <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
-          <strong>fileset</strong> (org.apache.tools.ant.types.FileSet)</font>
-      </td></tr>
-      <tr><td><blockquote>
-        A fileset of JAR files to include in the URL list, each separated by the separator.
- <!-- Ignore -->
- <!-- Ignore -->
-
-      </blockquote></td></tr>
-    </table>
-    <!-- End Element -->
-    <!-- Start Element -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#828DA6">
-        <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
-          <strong>path</strong> (org.apache.tools.ant.types.Path)</font>
-      </td></tr>
-      <tr><td><blockquote>
-        Add a path to the URL. All elements in the path will be converted to individual URL entries.
- <!-- Ignore -->
- <!-- Ignore -->
-
-      </blockquote></td></tr>
-    </table>
-    <!-- End Element -->
-
-      </blockquote></td></tr>
-
-    </table>
-    <!-- End Elements -->
-
-
+<h3 id="attributes">Parameters</h3>
+<table>
+  <tr>
+    <td valign="top" align="left">
+      <b>Attribute</b>
+    </td>
+    <td valign="top" align="left">
+      <b>Description</b>
+    </td>
+    <td valign="top" align="left">
+      <b>Type</b>
+    </td>
+    <td valign="top" align="left">
+      <b>Requirement</b>
     </td>
   </tr>
-  <!-- END RIGHT SIDE MAIN BODY -->
-
+  <tr>
+    <td valign="top" align="left">
+      file
+    </td>
+    <td valign="top" align="left">
+      name of a file to be converted into a URL
+    </td>
+    <td valign="top" align="left">
+      File
+    </td>
+    <td valign="top" align="left">
+      optional, if a nested fileset or path is supplied
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      property
+    </td>
+    <td valign="top" align="left">
+      name of a property to set to the URL
+    </td>
+    <td valign="top" align="left">
+      String
+    </td>
+    <td valign="top" align="left">
+      required
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      separator
+    </td>
+    <td valign="top" align="left">
+      separator for the multi-URL option
+    </td>
+    <td valign="top" align="left">
+      String
+    </td>
+    <td valign="top" align="left">
+      optional
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      validate
+    </td>
+    <td valign="top" align="left">
+      validate that every named file exists
+    </td>
+    <td valign="top" align="left">
+      boolean
+    </td>
+    <td valign="top" align="left">
+      optional; default: true
+    </td>
+  </tr>
 </table>
+<h3 id="elements">Parameters as nested elements</h3>
+<h4><strong>fileset</strong> (org.apache.tools.ant.types.FileSet)</h4>
 
+A fileset of JAR files to include in the URL list, each separated by the separator.
+
+<h4><strong>path</strong> (org.apache.tools.ant.types.Path)</h4>
+
+Add a path to the URL. All elements in the path will be converted to individual URL entries.
 </body>
 </html>
diff --git a/manual/Tasks/manifest.html b/manual/Tasks/manifest.html
index 7a5b98b..208503b 100644
--- a/manual/Tasks/manifest.html
+++ b/manual/Tasks/manifest.html
@@ -24,16 +24,14 @@
 
 <body>
 
-<h2><a name="manifest">Manifest</a></h2>
+<h2 id="manifest">Manifest</h2>
 <h3>Description</h3>
 <p>Creates a manifest file.</p>
 
 <p>This task can be used to write a Manifest file, optionally
 replacing or updating an existing file.</p>
 
-
-
-<p>Manifests are processed according to the 
+<p>Manifests are processed according to the
 <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html">Jar
 file specification.</a>. Specifically, a manifest element consists of
 a set of attributes and sections. These sections in turn may contain
@@ -52,14 +50,14 @@
 
 <p>
   If you find that Ant generates manifests incompatible with your runtime, take
-  a manifest it has built, fix it up however you need and switch to using the &lt;zip&gt
+  a manifest it has built, fix it up however you need and switch to using the <a href="zip.html">zip</a>
   task to create the JAR, feeding in the hand-crafted manifest.
 </p>
 
 
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -88,7 +86,7 @@
       in different manifests (if updating).  If false, only the
       attribute of the most recent manifest will be preserved.
       <em>Since Ant 1.8.0</em>.
-      <br/>unless you also set flattenAttributes to true this may
+      <br/>Unless you also set flattenAttributes to true this may
       result in manifests containing multiple Class-Path attributes
       which violates the manifest specification.</td>
     <td align="center" valign="top">No, default is false</td>
@@ -104,10 +102,10 @@
 </table>
 
 <h3>Nested elements</h3>
-<h4><a name="attribute">attribute</a></h4>
+<h4 id="attribute">attribute</h4>
 <p>One attribute for the manifest file.  Those attributes that are
 not nested into a section will be added to the "Main" section.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -132,7 +130,7 @@
 <p>A manifest section - you can nest <a
 href="#attribute">attribute</a> elements into sections.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -156,7 +154,7 @@
       &lt;attribute name=&quot;Specification-Version&quot; value=&quot;${version}&quot;/&gt;
       &lt;attribute name=&quot;Specification-Vendor&quot; value=&quot;Example Organization&quot;/&gt;
       &lt;attribute name=&quot;Implementation-Title&quot; value=&quot;common&quot;/&gt;
-      &lt;attribute name=&quot;Implementation-Version&quot; value=&quot;${version} ${TODAY}&quot;/&gt; 
+      &lt;attribute name=&quot;Implementation-Version&quot; value=&quot;${version} ${TODAY}&quot;/&gt;
       &lt;attribute name=&quot;Implementation-Vendor&quot; value=&quot;Example Corp.&quot;/&gt;
     &lt;/section&gt;
     &lt;section name=&quot;common/class1.class&quot;&gt;
@@ -168,7 +166,7 @@
 <p>Creates or replaces the file MANIFEST.MF.  Note that the Built-By
 attribute will take the value of the Ant property ${user.name}.  The
 same is true for the ${version} and ${TODAY} properties.  This example
-produces a MANIFEST.MF that contains 
+produces a MANIFEST.MF that contains
 <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/versioning/spec/versioning2.html#wp90779">package
 version identification</a> for the package <code>common</code>.</p>
 
@@ -191,7 +189,5 @@
 
 </code></pre>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/manifestclasspath.html b/manual/Tasks/manifestclasspath.html
index 2c193b8..c19fb5d 100644
--- a/manual/Tasks/manifestclasspath.html
+++ b/manual/Tasks/manifestclasspath.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="manifestclasspath">Manifestclasspath</a></h2>
+<h2 id="manifestclasspath">Manifestclasspath</h2>
 
 <h3>Description</h3>
 <p>Converts a <a href="../using.html#path">Path</a> into a property
@@ -37,7 +37,7 @@
 empty) jar file which an in-manifest Class-Path attribute whose value lists
 all the jar and zip files the class path should contain. The files referenced
 from this attribute must be found relatively to the jar file itself, usually
-in the same directory. The Java VM automically uses all file entries listed
+in the same directory. The Java VM automatically uses all file entries listed
 in the Class-Path attributes of a jar to locate/load classes. Note though that
 it silently ignores entries for which it cannot find any corresponding file.</p>
 
@@ -54,7 +54,7 @@
 <p><em>since Apache Ant 1.7</em></p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -105,13 +105,11 @@
   </pre></blockquote>
   <p>Assuming a path of id "classpath" was already defined, convert this
   path relatively to the build/ directory that will contain acme.jar, which
-  can later be created with <code>&lt;jar&gt;</code> with a nested 
+  can later be created with <code>&lt;jar&gt;</code> with a nested
   <code>&lt;manifest&gt;</code> element that lists an
-  <code>&lt;attribute name="Class-Path" value="${jar.classpath}" /&gt;</code>.
+  <code>&lt;attribute name="Class-Path" value="${jar.classpath}"/&gt;</code>.
   </p>
 </div>
 
-
-
 </body>
 </html>
diff --git a/manual/Tasks/mimemail.html b/manual/Tasks/mimemail.html
index ba066a6..44b0e8b 100644
--- a/manual/Tasks/mimemail.html
+++ b/manual/Tasks/mimemail.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="mimemail">MimeMail</a></h2>
+<h2 id="mimemail">MimeMail</h2>
 
 <h3><i>Deprecated</i></h3>
 <p><i>This task has been deprecated.  Use the <a href="../Tasks/mail.html">mail</a> task instead.</i></p>
@@ -36,7 +36,7 @@
 Activation Framework</a> are required for this task.</p>
 <p>Multiple files can be attached using <a href="../Types/fileset.html">FileSets.</a></p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -45,9 +45,7 @@
   <tr>
     <td valign="top">message</td>
     <td valign="top">The message body</td>
-    <td valign="top" align="center" rowspan="2">No, but only one of of 'message' or
-      'messageFile' may be specified.&nbsp; If not specified, a fileset must be
-      provided.</td>
+    <td valign="top" align="center" rowspan="2">Exactly one of these, or a nested fileset</td>
   </tr>
   <tr>
     <td valign="top">messageFile</td>
@@ -62,18 +60,15 @@
   <tr>
     <td valign="top">tolist</td>
     <td valign="top">Comma-separated list of To: recipients</td>
-    <td valign="top" align="center" rowspan="3">Yes, at least one of 'tolist', 'cclist',
-      or 'bcclist' must be specified.</td>
+    <td valign="top" align="center" rowspan="3">Yes, at least one of these</td>
   </tr>
   <tr>
     <td valign="top">cclist</td>
     <td valign="top">Comma-separated list of CC: recipients</td>
-    <td valign="top" align="center">&nbsp;</td>
   </tr>
   <tr>
     <td valign="top">bcclist</td>
     <td valign="top">Comma-separated list of BCC: recipients</td>
-    <td valign="top" align="center">&nbsp;</td>
   </tr>
   <tr>
     <td valign="top">mailhost</td>
@@ -109,7 +104,5 @@
     &lt;/mimemail&gt;
 </pre>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/mkdir.html b/manual/Tasks/mkdir.html
index 5d945c0..5de1899 100644
--- a/manual/Tasks/mkdir.html
+++ b/manual/Tasks/mkdir.html
@@ -24,12 +24,12 @@
 
 <body>
 
-<h2><a name="mkdir">Mkdir</a></h2>
+<h2 id="mkdir">Mkdir</h2>
 <h3>Description</h3>
 <p>Creates a directory. Also non-existent parent directories are created, when
 necessary. Does nothing if the directory already exist.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -47,6 +47,5 @@
 <pre>&lt;mkdir dir=&quot;${dist}/lib&quot;/&gt;</pre>
 <p>creates a directory <code>${dist}/lib</code>.</p>
 
-
 </body>
 </html>
diff --git a/manual/Tasks/move.html b/manual/Tasks/move.html
index c4f931a..9e40d8e 100644
--- a/manual/Tasks/move.html
+++ b/manual/Tasks/move.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="move">Move</a></h2>
+<h2 id="move">Move</h2>
 <h3>Description</h3>
 <p>Moves a file to a new file or directory, or collections of files to
 a new directory.  By default, the
@@ -42,12 +42,12 @@
 To use a resource collection, the <code>todir</code> attribute must be
 set.</p>
 
-<p><b>Since Ant 1.6.3</b>, the <i>file</i> attribute may be used to move
+<p><em>Since Ant 1.6.3</em>, the <i>file</i> attribute may be used to move
 (rename) an entire directory.  If <i>tofile</i> denotes an existing file, or
 there is a directory by the same name in <i>todir</i>, the action will fail.
 </p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -63,7 +63,7 @@
     <td valign="top">preservelastmodified</td>
     <td valign="top">Give the moved files the same last modified
       time as the original source files.
-      (<em>Note</em>: Ignored on Java 1.1)</td>
+      (<strong>Note</strong>: Ignored on Java 1.1)</td>
     <td valign="top" align="center">No; defaults to false.</td>
   </tr>
   <tr>
@@ -252,7 +252,5 @@
   &lt;/move&gt;
 </pre>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/native2ascii.html b/manual/Tasks/native2ascii.html
index ecc065a..8a43e08 100644
--- a/manual/Tasks/native2ascii.html
+++ b/manual/Tasks/native2ascii.html
@@ -15,8 +15,10 @@
    limitations under the License.
 -->
 <html>
-  <head><link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
-<title>Native2Ascii Task</title></head>
+  <head>
+    <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+    <title>Native2Ascii Task</title>
+  </head>
   <body>
     <h2>Native2Ascii</h2>
 
@@ -57,21 +59,22 @@
       and <code>&lt;patternset&gt;</code> elements.
     </p>
 
-    <p>It is possible to use different converters. This can be selected
-      with the <code>implementation</code> attribute or a nested element.
-      <a name="implementationvalues">Here are the choices of the attribute</a>:</p>
+    <p id="implementationvalues">
+      It is possible to use different converters. This can be selected
+      with the <code>implementation</code> attribute or a nested
+      element. Here are the choices of the attribute:
+    </p>
     <ul>
-      <li>default - the default converter for the platform - kaffee
-        when run on Kaffee, builtin if JDK9 or newer is detected, sun
-        otherwise.</li>
-      <li>sun (the standard converter of the JDK < 9)</li>
-      <li>kaffe (the standard converter
-        of <a href="http://www.kaffe.org" target="_top">Kaffe</a>)</li>
-      <li>builtin - Ant's internal implementation used for
-        JDK9+. <em>since ant 1.9.8</em></li>
+      <li>default - the default converter for the platform: kaffe
+        when run on Kaffe, builtin otherwise.</li>
+      <li>sun - used to be the standard converter of the JDK &lt; 9</li>
+      <li>kaffe - the standard converter
+        of <a href="http://www.kaffe.org" target="_top">Kaffe</a></li>
+      <li>builtin - Ant's internal implementation. <em>Since Ant
+          1.9.8</em></li>
     </ul>
 
-    <table border="1" cellpadding="2" cellspacing="0">
+    <table>
       <tr>
         <td><b>Attribute</b></td>
         <td><b>Description</b></td>
@@ -157,7 +160,7 @@
 but have an additional attribute that can be used to enable arguments
 only if a given converter implementation will be used.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -167,7 +170,7 @@
     <td valign="top">value</td>
     <td align="center" rowspan="4">See
     <a href="../using.html#arg">Command-line Arguments</a>.</td>
-    <td align="center" rowspan="4">Exactly one of these.</td>
+    <td align="center" rowspan="4">Exactly one of these</td>
   </tr>
   <tr>
     <td valign="top">line</td>
@@ -188,7 +191,7 @@
   </tr>
 </table>
 
-<h4>implementationclasspath <em>since Apache Ant 1.8.0</em></h4>
+<h4>implementationclasspath (<em>since Apache Ant 1.8.0</em>)</h4>
 
 <p>A <a href="../using.html#path">PATH like structure</a> holding the
   classpath to use when loading the converter implementation if a
@@ -196,7 +199,7 @@
   using one of the built-in converters.</p>
 
 <h4>Any nested element of a type that implements Native2AsciiAdapter
-  <em>since Ant 1.8.0</em></h4>
+  (<em>since Ant 1.8.0</em>)</h4>
 
 <p>If a defined type implements the <code>Native2AsciiAdapter</code>
   interface a nested element of that type can be used as an
@@ -246,6 +249,6 @@
 </pre>
 <p>in which case your native2ascii adapter can support attributes and
   nested elements of its own.</p>
-  </body>
 
+</body>
 </html>
diff --git a/manual/Tasks/netrexxc.html b/manual/Tasks/netrexxc.html
index efdfa4d..6231aa9 100644
--- a/manual/Tasks/netrexxc.html
+++ b/manual/Tasks/netrexxc.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="netrexxc">NetRexxC</a></h2>
+<h2 id="netrexxc">NetRexxC</h2>
 <h3>Description</h3>
 <p>Compiles a <a href="http://www2.hursley.ibm.com/netrexx" target="_top">NetRexx</a>
 source tree within the running (Apache Ant) VM.</p>
@@ -58,12 +58,12 @@
 or from the command line as<br>
 <code>ant -Dant.netrexxc.verbose=noverbose ...</code>
 </p>
-<p><strong>Note:</strong> This task depends on external libraries not
+<p><strong>Note</strong>: This task depends on external libraries not
 included in the Apache Ant distribution. See <a href="../install.html#librarydependencies">Library Dependencies</a>
 for more information.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -335,7 +335,5 @@
   </p>
 </blockquote>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/nice.html b/manual/Tasks/nice.html
index 03c0eaa..c3e1156 100644
--- a/manual/Tasks/nice.html
+++ b/manual/Tasks/nice.html
@@ -24,12 +24,12 @@
 
 <body>
 
-<h2><a name="echo">Nice</a></h2>
+<h2 id="echo">Nice</h2>
 <h3>Description</h3>
 <p>Provide "nice-ness" to the current thread
    and/or query the current value.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -64,7 +64,5 @@
 can be used to set the priority back to its original value later.
 </p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/pack.html b/manual/Tasks/pack.html
index 60ae1e5..3ecebca 100644
--- a/manual/Tasks/pack.html
+++ b/manual/Tasks/pack.html
@@ -19,18 +19,24 @@
 <head>
 <meta http-equiv="Content-Language" content="en-us">
 <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
-<title>GZip/BZip2 Tasks</title>
+<title>GZip/BZip2/XZ Tasks</title>
 </head>
 
 <body>
 
-<h2><a name="pack">GZip/BZip2</a></h2>
+<h2 id="pack">GZip/BZip2/XZ</h2>
 <h3>Description</h3>
-<p>Packs a resource using the GZip or BZip2 algorithm.
+<p>Packs a resource using the GZip, BZip2 or XZ algorithm.
 The output file is only generated if it doesn't exist or the source
 resource is newer.</p>
+
+<p>XZ compression support has been added with Apache Ant 1.10.1 and
+depends on external libraries not included in the Ant distribution.
+See <a href="../install.html#librarydependencies">Library
+Dependencies</a> for more information.</p>
+
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -38,13 +44,13 @@
   </tr>
   <tr>
     <td valign="top">src</td>
-    <td valign="top">the file to gzip/bzip.</td>
+    <td valign="top">the file to gzip/bzip/xz.</td>
     <td align="center" valign="top">Yes, or a nested resource collection.</td>
   </tr>
   <tr>
     <td valign="top">destfile</td>
     <td valign="top">the destination file to create.</td>
-    <td align="center" valign="top" rowspan="2">Exactly one of the two.</td>
+    <td align="center" valign="top" rowspan="2">Exactly one of the two</td>
   </tr>
   <tr>
     <td valign="top">zipfile</td>
@@ -64,6 +70,9 @@
 &lt;bzip2 src=&quot;test.tar&quot; destfile=&quot;test.tar.bz2&quot;/&gt;
 </pre></blockquote>
 <blockquote><pre>
+&lt;xz src=&quot;test.tar&quot; destfile=&quot;test.tar.xz&quot;/&gt;
+</pre></blockquote>
+<blockquote><pre>
 &lt;gzip destfile=&quot;archive.tar.gz&quot;&gt;
   &lt;url url="http://example.org/archive.tar"/&gt;
 &lt;/gzip&gt;
@@ -71,6 +80,5 @@
 <p>downloads <i>http://example.org/archive.tar</i> and compresses it
 to <i>archive.tar.gz</i> in the project's basedir on the fly.</p>
 
-
 </body>
 </html>
diff --git a/manual/Tasks/parallel.html b/manual/Tasks/parallel.html
index 362daf3..5f272c0 100644
--- a/manual/Tasks/parallel.html
+++ b/manual/Tasks/parallel.html
@@ -28,12 +28,12 @@
 <h3>Description</h3>
 <p>
     Executes nested tasks in parallel with no guarantees of thread safety.
-    Every task will run in its own thread, with the likelihood of 
+    Every task will run in its own thread, with the likelihood of
     concurrency problems scaling with the number of CPUs on the host system.
 </p>
-<p><b>Warning:</b> While the Apache Ant core is believed to be thread safe, no such 
+<p><b>Warning:</b> While the Apache Ant core is believed to be thread safe, no such
     guarantees are made about tasks, which are not tested for thread safety during
-    Ant's test process. 
+    Ant's test process.
     Third party tasks may or may not be thread safe, and some of Ant's core tasks, such as
     <code>&lt;javac&gt;</code> are definitely not re-entrant. This is because they use libraries that
     were never designed to be used in a multithreaded environment.
@@ -44,16 +44,16 @@
     same time. Anyone trying to run large Ant task sequences in parallel, such
     as javadoc and javac at the same time, is implicitly taking on the task
     of identifying and fixing all concurrency bugs the tasks that they run.
-    
+
 </p>
 <p>
     Accordingly, while this task has uses, it should be considered an advanced
     task which should be used in certain batch-processing or testing situations,
-    rather than an easy trick to speed up build times on a multiway CPU. 
+    rather than an easy trick to speed up build times on a multicore CPU.
 </p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -130,13 +130,13 @@
 override the value in <code>threadCount</code>.  If <code>threadsPerProcessor</code>
 is specified on any older JVM, then the value in <code>threadCount</code> will be used as is.</p>
 
-<p>When using <code>threadCount</code> and  <code>threadsPerProcessor</code> 
-    care should be taken to ensure that the build does not deadlock.  
+<p>When using <code>threadCount</code> and  <code>threadsPerProcessor</code>
+    care should be taken to ensure that the build does not deadlock.
     This can be caused by tasks such as <code>waitfor</code>
-    taking up all available threads before the tasks that would unlock the 
+    taking up all available threads before the tasks that would unlock the
     <code>waitfor</code>
 would occur.  This is not a replacement for Java Language level thread
-semantics and is best used for "embarassingly parallel" tasks.</p>
+semantics and is best used for "embarrassingly parallel" tasks.</p>
 
 
 <h3>Parameters specified as nested elements</h3>
@@ -169,7 +169,7 @@
 &lt;/parallel&gt;
 </pre>
 <p>This example represents a typical pattern for testing a server application.
-In one thread the server is started (the <code>&lt;wlrun&gt;</code> task). 
+In one thread the server is started (the <code>&lt;wlrun&gt;</code> task).
 The other thread consists
 of a three tasks which are performed in sequence. The <code>&lt;sleep&gt;</code> task is used to
 give the server time to come up. Another task which is capable of validating
@@ -191,8 +191,8 @@
 compiled in one thead and a set of JSPs is being precompiled in another. Developers
 need to be careful that the two tasks are independent, both in
 terms of their dependencies and in terms of their potential interactions in
-Ant's external environment. Here we set <code>fork="true"</code> for the 
-<code>&lt;javac&gt;</code> task, so that it runs in a new process; 
+Ant's external environment. Here we set <code>fork="true"</code> for the
+<code>&lt;javac&gt;</code> task, so that it runs in a new process;
 if the <code>&lt;wljspc&gt;</code> task used the javac compiler in-VM
 (it may), concurrency problems may arise.
 </p>
@@ -206,7 +206,7 @@
       &lt;/java&gt;
    &lt;/sequential&gt;
 &lt;/macrodef&gt;
-    
+
 &lt;parallel threadCount="4"&gt;
   &lt;dbpurge file="db/one" /&gt;
   &lt;dbpurge file="db/two" /&gt;
@@ -223,13 +223,11 @@
 <p>This example represents a typical need for use of the threadCount and
 threadsPerProcessor attributes.  Spinning up all 40 of those tasks could cripple
 the system for memory and CPU time.  By limiting the number of
-concurrent executions you can reduce contention for CPU, memory and disk IO, 
+concurrent executions you can reduce contention for CPU, memory and disk IO,
 and so actually finish faster.  This is also a good
 candidate for use of threadCount (and possibly threadsPerProcessor) because
 each task is independent (every new JVM is forked) and has no dependencies on
 the other tasks.</p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/patch.html b/manual/Tasks/patch.html
index 96a5ee9..611c0e8 100644
--- a/manual/Tasks/patch.html
+++ b/manual/Tasks/patch.html
@@ -24,63 +24,62 @@
 
 <body>
 
-<h2><a name="patch">Patch</a></h2>
+<h2 id="patch">Patch</h2>
 <h3>Description</h3>
-<p>Applies a diff file to originals. ; requires "patch" to be
- on the execution path.  </p>
+<p>Applies a diff file to originals. Requires "patch" to be on the execution path.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
     <td align="center" valign="top"><b>Required</b></td>
   </tr>
   <tr>
-    <td valign="top">patchfile</td> 
+    <td valign="top">patchfile</td>
     <td valign="top">the file that includes the diff output</td>
     <td align="center" valign="top">Yes</td>
   </tr>
   <tr>
-    <td valign="top">originalfile</td> 
+    <td valign="top">originalfile</td>
     <td valign="top">the file to patch</td>
-    <td align="center" valign="top">No, tries to guess it from the diff 
+    <td align="center" valign="top">No, tries to guess it from the diff
       file</td>
   </tr>
   <tr>
-    <td valign="top">destfile</td> 
+    <td valign="top">destfile</td>
     <td valign="top">the file to send the output to instead of
       patching the file(s) in place.  <em>since Apache Ant 1.6</em></td>
     <td align="center" valign="top">No.</td>
   </tr>
   <tr>
-    <td valign="top">backups</td> 
+    <td valign="top">backups</td>
     <td valign="top">Keep backups of the unpatched files</td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
-    <td valign="top">quiet</td> 
+    <td valign="top">quiet</td>
     <td valign="top">Work silently unless an error occurs</td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
-    <td valign="top">reverse</td> 
-    <td valign="top">Assume patch was created with old and new files 
+    <td valign="top">reverse</td>
+    <td valign="top">Assume patch was created with old and new files
       swapped.</td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
-    <td valign="top">ignorewhitespace</td> 
+    <td valign="top">ignorewhitespace</td>
     <td valign="top">Ignore whitespace differences.</td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
-    <td valign="top">strip</td> 
-    <td valign="top">Strip the smallest prefix containing <i>num</i> leading 
+    <td valign="top">strip</td>
+    <td valign="top">Strip the smallest prefix containing <i>num</i> leading
       slashes from filenames.</td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
-    <td valign="top">dir</td> 
+    <td valign="top">dir</td>
     <td valign="top">The directory in which to run the patch command.</td>
     <td align="center" valign="top">No, default is the project's basedir.</td>
   </tr>
@@ -102,10 +101,8 @@
 <pre>
 --- a/mod1.0/A	Mon Jun  5 17:28:41 2000
 +++ a/mod1.1/A	Mon Jun  5 17:28:49 2000
-</pre> 
+</pre>
 the leading <i>a/</i> will be stripped.
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/pathconvert.html b/manual/Tasks/pathconvert.html
index 41f56f4..d1485ec 100644
--- a/manual/Tasks/pathconvert.html
+++ b/manual/Tasks/pathconvert.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="pathconvert">Pathconvert</a></h2>
+<h2 id="pathconvert">Pathconvert</h2>
 <h3>Description</h3>
 <p>Converts nested <a href="../Types/resources.html#collection">
 ResourceCollection</a>s, or a reference to just one, into a path
@@ -38,11 +38,11 @@
 drive letters to Unix paths, and vice-versa.</p>
 <p>More complex transformations can be achieved using a nested
 <a href="../Types/mapper.html"><code>&lt;mapper&gt;</code></a>
-(since Apache Ant 1.6.2).
+(<em>since Apache Ant 1.6.2</em>).
 </p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -51,7 +51,7 @@
   <tr>
     <td valign="top">targetos</td>
     <td valign="top">
-        The target architecture.  Must be one of 'unix', 'windows', 
+        The target architecture.  Must be one of 'unix', 'windows',
         'netware', 'tandem' or 'os/2'.
         This is a shorthand mechanism for specifying both
         <code>pathsep</code> and <code>dirsep</code>
@@ -98,14 +98,14 @@
   </tr>
   <tr>
     <td valign="top">preserveduplicates</td>
-    <td valign="top">Whether to preserve duplicate resources. <b>Since Ant 1.8</b></td>
+    <td valign="top">Whether to preserve duplicate resources. <em>Since Ant 1.8</em></td>
     <td valign="top" align="center">No; default &quot;false&quot;.
   </tr>
 </table>
 <h3>Parameters specified as nested elements</h3>
 <h4>map</h4>
 <p>Specifies the mapping of path prefixes between Unix and Windows.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -115,7 +115,7 @@
     <td valign="top">from</td>
     <td valign="top">
       The prefix to match.  Note that this value is case-insensitive when
-      the build is running on a Windows platform and case-sensitive 
+      the build is running on a Windows platform and case-sensitive
       when running on a Unix platform.
       <em>Since Ant 1.7.0</em>, on Windows this value is also insensitive
       to the slash style used for directories, one can use '/' or '\'.
@@ -136,8 +136,8 @@
 <p><strong>Note</strong>: The map elements are applied in the order specified,
 and only the first matching map element is applied.  So, the ordering of
 your map elements can be important, if any <code>from</code> values are
-prefixes of other <code>from</code> values.</i>
-</p>   
+prefixes of other <code>from</code> values.
+</p>
 <h4>Resource Collections</h4>
 <p>If the <code>refid</code> attribute is not specified, then one or more
    nested <a href="../Types/resources.html#collection">Resource
@@ -145,7 +145,7 @@
 <h4>mapper</h4>
 <p>A single nested <a href="../Types/mapper.html">
 <code>&lt;mapper&gt;</code></a> element can be specified
-to perform any of various filename transformations (since Ant 1.6.2).
+to perform any of various filename transformations (<em>since Ant 1.6.2</em>).
 </p>
 
 <h3>Examples</h3>
@@ -161,15 +161,15 @@
       &lt;pathelement location=&quot;${wl.home}/mssqlserver4/classes&quot;/&gt;
       &lt;pathelement location=&quot;c:\winnt\System32&quot;/&gt;
     &lt;/path&gt;
-    
+
     &lt;pathconvert targetos=&quot;unix&quot; property=&quot;wl.path.unix&quot; refid=&quot;wl.path&quot;&gt;
       &lt;map from=&quot;${wl.home}&quot; to=&quot;${wl.home.unix}&quot;/&gt;
       &lt;map from=&quot;c:&quot; to=&quot;&quot;/&gt;
     &lt;/pathconvert&gt;
 </pre>
-<p> will generate the path shown below
-and store it in the property named <code>wl.path.unix</code>.
-</p>   
+<p>
+will generate the path shown below and store it in the property named <code>wl.path.unix</code>.
+</p>
 <pre>
 /weblogic/lib/weblogicaux.jar:/weblogic/classes:/weblogic/mssqlserver4/classes:/WINNT/SYSTEM32
 </pre>
@@ -197,7 +197,7 @@
     &lt;fileset dir=&quot;${src.dir}&quot; id=&quot;src.files&quot;&gt;
       &lt;include name=&quot;**/*.java&quot;/&gt;
     &lt;/fileset&gt;
-  
+
     &lt;pathconvert pathsep=&quot;,&quot; property=&quot;javafiles&quot; refid=&quot;src.files&quot;/&gt;
 </pre>
 <p>This example takes the set of files determined by the fileset (all files ending
@@ -220,5 +220,3 @@
   </p>
 </body>
 </html>
-
- 
diff --git a/manual/Tasks/presetdef.html b/manual/Tasks/presetdef.html
index c7f381c..d975bf9 100644
--- a/manual/Tasks/presetdef.html
+++ b/manual/Tasks/presetdef.html
@@ -15,21 +15,16 @@
    limitations under the License.
 -->
 <html>
-  
+
   <head>
-    <meta http-equiv="Content-Language" content="en-us"></meta>
+    <meta http-equiv="Content-Language" content="en-us">
     <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
-<title>PreSetDef Task</title>
-    <style type="text/css">
-      <!--
-           .code { background: #EFEFEF; margin-top: }
-           -->
-    </style>
+    <title>PreSetDef Task</title>
   </head>
-  
+
   <body>
-    
-    <h2><a name="presetdef">PreSetDef</a></h2>
+
+    <h2 id="presetdef">PreSetDef</h2>
     <h3>Description</h3>
     <p>
       The preset definition generates a new definition
@@ -45,7 +40,7 @@
       when the preset definition is defined.
     </p>
     <h3>Parameters</h3>
-    <table border="1" cellpadding="2" cellspacing="0">
+    <table>
       <tr>
         <td valign="top"><b>Attribute</b></td>
         <td valign="top"><b>Description</b></td>
@@ -70,7 +65,7 @@
       This nested element can be any other type or task. The attributes
       and elements that need to be preset are placed here.
     </p>
-    
+
     <h3>Examples</h3>
       The following fragment defines a javac task with the debug, deprecation
       srcdir and destdir
@@ -177,8 +172,6 @@
 &lt;/macrodef&gt;
 &lt;showmessage-presetdef messageval="${message}"/&gt;
 </pre></blockquote>
-    <hr></hr>
-    
+
   </body>
 </html>
-
diff --git a/manual/Tasks/projecthelper.html b/manual/Tasks/projecthelper.html
index ea78eb2..986bf76 100644
--- a/manual/Tasks/projecthelper.html
+++ b/manual/Tasks/projecthelper.html
@@ -35,7 +35,7 @@
 <p>See the description of Apache Ant's
 <a href="../projecthelper.html">Project Helper</a> for more information.
 </p>
-<p><b>Since Ant 1.8.2</b></p>
+<p><em>Since Ant 1.8.2</em></p>
 
 <h3>Parameters specified as nested elements</h3>
 
@@ -56,4 +56,3 @@
 
 </body>
 </html>
-
diff --git a/manual/Tasks/property.html b/manual/Tasks/property.html
index 7dc90a7..31733c6 100644
--- a/manual/Tasks/property.html
+++ b/manual/Tasks/property.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="property">Property</a></h2>
+<h2 id="property">Property</h2>
 <h3>Description</h3>
 <p>Sets a <a href="../using.html#properties">property</a>
 (by name and value), or set of properties (from file or
@@ -58,13 +58,13 @@
 This also holds for properties loaded from a property file.</p>
 <p>A list of predefined properties can be found <a
 href="../properties.html#built-in-props">here</a>.</p>
-<p>Since Apache Ant 1.8.0 it is possible to load properties defined in xml
+<p><em>Since Apache Ant 1.8.0</em>, it is possible to load properties defined in xml
 according to <a href="http://java.sun.com/dtd/properties.dtd">Suns DTD</a>,
-if Java5+ is present. For this the name of the file, resource or url has 
+if Java 5+ is present. For this the name of the file, resource or url has
 to end with <tt>.xml</tt>.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -177,21 +177,21 @@
 </p>
 
 <h4>Any OS except OpenVMS</h4>
-<p>Starting with Ant 1.8.2 if Ant detects it is running of a Java 1.5
-  VM (or better) Ant will use <code>System.getenv</code> rather than
+<p><em>Since Ant 1.8.2</em>, if Ant detects it is running on a Java 5
+  or newer VM, Ant will use <code>System.getenv</code> rather than
   its own OS dependent native implementation.  For some OSes this
   causes minor differences when compared to older versions of Ant.
   For a full list
   see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=49366">Bugzilla
   Issue 49366</a>.  In particular:</p>
 <ul>
-  <li>On Windows Ant will now return additional "environment
+  <li>On Windows, Ant will now return additional "environment
     variables" that correspond to the drive specific current working
     directories when Ant is run from the command line.  The keys of
     these variables starts with an equals sign.</li>
   <li>Some users reported that some Cygwin specific variables (in
     particular PROMPT) was no longer present.</li>
-  <li>On OS/2 Ant no longer returns the BEGINLIBPATH variable.</li>
+  <li>On OS/2, Ant no longer returns the BEGINLIBPATH variable.</li>
 </ul>
 
 <h3>Parameters specified as nested elements</h3>
@@ -288,58 +288,56 @@
 deploy.url=http://${deploy.server}:${deploy.port}/
 </pre>
 
-
-<a name="notes-env"></a>
-<h3>Notes about environment variables</h3>
+<h3 id="notes-env">Notes about environment variables</h3>
 <p>
-  Ant runs on Java 1.2 therefore it cannot use Java5 features for accessing environment
+  Ant runs on Java 1.2 therefore it cannot use Java 5 features for accessing environment
   variables. So it starts a command in a new process which prints the environment variables,
-  analyzes the output and creates the properties. <br>
+  analyzes the output and creates the properties.<br>
   There are commands for the following operating systems implemented in
   <a href="https://git-wip-us.apache.org/repos/asf?p=ant.git;a=blob;f=src/main/org/apache/tools/ant/taskdefs/Execute.java;hb=24e5a0e881dba01a6f012c4a271b743946412a0d">
   Execute.java</a> (method <tt>getProcEnvCommand()</tt>):
+</p>
   <table>
     <tr>
       <th>OS</th>
       <th>command</th>
     </tr>
     <tr>
-      <td> os/2 </td>
-      <td> cmd /c set </td>
+      <td>os/2</td>
+      <td>cmd /c set</td>
     </tr>
     <tr>
-      <td colspan="2"> windows </td>
+      <td colspan="2"> windows</td>
     </tr>
     <tr>
-      <td> * win9x </td>
-      <td> command.com /c set </td>
+      <td>* win9x</td>
+      <td>command.com /c set</td>
     </tr>
     <tr>
-      <td> * other </td>
-      <td> cmd /c set </td>
+      <td>* other</td>
+      <td>cmd /c set</td>
     </tr>
     <tr>
-      <td> z/os </td>
-      <td> /bin/env <b>OR</b> /usr/bin/env <b>OR</b> env   <i>(depending on read rights)</i> </td>
+      <td>z/os</td>
+      <td>/bin/env <b>OR</b> /usr/bin/env <b>OR</b> env   <i>(depending on read rights)</i></td>
     </tr>
     <tr>
-      <td> unix </td>
-      <td> /bin/env <b>OR</b> /usr/bin/env <b>OR</b> env   <i>(depending on read rights)</i> </td>
+      <td>unix</td>
+      <td>/bin/env <b>OR</b> /usr/bin/env <b>OR</b> env   <i>(depending on read rights)</i></td>
     </tr>
     <tr>
-      <td> netware </td>
-      <td> env </td>
+      <td>netware</td>
+      <td>env</td>
     </tr>
     <tr>
-      <td> os/400 </td>
-      <td> env </td>
+      <td>os/400</td>
+      <td>env</td>
     </tr>
     <tr>
-      <td> openvms </td>
-      <td> show logical </td>
+      <td>openvms</td>
+      <td>show logical</td>
     </tr>
   </table>
-</p>
 
 </body>
 </html>
diff --git a/manual/Tasks/propertyfile.html b/manual/Tasks/propertyfile.html
index e4030f8..a77f91f 100644
--- a/manual/Tasks/propertyfile.html
+++ b/manual/Tasks/propertyfile.html
@@ -24,9 +24,8 @@
 <body>
 
 <h1>PropertyFile</h1>
-
-<hr>
-<h2><a name="introduction">Introduction</a></h2>
+<hr/>
+<h2 id="introduction">Introduction</h2>
 <p>Apache Ant provides an optional task for editing property files. This is
 very useful when wanting to make unattended modifications to
 configuration files for application servers and
@@ -40,10 +39,10 @@
   In general, linefeeds of the updated file will be the same as the
   first linefeed found when reading it.</p>
 
-<hr>
-<h2><a name="proptask">PropertyFile Task</a></h2>
+<hr/>
+<h2 id="proptask">PropertyFile Task</h2>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -62,7 +61,7 @@
 <tr>
   <td width="12%" valign="top">jdkproperties</td>
   <td width="78%" valign="top">Use java.lang.Properties, which will
-    loose comments and layout of file (default is 'false').  <em>since
+    lose comments and layout of file (default is 'false').  <em>since
     Ant 1.8.0</em></td>
   <td width="10%" valign="top">no</td>
 </tr>
@@ -73,10 +72,10 @@
 in the properties file were lost by the task.</p>
 
 <h3>Parameters specified as nested elements</h3>
-<h4><a name="entryElement">Entry</a></h4>
+<h4 id="entryElement">Entry</h4>
 <p>Use nested <code>&lt;entry&gt;</code>
 elements to specify actual modifications to the property file itself.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -156,7 +155,6 @@
   <li>If value and default are both specified and the property did not exist in
   the property file, the property is set to default.</li>
 </ul>
-<p>&nbsp;</p>
 
 <h3>Examples</h3>
 
@@ -186,7 +184,7 @@
 
 formated.date=243 13\:47</pre>
 <p>
-The slashes conform to the expectations of the Properties class.  The file will be stored in a manner so that each character is examined and escaped if necessary. 
+The slashes conform to the expectations of the Properties class.  The file will be stored in a manner so that each character is examined and escaped if necessary.
 </p>
 
 <p>
@@ -228,7 +226,7 @@
 <p>Each time called, a &quot;.&quot; will be appended to &quot;progress&quot;
 </p>
 
-<p>Pumps the project version to the next minor version (increase minor and set path=0):
+<p>Pumps the project version to the next minor version (increase minor and set path=0):</p>
 <blockquote><pre>&lt;target name="nextMinorVersion"&gt;
    &lt;property
      name="header"
@@ -242,8 +240,6 @@
 &lt;/target&gt;
 </pre></blockquote>
 After running this target the version changed e.g. from 3.2.2 to 3.3.0.
-</p>
-
 
 </body>
 </html>
diff --git a/manual/Tasks/propertyhelper.html b/manual/Tasks/propertyhelper.html
index 6c73b0b..8295d9e 100644
--- a/manual/Tasks/propertyhelper.html
+++ b/manual/Tasks/propertyhelper.html
@@ -32,7 +32,7 @@
 PropertyHelper active on the current Project. This is somewhat advanced Apache Ant usage and
 assumes a working familiarity with the modern Ant APIs. See the description of Ant's
 <a href="../properties.html#propertyHelper">Property Helper</a> for more information.
-<b>Since Ant 1.8.0</b></p>
+<em>Since Ant 1.8.0</em></p>
 
 <h3>Parameters specified as nested elements</h3>
 
@@ -51,7 +51,7 @@
 is also provided:</p>
 
 <h5>Parameters</h5>
-<table border="1" cellpadding="2" cellspacing="0"> 
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -105,4 +105,3 @@
 
 </body>
 </html>
-
diff --git a/manual/Tasks/pvcstask.html b/manual/Tasks/pvcstask.html
index a95b32e..91c85c4 100644
--- a/manual/Tasks/pvcstask.html
+++ b/manual/Tasks/pvcstask.html
@@ -14,20 +14,17 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
 <html>
 <head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta http-equiv="Content-Language" content="en-us">
    <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
 <title>PVCS task</title>
 </head>
 <body>
 
-<h1>
-Apache Ant Pvcs Task User Manual</h1>
+<h1>Apache Ant Pvcs Task User Manual</h1>
 
-<p><b>Note:</b>
+<p><strong>Note</strong>:
 Before using this task, the user running Ant must have access to the
 commands of PVCS (get and pcli) and must have access to the
 repository. Note that the way to specify the repository is platform
@@ -47,160 +44,158 @@
 Version 1.0 - 2001/01/31<br>
 <p>Initial release.</p>
 <hr>
-<h2>
-Table of Contents</h2>
+<h2>Table of Contents</h2>
 <ul>
   <li><a href="#introduction">Introduction</a></li>
   <li><a href="#pvcs">Pvcs Task</a></li>
 </ul>
-<hr>
+<hr/>
 
-<h2><a NAME="introduction">Introduction</a></h2>
+<h2 id="introduction">Introduction</h2>
 The pvcs task allows the user of Ant to extract the latest edition
 of the source code from a PVCS repository. PVCS is a version control system
 developed by <a href="http://www.merant.com/products/pvcs">Merant</a>.
 <br>
 This version has been tested against PVCS version 6.5 and 6.6 under Windows and Solaris.
 
-<hr>
-<h2><a NAME="pvcs">Pvcs Task</a></h2>
+<hr/>
+<h2 id="pvcs">Pvcs Task</h2>
 <h3>Description</h3>
 The pvcs task is set to point at a PVCS repository and optionally a project
 within that repository, and can from that specification get the latest
 version of the files contained by the repository.
-<h3>
-Parameters</h3>
+<h3>Parameters</h3>
 
-<table BORDER CELLSPACING=0 CELLPADDING=2 >
+<table>
 <tr>
-<td VALIGN=TOP WIDTH="12%"><b>Attribute</b></td>
+<td valign="top" width="12%"><b>Attribute</b></td>
 
-<td VALIGN=TOP WIDTH="78%"><b>Description</b></td>
+<td valign="top" width="78%"><b>Description</b></td>
 
-<td VALIGN=TOP WIDTH="10%"><b>Required</b></td>
+<td valign="top" width="10%"><b>Required</b></td>
 </tr>
 
 <tr>
-<td VALIGN=TOP WIDTH="12%">repository</td>
+<td valign="top" width="12%">repository</td>
 
-<td VALIGN=TOP WIDTH="78%">The location of the repository (see your PVCS
+<td valign="top" width="78%">The location of the repository (see your PVCS
 manuals)</td>
 
-<td VALIGN=TOP WIDTH="10%">Yes</td>
+<td valign="top" width="10%">Yes</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP WIDTH="12%">pvcsproject</td>
+<td valign="top" width="12%">pvcsproject</td>
 
-<td VALIGN=TOP WIDTH="78%">The project within the PVCS repository to extract
+<td valign="top" width="78%">The project within the PVCS repository to extract
 files from (&quot;/&quot; is root project and that is default if this attribute isn't
 specified)</td>
 
-<td VALIGN=TOP WIDTH="10%">No</td>
+<td valign="top" width="10%">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP WIDTH="12%">label</td>
+<td valign="top" width="12%">label</td>
 
-<td VALIGN=TOP WIDTH="78%">Only files marked with this label are extracted.</td>
+<td valign="top" width="78%">Only files marked with this label are extracted.</td>
 
-<td VALIGN=TOP WIDTH="10%">No</td>
+<td valign="top" width="10%">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP WIDTH="12%">promotiongroup</td>
+<td valign="top" width="12%">promotiongroup</td>
 
-<td VALIGN=TOP WIDTH="78%">Only files within this promotion group are extracted. Using
+<td valign="top" width="78%">Only files within this promotion group are extracted. Using
 both the <i>label</i> and the <i>promotiongroup</i> tag will cause the files in the
 promotion group and with that label to be extracted.
 </td>
 
-<td VALIGN=TOP WIDTH="10%">No</td>
+<td valign="top" width="10%">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP WIDTH="12%">config</td>
+<td valign="top" width="12%">config</td>
 
-<td VALIGN=TOP WIDTH="78%">path of a non default .cfg file.
+<td valign="top" width="78%">path of a non default .cfg file.
 Can be given absolute or relative to Ant's base directory.
 </td>
 
-<td VALIGN=TOP WIDTH="10%">No</td>
+<td valign="top" width="10%">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP WIDTH="12%">force</td>
+<td valign="top" width="12%">force</td>
 
-<td VALIGN=TOP WIDTH="78%">If set to <i>yes</i> all files that exists and are writable are overwritten. Default <i>no</i> causes the files that are writable to be ignored. This stops the PVCS command <i>get</i> to stop asking questions!</td>
+<td valign="top" width="78%">If set to <i>yes</i> all files that exists and are writable are overwritten. Default <i>no</i> causes the files that are writable to be ignored. This stops the PVCS command <i>get</i> to stop asking questions!</td>
 
-<td VALIGN=TOP WIDTH="10%">No</td>
+<td valign="top" width="10%">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP WIDTH="12%">workspace</td>
+<td valign="top" width="12%">workspace</td>
 
-<td VALIGN=TOP WIDTH="78%">By specifying a workspace, the files are extracted to that location. A PVCS workspace is a
+<td valign="top" width="78%">By specifying a workspace, the files are extracted to that location. A PVCS workspace is a
 name for a location of the workfiles and isn't as such the location itself. You define the location for a workspace
 using the PVCS GUI clients. If this isn't specified the default workspace for the current user is used.</td>
 
-<td VALIGN=TOP WIDTH="10%">No</td>
+<td valign="top" width="10%">No</td>
 </tr>
 
 <tr>
-<td VALIGN=TOP WIDTH="12%">pvcsbin</td>
+<td valign="top" width="12%">pvcsbin</td>
 
-<td VALIGN=TOP WIDTH="78%">On some systems the PVCS executables <i>pcli</i>
+<td valign="top" width="78%">On some systems the PVCS executables <i>pcli</i>
 and <i>get</i> are not found in the PATH. In such cases this attribute
 should be set to the bin directory of the PVCS installation containing
 the executables mentioned before. If this attribute isn't specified the
 tag expects the executables to be found using the PATH environment variable.</td>
 
-<td VALIGN=TOP WIDTH="10%">No</td>
+<td valign="top" width="10%">No</td>
 </tr>
     <tr>
-      <td VALIGN=TOP WIDTH="12%">ignorereturncode</td>
-      <td VALIGN=TOP WIDTH="78%">If set to <i>true</i> the return value from executing
+      <td valign="top" width="12%">ignorereturncode</td>
+      <td valign="top" width="78%">If set to <i>true</i> the return value from executing
         the pvcs commands are ignored.</td>
-      <td VALIGN=TOP WIDTH="10%">No</td>
+      <td valign="top" width="10%">No</td>
     </tr>
     <tr>
-      <td VALIGN=TOP WIDTH="12%">updateonly</td>
-      <td VALIGN=TOP WIDTH="78%">If set to <i>true</i> files are gotten only if
+      <td valign="top" width="12%">updateonly</td>
+      <td valign="top" width="78%">If set to <i>true</i> files are gotten only if
         newer than existing local files.</td>
-      <td VALIGN=TOP WIDTH="10%">No</td>
+      <td valign="top" width="10%">No</td>
     </tr>
     <tr>
-      <td valign="TOP">filenameformat</td>
-      <td valign="TOP">The format of your folder names in a
+      <td valign="top">filenameformat</td>
+      <td valign="top">The format of your folder names in a
           format suitable for <code>java.text.MessageFormat</code>.
           Defaults to <code>{0}-arc({1})</code>.  Repositories where
           the archive extension is not  <code>-arc</code> should set
           this.</td>
-      <td valign="TOP">No</td>
+      <td valign="top">No</td>
     </tr>
     <tr>
-      <td valign="TOP">linestart</td>
-        <td valign="TOP">Used to parse the output of the pcli
+      <td valign="top">linestart</td>
+        <td valign="top">Used to parse the output of the pcli
           command. It defaults to <code>&quot;P:</code>.  The parser already
           knows about / and \\, this property is useful in cases where the
           repository is accessed on a Windows platform via a drive letter
           mapping.</td>
-      <td valign="TOP">No</td>
+      <td valign="top">No</td>
     </tr>
     <tr>
-      <td valign="TOP">revision</td>
-      <td valign="TOP">Retrieve the specified revision.</td>
-      <td valign="TOP">No</td>
+      <td valign="top">revision</td>
+      <td valign="top">Retrieve the specified revision.</td>
+      <td valign="top">No</td>
     </tr>
     <tr>
-      <td valign="TOP">userid</td>
-      <td valign="TOP">Use the specified userid.</td>
-      <td valign="TOP">No</td>
+      <td valign="top">userid</td>
+      <td valign="top">Use the specified userid.</td>
+      <td valign="top">No</td>
     </tr>
 </table>
-<h3><a name="nested">Nested Elements</a></h3>
+<h3 id="nested">Nested Elements</h3>
 
-<h3>pvcsproject element</h3>
+<h4>pvcsproject element</h4>
 <p><code>pvcs</code> supports a nested
 <code>&lt;pvcsproject&gt;</code> element, that represents a project
 within the PVCS repository to extract files from.  By nesting multiple
@@ -210,21 +205,21 @@
 
 <h3>Parameters</h3>
 
-<table BORDER CELLSPACING=0 CELLPADDING=2 >
+<table>
 <tr>
-<td VALIGN=TOP WIDTH="12%"><b>Attribute</b></td>
+<td valign="top" width="12%"><b>Attribute</b></td>
 
-<td VALIGN=TOP WIDTH="78%"><b>Description</b></td>
+<td valign="top" width="78%"><b>Description</b></td>
 
-<td VALIGN=TOP WIDTH="10%"><b>Required</b></td>
+<td valign="top" width="10%"><b>Required</b></td>
 </tr>
 
 <tr>
-<td VALIGN=TOP WIDTH="12%">name</td>
+<td valign="top" width="12%">name</td>
 
-<td VALIGN=TOP WIDTH="78%">The name of the pvcs project</td>
+<td valign="top" width="78%">The name of the pvcs project</td>
 
-<td VALIGN=TOP WIDTH="10%">Yes</td>
+<td valign="top" width="10%">Yes</td>
 </tr>
 </table>
 
@@ -236,7 +231,7 @@
   &lt;!-- =================================================================== --&gt;
   &lt;target name=&quot;getlatest&quot;&gt;
     &lt;pvcs repository=&quot;/mnt/pvcs&quot; pvcsproject=&quot;/myprj&quot;/&gt;
-  &lt;/target&gt;</ul>
+  &lt;/target&gt;
 </pre>
 <p>Now run:</p>
 <code>ant getlatest</code>
@@ -267,7 +262,7 @@
       &lt;pvcsproject name=&quot;/myprj&quot;/&gt;
       &lt;pvcsproject name=&quot;/myprj2&quot;/&gt;
     &lt;/pvcs&gt;
-  &lt;/target&gt;</ul>
+  &lt;/target&gt;
 </pre>
 <p>Now run:</p>
 <code>ant getlatest2</code>
@@ -289,7 +284,7 @@
 
   Total time: 22 seconds</pre>
 
-<hr WIDTH="100%">
+<hr/>
 <p>PVCS is a registered trademark of MERANT.</p>
 </body>
 </html>
diff --git a/manual/Tasks/recorder.html b/manual/Tasks/recorder.html
index dfbfc0d..5066887 100644
--- a/manual/Tasks/recorder.html
+++ b/manual/Tasks/recorder.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="log">Record</a></h2>
+<h2 id="log">Record</h2>
 <h3>Description</h3>
 <p>A recorder is a listener to the current build process that records the
 output to a file.</p>
@@ -42,7 +42,7 @@
 a buildFinished event.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -115,7 +115,7 @@
 <h3>Notes</h3>
 <p>There is some functionality that I would like to be able to add in the
 future.  They include things like the following:</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -164,9 +164,5 @@
   </tr>
 </table>
 
-
-
-
-
 </body>
 </html>
diff --git a/manual/Tasks/rename.html b/manual/Tasks/rename.html
index 330fbe3..d2442fd 100644
--- a/manual/Tasks/rename.html
+++ b/manual/Tasks/rename.html
@@ -24,13 +24,13 @@
 
 <body>
 
-<h2><a name="rename">Rename</a></h2>
+<h2 id="rename">Rename</h2>
 <h3><i>Deprecated</i></h3>
 <p><i>This task has been deprecated.  Use the Move task instead.</i></p>
 <h3>Description</h3>
 <p>Renames a given file.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -53,12 +53,10 @@
   </tr>
 </table>
 <h3>Examples</h3>
-<pre>  &lt;rename src=&quot;foo.jar&quot; dest=&quot;${name}-${version}.jar&quot;/&gt;</pre> 
+<pre>  &lt;rename src=&quot;foo.jar&quot; dest=&quot;${name}-${version}.jar&quot;/&gt;</pre>
 <p>Renames the file <code>foo.jar</code> to <code>${name}-${version}.jar</code> (assuming <code>name</code>
  and <code>version</code> being predefined properties). If a file named <code>${name}-${version}.jar</code>
  already exists, it will be removed prior to renaming <code>foo.jar</code>.</p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/renameextensions.html b/manual/Tasks/renameextensions.html
index ed3bfbb..d54d1fa 100644
--- a/manual/Tasks/renameextensions.html
+++ b/manual/Tasks/renameextensions.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="renameexts">RenameExtensions</a></h2>
+<h2 id="renameexts">RenameExtensions</h2>
 <h3><i>Deprecated</i></h3>
 <p><i>This task has been deprecated.  Use the <a href="../Tasks/move.html">move</a>
 task with a <a href="../Types/mapper.html#glob-mapper">glob mapper</a> instead.</i></p>
@@ -43,7 +43,7 @@
 <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
 <code>&lt;patternset&gt;</code> elements.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -116,8 +116,5 @@
   </p>
 </blockquote>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/replace.html b/manual/Tasks/replace.html
index 36204d0..bc1988f 100644
--- a/manual/Tasks/replace.html
+++ b/manual/Tasks/replace.html
@@ -24,19 +24,19 @@
 
 <body>
 
-<h2><a name="replace">Replace</a></h2>
+<h2 id="replace">Replace</h2>
 <h3>Description</h3>
-<p>Replace is a directory based task for replacing the occurrence of a given string with another string 
+<p>Replace is a directory based task for replacing the occurrence of a given string with another string
 in selected file.</p>
 <p>If you want to replace a text that crosses line boundaries, you
 must use a nested <code>&lt;replacetoken&gt;</code> element.</p>
 
 <p>The output file is only written if it differs from the existing
 file.  This prevents spurious rebuilds based on unchanged files which
-have been regenerated by this task.</p> 
+have been regenerated by this task.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -45,11 +45,11 @@
   <tr>
     <td valign="top">file</td>
     <td valign="top">file for which the token should be replaced.</td>
-    <td align="center" rowspan="2">Exactly one of the two.</td>
+    <td align="center" rowspan="2">Exactly one of the two</td>
   </tr>
   <tr>
     <td valign="top">dir</td>
-    <td valign="top">The base directory to use when replacing a token in 
+    <td valign="top">The base directory to use when replacing a token in
       multiple files.</td>
   </tr>
   <tr>
@@ -72,8 +72,8 @@
   </tr>
   <tr>
     <td valign="top">summary</td>
-    <td valign="top">Indicates whether a summary of the replace operation 
-                     should be produced, detailing how many token occurrences 
+    <td valign="top">Indicates whether a summary of the replace operation
+                     should be produced, detailing how many token occurrences
                      and files were processed
                      </td>
     <td valign="top" align="center">No, by default no summary is produced</td>
@@ -123,13 +123,13 @@
   <tr>
     <td valign="top">preserveLastModified</td>
     <td valign="top">Keep the file timestamp(s) even if the file(s)
-      is(are) modified.  <em>since Apache Ant 1.8.0.</em></td>
+      is(are) modified.  <em>since Apache Ant 1.8.0</em>.</td>
     <td valign="top" align="center">No, defaults to false</td>
   </tr>
   <tr>
     <td valign="top">failOnNoReplacements</td>
     <td valign="top">Whether to fail the build if the task didn't do
-      anything.  <em>since Ant 1.8.0.</em></td>
+      anything.  <em>since Ant 1.8.0</em>.</td>
     <td valign="top" align="center">No, defaults to false</td>
   </tr>
 </table>
@@ -150,7 +150,7 @@
 cross line boundaries, you can use nested elements to specify
 them.</p>
 <p>The elements support attributes:</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -159,7 +159,7 @@
   <tr>
     <td valign="top">expandProperties</td>
     <td valign="top">Whether to expand properties in the nested text.
-      <em>since Ant 1.8.0.</em></td>
+      <em>since Ant 1.8.0</em>.</td>
     <td align="center">No, defaults to true.</td>
   </tr>
 </table>
@@ -186,7 +186,7 @@
 <h4>replacefilter</h4>
 <p>In addition to allowing for multiple replacements, optional nested <code>&lt;replacefilter&gt;</code> elements allow replacement values to be extracted from a property file. The name of this file is specified using the <code>&lt;replace&gt;</code> attribute <i>propertyFile</i>.
 </p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -208,35 +208,32 @@
     <td valign="top">Name of the property whose value is to serve as the replacement value.</td>
   </tr>
 </table>
-<p>Since Ant 1.8.0 token and value can be specified as nested elements
+<p><em>Since Ant 1.8.0</em> token and value can be specified as nested elements
   just like in the task itself.</p>
 <p>If neither <i>value</i> nor <i>property</i> is used, the value provided using the <code>&lt;replace&gt;</code> attribute <i>value</i> and/or the <code>&lt;replacevalue&gt;</code> element is used. If no value was specified using either of these options, the token is replaced with an empty string.
 </p>
 <h3>Examples</h3>
 <blockquote><pre>
-&lt;replace 
+&lt;replace
     file=&quot;configure.sh&quot;
     value=&quot;defaultvalue&quot;
     propertyFile=&quot;src/name.properties&quot;&gt;
-  &lt;replacefilter 
+  &lt;replacefilter
     token=&quot;@token1@&quot;/&gt;
-  &lt;replacefilter 
-    token=&quot;@token2@&quot; 
+  &lt;replacefilter
+    token=&quot;@token2@&quot;
     value=&quot;value2&quot;/&gt;
-  &lt;replacefilter 
-    token=&quot;@token3@&quot; 
+  &lt;replacefilter
+    token=&quot;@token3@&quot;
     property=&quot;property.key&quot;/&gt;
   &lt;replacefilter&gt;
-    &lt;replacetoken&gt;@token4@&lt;/replacetoken&gt; 
+    &lt;replacetoken&gt;@token4@&lt;/replacetoken&gt;
     &lt;replacevalue&gt;value4&lt;/replacevalue&gt;
   &lt;/replacefilter&gt;
 &lt;/replace&gt;
 </pre></blockquote>
 <p>In file <code>configure.sh</code>, replace all instances of &quot;@token1@&quot; with &quot;defaultvalue&quot;, all instances of &quot;@token2@&quot; with &quot;value2&quot;, and all instances of &quot;@token3@&quot; with the value of the property &quot;property.key&quot;, as it appears in property file <code>src/name.properties</code>.</p>
-<p><b>Note:</b> It is possible to use either the <i>token</i>/<code>&lt;replacetoken&gt;</code> and <i>value</i>/<code>&lt;replacevalue&gt;</code> attributes/elements, the nested replacefilter elements, or both in the same operation.
-</p>
-
+<p><strong>Note</strong>: It is possible to use either the <i>token</i>/<code>&lt;replacetoken&gt;</code> and <i>value</i>/<code>&lt;replacevalue&gt;</code> attributes/elements, the nested replacefilter elements, or both in the same operation.</p>
 
 </body>
 </html>
-
diff --git a/manual/Tasks/replaceregexp.html b/manual/Tasks/replaceregexp.html
index eed4c84..68e6523 100644
--- a/manual/Tasks/replaceregexp.html
+++ b/manual/Tasks/replaceregexp.html
@@ -23,7 +23,7 @@
 </head>
 <body>
 
-<h2><a name="replaceregexp">ReplaceRegExp</a></h2>
+<h2 id="replaceregexp">ReplaceRegExp</h2>
 <h3>Description</h3>
 <p>ReplaceRegExp is a directory based task for replacing the
 occurrence of a given regular expression with a substitution pattern
@@ -31,16 +31,16 @@
 
 <p>The output file is only written if it differs from the existing
 file.  This prevents spurious rebuilds based on unchanged files which
-have been regenerated by this task.</p> 
+have been regenerated by this task.</p>
 
 <p>Similar to <a href="../Types/mapper.html#regexp-mapper">regexp
 type mappers</a> this task needs a supporting regular expression
 library and an implementation of
 <code>org.apache.tools.ant.util.regexp.Regexp</code>.
-See details in the documentation of the <a href="../Types/regexp.html#implementation">Regexp Type</a>. </p>
+See details in the documentation of the <a href="../Types/regexp.html#implementation">Regexp Type</a>.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -90,7 +90,7 @@
   <tr>
     <td valign="top">preserveLastModified</td>
     <td valign="top">Keep the file timestamp(s) even if the file(s)
-      is(are) modified.  <em>since Ant 1.8.0.</em></td>
+      is(are) modified.  <em>since Ant 1.8.0</em>.</td>
     <td valign="top" align="center">No, defaults to false</td>
   </tr>
 </table>
@@ -109,7 +109,7 @@
 <h3>Parameters specified as nested elements</h3>
 <p>This task supports a nested <a href="../Types/fileset.html">FileSet</a>
    element.</p>
-<p>Since Ant 1.8.0 this task supports any filesystem
+<p><em>Since Ant 1.8.0</em>, this task supports any filesystem
   based <a href="../Types/resources.html#collection">resource
     collections</a> as nested elements.</p>
 <p>This task supports a nested <i><a href="../Types/regexp.html">Regexp</a></i> element to specify
@@ -151,21 +151,20 @@
 &lt;/replaceregexp&gt;
 </pre></blockquote>
 <p>replaces all whitespaces (blanks, tabs, etc) by one blank remaining the
-line separator. So with input
+line separator. So with input</p>
 <blockquote>
 <pre>
 &lt;html&gt;    &lt;body&gt;
-&lt;&lt;TAB&gt;&gt;&lt;h1&gt;    T E S T   &lt;/h1&gt;  &lt;&lt;TAB&gt;&gt;    
+&lt;&lt;TAB&gt;&gt;&lt;h1&gt;    T E S T   &lt;/h1&gt;  &lt;&lt;TAB&gt;&gt;
 &lt;&lt;TAB&gt;&gt; &lt;/body&gt;&lt;/html&gt;
 </pre></blockquote>
-would converted to
+<p>would converted to</p>
 <blockquote>
 <pre>
 &lt;html&gt; &lt;body&gt;
  &lt;h1&gt; T E S T &lt;/h1&gt; &lt;/body&gt;&lt;/html&gt;
 </pre>
 </blockquote>
-</p>
 
 <br><!-- small distance from code of the previous example -->
 <blockquote>
@@ -174,12 +173,12 @@
 &lt;/replaceregexp&gt;
 </pre></blockquote>
 <p>replaces all <tt>\n</tt> markers (beware the quoting of the backslash) by a line break.
-So with input
+So with input</p>
 <blockquote>
 <pre>
 one\ntwo\nthree
 </pre></blockquote>
-would converted to
+<p>would converted to</p>
 <blockquote>
 <pre>
 one
@@ -187,7 +186,7 @@
 three
 </pre>
 </blockquote>
-Beware that inserting line breaks could break file syntax. For example in xml:
+<p>Beware that inserting line breaks could break file syntax. For example in xml:</p>
 <blockquote>
 <pre>
 &lt;root&gt;
@@ -196,10 +195,6 @@
 &lt;/root&gt;
 </pre>
 </blockquote>
-</p>
-
-
 
 </body>
 </html>
-
diff --git a/manual/Tasks/resourcecount.html b/manual/Tasks/resourcecount.html
index a34506b..39d9627 100644
--- a/manual/Tasks/resourcecount.html
+++ b/manual/Tasks/resourcecount.html
@@ -29,9 +29,9 @@
 <h3>Description</h3>
 <p>Display or set a property containing the size of a nested
    <a href="../Types/resources.html#collection">Resource Collection</a>.
-   Can also be used as a condition. <b>Since Apache Ant 1.7</b></p>
+   Can also be used as a condition. <em>Since Apache Ant 1.7</em></p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -101,7 +101,5 @@
 <p>Stores the number of lines of the current buildfile in the property <tt>file.lines</tt>.
 Requires Ant 1.7.1+ as &lt;concat&gt; has to be resource.</p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/retry.html b/manual/Tasks/retry.html
index af68d40..360019f 100644
--- a/manual/Tasks/retry.html
+++ b/manual/Tasks/retry.html
@@ -29,18 +29,18 @@
 <em>Since Apache Ant 1.7.1</em></p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
-  <tr> 
+<table>
+  <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
     <td align="center" valign="top"><b>Required</b></td>
   </tr>
-  <tr> 
+  <tr>
     <td valign="top">retrycount</td>
     <td valign="top">number of times to attempt to execute the nested task</td>
     <td valign="top" align="center">Yes</td>
   </tr>
-  <tr> 
+  <tr>
     <td valign="top">retrydelay</td>
     <td valign="top">number of milliseconds to wait between retry attempts
     task. <em>Since Apache Ant 1.8.3</em></td>
@@ -52,7 +52,7 @@
 <h3>Example</h3>
 <pre>
 &lt;retry retrycount="3"&gt;
-  &lt;get src="http://www.unreliable-server.com/unreliable.tar.gz" 
+  &lt;get src="http://www.unreliable-server.com/unreliable.tar.gz"
        dest="/home/retry/unreliable.tar.gz" /&gt;
 &lt;/retry&gt;
 </pre>
diff --git a/manual/Tasks/rexec.html b/manual/Tasks/rexec.html
index 02f6fe2..7874c7b 100644
--- a/manual/Tasks/rexec.html
+++ b/manual/Tasks/rexec.html
@@ -24,13 +24,13 @@
 
 <body>
 
-<h2><a name="rexec">RExec</a></h2>
+<h2 id="rexec">RExec</h2>
 <h3>Description</h3>
 Task to automate a remote rexec session. Just like the Telnet task,
 it uses nested <tt>&lt;read&gt;</tt> to indicate strings to wait for, and
 <tt>&lt;write&gt;</tt> tags to specify text to send to the remote process.
 
-<p><b>Note:</b> This task depends on external libraries not included in the Apache Ant distribution.
+<p><strong>Note</strong>: This task depends on external libraries not included in the Apache Ant distribution.
 See <a href="../install.html#librarydependencies">Library Dependencies</a> for more information.</p>
 
 <p>You can specify the commands you want to execute as nested elements
@@ -39,7 +39,7 @@
 username and password attributes as well.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -76,16 +76,16 @@
      <td>No</td>
   </tr>
 </table>
-<h3><a name="nested">Nested Elements</a></h3>
+<h3 id="nested">Nested Elements</h3>
 The input to send to the server, and responses to wait for, are
-described as nested elements.  
+described as nested elements.
 
 <h4>read</h4>
 
 <p>declare (as a text child of this element) a string to wait for.
 The element supports the timeout attribute, which overrides any
 timeout specified for the task as a whole. It also has a <tt>string</tt>
-attribute, which is an alternative to specifying the string as 
+attribute, which is an alternative to specifying the string as
 a text element.
 </p>
 <i>It is not necessary to declare a closing <code>&lt;read&gt;</code> element like for the Telnet task. The connection is not broken until the command has completed and
@@ -94,7 +94,7 @@
 <h4>write</h4>
 
 <p>describes the text to send to the server. The <tt>echo</tt> boolean
-attribute controls whether the string is echoed to the local log; 
+attribute controls whether the string is echoed to the local log;
 this is "true" by default
 </p>
 <h3>Example</h3>
@@ -109,8 +109,5 @@
 &lt;rexec port=&quot;80&quot; userid=&quot;bob&quot; password=&quot;badpass&quot; server=&quot;localhost&quot; command=&quot;ls&quot;/&gt;
 </pre></blockquote>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/rmic.html b/manual/Tasks/rmic.html
index fa927bf..92bd28d 100644
--- a/manual/Tasks/rmic.html
+++ b/manual/Tasks/rmic.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="rmic">Rmic</a></h2>
+<h2 id="rmic">Rmic</h2>
 <h3>Description</h3>
 <p>Runs the rmic compiler for a certain class.</p>
 <p>Rmic can be run on a single class (as specified with the classname
@@ -47,27 +47,23 @@
 (<code>dir</code> becomes <code>base</code>) as well as the nested
 <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
 <code>&lt;patternset&gt;</code> elements.</p>
-<p>It is possible to use different compilers. This can be selected
+<p id="compilervalues">It is possible to use different compilers. This can be selected
 with the &quot;build.rmic&quot; property, the <code>compiler</code>
-attribute. or a nested element.
-<a name="compilervalues">Here are the choices</a>:</p>
+attribute, or a nested element. Here are the choices:</p>
 <ul>
   <li>default -the default compiler (kaffe, sun or forking) for the platform.
-  <li>sun (the standard compiler of the JDK &lt; JDK 9)</li>
-  <li>kaffe (the standard compiler of <a href="http://www.kaffe.org" target="_top">Kaffe</a>)</li>
+  <li>sun - the standard compiler of the JDK &lt; 9</li>
+  <li>kaffe - the standard compiler of <a href="http://www.kaffe.org" target="_top">Kaffe</a></li>
   <li>weblogic</li>
-  <li>forking - the sun compiler forked into a separate process (since
-    Apache Ant 1.7). Starting with Ant 1.9.8 this is the default when
-    running on JDK 9+.</li>
-  <li>xnew - the sun compiler forked into a separate process,
-      with the -Xnew option (since Ant 1.7).
-    This is the most reliable way to use -Xnew.
-    <br></br>JDK9 has removed support for -Xnew and starting with Ant
-    1.9.8 this option will be rejected by ant when running on JDK9.</li>
-    <li> "" (empty string). This has the same behaviour as not setting the compiler attribute.
+  <li>forking - (<em>since Apache Ant 1.7</em>) the sun compiler forked into a separate process.
+    <em>Since Ant 1.9.8</em>, this is the default when running on JDK 9+.</li>
+  <li>xnew - (<em>since Ant 1.7</em>) the sun compiler forked into a separate process,
+    with the -Xnew option. This is the most reliable way to use -Xnew.<br>
+    JDK 9 has removed support for -Xnew and <em>since Ant 1.9.8</em>
+    this option will be rejected when running on JDK 9.</li>
+  <li> "" (empty string). This has the same behaviour as not setting the compiler attribute.
     First the value of <tt>build.rmic</tt> is used if defined, and if not, the default
-    for the platform is chosen. If build.rmic is set to this, you get the default.
-
+    for the platform is chosen. If build.rmic is set to this, you get the default.</li>
 </ul>
 
 <p>The <a href="http://dione.zcu.cz/~toman40/miniRMI/">miniRMI</a>
@@ -75,7 +71,7 @@
 please consult miniRMI's documentation to learn how to use it.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -112,10 +108,10 @@
     <td valign="top">stubversion</td>
     <td valign="top">Specify the JDK version for the generated stub code.
  Specify &quot;1.1&quot; to pass the &quot;-v1.1&quot; option to rmic,
- "1.2" for -v12, compat for -vcompat. <br>
-        Since Ant1.7, if you do not specify a version, and do not ask
+ "1.2" for -v12, compat for -vcompat.<br>
+        <em>Since Ant 1.7</em>, if you do not specify a version, and do not ask
         for iiop or idl files, "compat" is selected.
- 
+
  </td>
     <td align="center" valign="top">No, default="compat"</td>
   </tr>
@@ -162,7 +158,7 @@
   </tr>
   <tr>
     <td valign="top">verify</td>
-    <td valign="top">check that classes implement Remote before handing them 
+    <td valign="top">check that classes implement Remote before handing them
         to rmic (default is false)</td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -192,13 +188,13 @@
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
-    <td valign="top">includeAntRuntime</td> 
+    <td valign="top">includeAntRuntime</td>
     <td valign="top">whether to include the Ant run-time libraries;
       defaults to <code>yes</code>.</td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
-    <td valign="top">includeJavaRuntime</td> 
+    <td valign="top">includeJavaRuntime</td>
     <td valign="top">whether to include the default run-time
       libraries from the executing VM; defaults to <code>no</code>.</td>
     <td align="center" valign="top">No</td>
@@ -237,7 +233,7 @@
   </tr>
 </table>
 
-<p><a name="footnote-1">*1</a>:
+<p id="footnote-1">*1:</p>
 <ul>
   <li>Maintaining compatibility, <code>base</code>, when specified by
     itself, serves as both the parent directory for any source files
@@ -249,7 +245,6 @@
     must be specified and exist, or a runtime error will
     occur.</li>
 </ul>
-</p>
 
 <h3>Parameters specified as nested elements</h3>
 <h4>classpath and extdirs</h4>
@@ -265,7 +260,7 @@
 Arguments</a> but have an additional attribute that can be used to
 enable arguments only if a given compiler implementation will be
 used.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -275,7 +270,7 @@
     <td valign="top">value</td>
     <td align="center" rowspan="4">See
     <a href="../using.html#arg">Command-line Arguments</a>.</td>
-    <td align="center" rowspan="4">Exactly one of these.</td>
+    <td align="center" rowspan="4">Exactly one of these</td>
   </tr>
   <tr>
     <td valign="top">line</td>
@@ -290,7 +285,7 @@
     <td valign="top">prefix</td>
     <td align="center" rowspan="2">See
     <a href="../using.html#arg">Command-line Arguments</a>.
-    <em>Since Ant 1.8.</em></td>
+    <em>Since Ant 1.8</em>.</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -308,7 +303,7 @@
   </tr>
 </table>
 
-<h4>compilerclasspath <em>since Ant 1.8.0</em></h4>
+<h4>compilerclasspath (<em>since Ant 1.8.0</em>)</h4>
 
 <p>A <a href="../using.html#path">PATH like structure</a> holding the
   classpath to use when loading the compiler implementation if a
@@ -316,7 +311,7 @@
   using one of the built-in compilers.</p>
 
 <h4>Any nested element of a type that implements RmicAdapter
-  <em>since Ant 1.8.0</em></h4>
+  (<em>since Ant 1.8.0</em>)</h4>
 
 <p>If a defined type implements the <code>RmicAdapter</code>
   interface a nested element of that type can be used as an
@@ -354,4 +349,3 @@
 
 </body>
 </html>
-
diff --git a/manual/Tasks/rpm.html b/manual/Tasks/rpm.html
index 691d391..c430f62 100644
--- a/manual/Tasks/rpm.html
+++ b/manual/Tasks/rpm.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="rpm">Rpm</a></h2>
+<h2 id="rpm">Rpm</h2>
 <h3>Description</h3>
 <p>
   A basic task for invoking the rpm executable to build a RedHat Package Manager Linux installation
@@ -32,7 +32,7 @@
 </p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -73,7 +73,7 @@
   </tr>
   <tr>
     <td valign="top">removeSource</td>
-    <td valign="top">Flag (optional, default=false) 
+    <td valign="top">Flag (optional, default=false)
         to remove the sources after the build.
         See the the <tt>--rmsource</tt> option of rpmbuild.</td>
     <td align="center" valign="top">No</td>
@@ -104,7 +104,7 @@
   </tr>
   <tr>
     <td valign="top">failOnError</td>
-    <td valign="top">Stop the buildprocess if the RPM build command exits with 
+    <td valign="top">Stop the buildprocess if the RPM build command exits with
        a non-zero returncode. Defaults to false</td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -120,4 +120,3 @@
 </pre>
 </body>
 </html>
-
diff --git a/manual/Tasks/schemavalidate.html b/manual/Tasks/schemavalidate.html
index 1aac2ef..40b3c21 100644
--- a/manual/Tasks/schemavalidate.html
+++ b/manual/Tasks/schemavalidate.html
@@ -23,7 +23,7 @@
 
 <body>
 
-<h2><a name="schemavalidate">SchemaValidate</a></h2>
+<h2 id="schemavalidate">SchemaValidate</h2>
 <h3>Description</h3>
 
 <p>This <tt>schemavalidate</tt> task validates XML files described by an XML Schema.
@@ -42,7 +42,8 @@
 sources of schema documents, so you can still delegate lookup to a catalog, you
 just need to list all schema URIs and their URL equivalents.
 
-<p>This task supports the use of nested
+<p>This task supports the use of nested</p>
+<ul>
   <li><a href="../Types/xmlcatalog.html"><tt>&lt;xmlcatalog&gt;</tt></a> elements</li>
   <li> <tt>&lt;schema&gt;</tt> elements, that bind a namespace URI to a URL or a
   local filename.
@@ -51,16 +52,16 @@
       These can be any number of
       <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"><tt>http://xml.org/sax/features/</tt></a>
       or other features that your parser may support.</li>
-  <li><tt>&lt;property&gt;</tt> elements, containing string properties
-</p>
+<li><tt>&lt;property&gt;</tt> elements, containing string properties</li>
+</ul>
 
 <p>
 The task only supports SAX2 or later parsers: it is an error to specify a SAX1
-parser. 
-
+parser.
+</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -73,14 +74,14 @@
   </tr>
   <tr>
     <td valign="top">classpathref</td>
-    <td valign="top">where to find the parser class. 
+    <td valign="top">where to find the parser class.
     Optionally can use an embedded <tt>&lt;classpath&gt;</tt> element.</td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
     <td valign="top">disableDTD</td>
     <td valign="top">
-      Flag to disable DTD support. DTD support is needed to 
+      Flag to disable DTD support. DTD support is needed to
       validate XSD files themselves, amongst others.
     </td>
     <td valign="top" align="center">No - default false</td>
@@ -102,7 +103,7 @@
     </td>
     <td valign="top" align="center">No - default true</td>
   </tr>
-  
+
   <tr>
     <td valign="top">lenient</td>
     <td valign="top">
@@ -113,7 +114,7 @@
   <tr>
     <td valign="top">noNamespaceFile</td>
     <td valign="top">
-      filename of a no-namespace XSD file to provide the 
+      filename of a no-namespace XSD file to provide the
       schema for no-namespace XML content.
     </td>
     <td valign="top" align="center">No</td>
@@ -121,7 +122,7 @@
   <tr>
     <td valign="top">noNamespaceURL</td>
     <td valign="top">
-      URL of a no-namespace XSD file to provide the 
+      URL of a no-namespace XSD file to provide the
       schema for no-namespace XML content.
     </td>
     <td valign="top" align="center">No</td>
@@ -133,15 +134,14 @@
   </tr>
 </table>
 
-<h3><a name="nested">Nested Elements</a></h3>
-
+<h3 id="nested">Nested Elements</h3>
 
 <h4>schema</h4>
 <p>
 Identify the name and location of a schema that may be used in validating
 the document(s).
 </p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -155,12 +155,11 @@
   <tr>
     <td valign="top">url</td>
     <td valign="top">URL of the schema</td>
-    <td align="center" valign="top">One of url or file is required</td>
+    <td align="center" valign="top" rowspan="2">Exactly one of the two</td>
   </tr>
   <tr>
     <td valign="top">file</td>
     <td valign="top">file of the schema</td>
-    <td align="center" valign="top">One of url or file is required</td>
   </tr>
 </table>
 
@@ -168,7 +167,7 @@
 <p>
 <tt>&lt;dtd&gt;</tt> is used to specify different locations for DTD resolution.
 </p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -197,7 +196,7 @@
 SAX features are defined here:
  <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"><tt>http://xml.org/sax/features/</tt></a><br>
  </p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -214,7 +213,6 @@
     <td align="center" valign="top">Yes</td>
   </tr>
 </table>
-</p>
 
 <h4>property</h4>
 <p>The <tt>&lt;property&gt;</tt> element is used to set properties.
@@ -222,7 +220,7 @@
  <a href="http://xml.apache.org/xerces-j/properties.html">XML Parser properties</a>
 Properties can be used to set the schema used to validate the XML file.
 </p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -239,8 +237,6 @@
     <td align="center" valign="top">Yes</td>
   </tr>
 </table>
-</p>
-
 
 <h3>Examples</h3>
 <pre>
@@ -250,7 +246,7 @@
     &lt;/schemavalidate&gt;
 </pre>
 Validate a document against an XML schema. The document does not declare
-any schema itself, which is why the <tt>noNamespaceFile</tt> is needed. 
+any schema itself, which is why the <tt>noNamespaceFile</tt> is needed.
 <pre>
     &lt;presetdef name="validate-soap"&gt;
       &lt;schemavalidate&gt;
@@ -266,18 +262,16 @@
     &lt;/presetdef&gt;
 </pre>
 Declare a new preset task, <tt>&lt;validate-soap&gt;</tt>, that validates
-XSD and WSDL documents against the relevant specifications. 
-To validate XSD documents, you also need XMLSchema.dtd and datatypes.dtd in 
+XSD and WSDL documents against the relevant specifications.
+To validate XSD documents, you also need XMLSchema.dtd and datatypes.dtd in
 the same directory as XMLSchema.xsd, or pointed to via the catalog. All
 these files can be fetched from <a href="http://www.w3.org/2001/XMLSchema">
-the W3C</a>. 
+the W3C</a>.
 <pre>
     &lt;validate-soap file="xml/test.xsd"/&gt;
 </pre>
 Use the preset task defined above to validate an XML Schema document.
 <br>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/scp.html b/manual/Tasks/scp.html
index 47a3cee..bcd9964 100644
--- a/manual/Tasks/scp.html
+++ b/manual/Tasks/scp.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="scp">SCP</a></h2>
+<h2 id="scp">SCP</h2>
 <h3>Description</h3>
 
 <p><em>since Apache Ant 1.6</em></p>
@@ -33,7 +33,7 @@
 FileSet <i>only</i> works for copying files from the local machine to a
 remote machine.</p>
 
-<p><b>Note:</b> This task depends on external libraries not included
+<p><strong>Note</strong>: This task depends on external libraries not included
 in the Ant distribution.  See <a
 href="../install.html#librarydependencies">Library Dependencies</a>
 for more information.  This task has been tested with jsch-0.1.2 and later.</p>
@@ -41,7 +41,7 @@
 <p>See also the <a href="sshexec.html">sshexec task</a></p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -81,7 +81,7 @@
     authentication or specify the password attribute.  The way remote
     path is recognized is whether it contains @ character or not. This
     will not work if your localPath contains @ character.</td>
-    <td valian="top" align="center">Yes</td>
+    <td valign="top" align="center">Yes</td>
   </tr>
   <tr>
     <td valign="top">localTodir</td>
@@ -90,48 +90,48 @@
     reason this was added was that when you give todir attribute it is
     treated as remote if it contains @ character. This character can
     exist also in local paths.  <em>since Ant 1.6.2</em></td>
-    <td valian="top" align="center">Alternative to todir attribute.</td>
+    <td valign="top" align="center">Alternative to todir attribute.</td>
   </tr>
   <tr>
     <td valign="top">localTofile</td>
     <td valign="top">Changes the file name to the given name while
     receiving it, only useful if receiving a single file.  <em>since
     Ant 1.6.2</em></td>
-    <td valian="top" align="center">Alternative to todir attribute.</td>
+    <td valign="top" align="center">Alternative to todir attribute.</td>
   </tr>
   <tr>
     <td valign="top">remoteTodir</td>
     <td valign="top">This is an alternative to the todir
     attribute. But this must always point to a remote directory.
     <em>since Ant 1.6.2</em></td>
-    <td valian="top" align="center">Alternative to todir attribute.</td>
+    <td valign="top" align="center">Alternative to todir attribute.</td>
   </tr>
   <tr>
     <td valign="top">remoteTofile</td>
     <td valign="top">Changes the file name to the given name while
     sending it, only useful if sending a single file.  <em>since
     Ant 1.6.2</em></td>
-    <td valian="top" align="center">Alternative to todir attribute.</td>
+    <td valign="top" align="center">Alternative to todir attribute.</td>
   </tr>
   <tr>
     <td valign="top">port</td>
     <td valign="top">The port to connect to on the remote host.</td>
-    <td valian="top" align="center">No, defaults to 22.</td>
+    <td valign="top" align="center">No, defaults to 22.</td>
   </tr>
   <tr>
     <td valign="top">trust</td>
     <td valign="top">This trusts all unknown hosts if set to yes/true.<br>
-      <strong>Note</strong> If you set this to false (the default), the
+      <strong>Note</strong>: If you set this to false (the default), the
       host you connect to must be listed in your knownhosts file, this
       also implies that the file exists.</td>
-    <td valian="top" align="center">No, defaults to No.</td>
+    <td valign="top" align="center">No, defaults to No.</td>
   </tr>
   <tr>
     <td valign="top">knownhosts</td>
     <td valign="top">This sets the known hosts file to use to validate
     the identity of the remote host.  This must be a SSH2 format file.
     SSH1 format is not supported.</td>
-    <td valian="top" align="center">No, defaults to
+    <td valign="top" align="center">No, defaults to
     ${user.home}/.ssh/known_hosts.</td>
   </tr>
   <tr>
@@ -248,10 +248,9 @@
 authentication.</b></p>
 <pre>
   &lt;scp file=&quot;myfile.txt&quot;
-       todir=&quot;user@somehost:/home/chuck&quot; 
+       todir=&quot;user@somehost:/home/chuck&quot;
        keyfile=&quot;${user.home}/.ssh/id_dsa&quot;
-       passphrase=&quot;my extremely secret passphrase&quot;
-  /&gt;
+       passphrase=&quot;my extremely secret passphrase&quot;/&gt;
 </pre>
 
 <p><b>Copy a single remote file to a local directory</b></p>
@@ -292,26 +291,25 @@
   &lt;/scp&gt;
 </pre>
 
-<p><strong>Security Note:</strong>  Hard coding passwords and/or usernames
+<p><strong>Security Note</strong>: Hardcoding passwords and/or usernames
 in scp task can be a serious security hole.  Consider using variable
 substitution and include the password on the command line.  For example:
 <p>
 <pre>
     &lt;scp todir=&quot;${username}:${password}@host:/dir&quot; ...&gt;
 </pre>
-Invoking ant with the following command line:
+Invoking Ant with the following command line:
 <pre>
     ant -Dusername=me -Dpassword=mypassword target1 target2
 </pre>
-
+<p>
 Is slightly better, but the username/password is exposed to all users on an Unix
 system (via the ps command). The best approach is to use the
 <code>&lt;input&gt;</code> task and/or retrieve the password from a (secured)
 .properties file.
+</p>
 
-<p>
-
-<p><strong>Unix Note:</strong> File permissions are not retained when files
+<p><strong>Unix Note</strong>: File permissions are not retained when files
 are downloaded; they end up with the default <code>UMASK</code> permissions
 instead. This is caused by the lack of any means to query or set file
 permissions in the current Java runtimes. If you need a permission-
@@ -319,8 +317,5 @@
 instead.
 </p>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/script.html b/manual/Tasks/script.html
index fb00822..eedbb17 100644
--- a/manual/Tasks/script.html
+++ b/manual/Tasks/script.html
@@ -17,28 +17,28 @@
 <html>
 
 <head>
-<meta http-equiv="Content-Language" content="en-us"></meta>
+<meta http-equiv="Content-Language" content="en-us">
 <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
 <title>Script Task</title>
 </head>
 
 <body>
 
-<h2><a name="script">Script</a></h2>
+<h2 id="script">Script</h2>
 <h3>Description</h3>
   <p>Execute a script in a
     <a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a>
     or
     <a href="https://scripting.dev.java.net">JSR 223</a>  supported language.
   </p>
-  <p><b>Note:</b>
+  <p><strong>Note</strong>:
     This task depends on external libraries not included in the Apache Ant distribution.
     See <a href="../install.html#librarydependencies">Library Dependencies</a>
     for more information.
   </p>
   <p>
     The task may use the BSF scripting manager or the JSR 223 manager that
-    is included in JDK6 and higher. This is controlled by the <code>manager</code>
+    is included in JDK 6 and higher. This is controlled by the <code>manager</code>
     attribute. The JSR 223 scripting manager is indicated by "javax".
   </p>
   <p>All items (tasks, targets, etc) of the running project are
@@ -67,7 +67,7 @@
 different location values.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -82,18 +82,18 @@
   <tr>
     <td valign="top">manager</td>
     <td valign="top">
-      <em>Since: Ant 1.7. </em>
+      <em>Since Ant 1.7</em>.
       The script engine manager to use. This can have
       one of three values ("auto", "bsf" or "javax").
       The default value is "auto".
-      <dl>
+      <ul>
         <li>"bsf" use the BSF scripting manager to run
           the language.</li>
         <li>"javax" use the <em>javax.scripting</em> manager
-          to run the language. (This will only work for JDK6 and higher).</li>
+          to run the language. (This will only work for JDK 6 and higher).</li>
         <li>"auto" use the BSF engine if it exists,
           otherwise use the <em>javax.scripting</em> manager.</li>
-      </dl>
+      </ul>
     </td>
     <td valign="top" align="center">No</td>
   </tr>
@@ -103,6 +103,11 @@
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
+    <td valign="top">encoding</td>
+    <td valign="top">The encoding of the script as a file. <em>Since Ant 1.10.2</em>.</td>
+    <td valign="top" align="center">No - defaults to default JVM encoding</td>
+  </tr>
+  <tr>
     <td valign="top">setbeans</td>
     <td valign="top">
       This attribute controls whether to set variables for
@@ -132,13 +137,14 @@
 <h4>classpath</h4>
   <p><em>Since Ant 1.7</em></p>
 <p>
-  <code>Script</code>'s <code>classpath</code> attribute is a 
+  <code>Script</code>'s <code>classpath</code> attribute is a
   <a href="../using.html#path">path-like structure</a> and can also be set via a nested
   <code>&lt;classpath&gt;</code> element.
+</p>
   <p>
     If a classpath is set, it will be used as the current thread
     context classloader, and
-    as the classloader given to the BSF manager. 
+    as the classloader given to the BSF manager.
     This means that it can be used to specify
     the classpath containing the language implementation for BSF
     or for JSR 223 managers.
@@ -147,14 +153,13 @@
     specific jar files.
   </p>
   <p>
-    <b>NB: (Since Ant 1.7.1)</b>
+    <strong>Note</strong>: (<em>since Ant 1.7.1</em>)
     This classpath <em>can</em> be used to
     specify the location of
     the BSF jar file and/or languages
     that have engines in the BSF jar file. This includes the
     javascript, jython, netrexx and jacl languages.
   </p>
-</p>
 <h3>Examples</h3>
 The following snippet shows use of five different languages:
   <blockquote><pre>
@@ -282,7 +287,7 @@
       // Access to Ant-Properties by their names
       dir      = <font color=blue>project</font>.getProperty("fs.dir");
       includes = <font color=blue>MyProject</font>.getProperty("fs.includes");
-      excludes = <font color=blue>self.getProject()</font>  .<font color=blue>getProperty("fs.excludes")</font>;
+      excludes = <font color=blue>self.getProject()</font>.<font color=blue>getProperty("fs.excludes")</font>;
 
       // Create a &lt;fileset dir="" includes=""/&gt;
       fs = project.<font color=blue>createDataType("fileset")</font>;
diff --git a/manual/Tasks/scriptdef.html b/manual/Tasks/scriptdef.html
index 38c3fff..1d016e6 100644
--- a/manual/Tasks/scriptdef.html
+++ b/manual/Tasks/scriptdef.html
@@ -24,11 +24,11 @@
 
 <body>
 
-<h2><a name="script">Scriptdef</a></h2>
+<h2 id="script">Scriptdef</h2>
 <h3>Description</h3>
 <p>Scriptdef can be used to define an Apache Ant task using a scripting language. Ant
 scripting languages supported by
-<a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a> 
+<a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a>
 or
   <a href="https://scripting.dev.java.net">JSR 223</a>
 may be
@@ -41,7 +41,7 @@
 into a Java based custom task.
 </p>
 
-<p><b>Note:</b> This task depends on external libraries not included in the
+<p><strong>Note</strong>: This task depends on external libraries not included in the
 Ant distribution. See
 <a href="../install.html#librarydependencies">Library Dependencies</a>
 for more information.</p>
@@ -58,21 +58,21 @@
 The instances in this list may be accessed by an integer index.
 </p>
 
-<p><b>Note:</b> Ant will turn all attribute and element names into all
+<p><strong>Note</strong>: Ant will turn all attribute and element names into all
 lowercase names, so even if you use name="SomeAttribute", you'll have
 to use "someattribute" to retrieve the attribute's value from the
 <code>attributes</code> collection.</p>
 
-<p>The name "self" (<i>since Ant 1.6.3</i>) is a pre-defined reference to the
+<p>The name "self" (<em>since Ant 1.6.3</em>) is a pre-defined reference to the
     script def task instance.
     It can be used for logging, or for integration with the rest of
-    ant. the <code>self.text attribute</code> contains
+    Ant. the <code>self.text attribute</code> contains
     any nested text passed to the script</p>
 
-<p>If an attribute or element is not passed in, 
-then <code>attributes.get()</code> or <code>elements.get()</code> will 
-return null. It is up to the script to perform any checks and validation. 
-<code>self.fail(String message)</code>can be used to raise a 
+<p>If an attribute or element is not passed in,
+then <code>attributes.get()</code> or <code>elements.get()</code> will
+return null. It is up to the script to perform any checks and validation.
+<code>self.fail(String message)</code>can be used to raise a
 <code>BuildException</code>.
 </p>
 
@@ -84,7 +84,7 @@
 
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -116,6 +116,20 @@
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
+    <td valign="top">encoding</td>
+    <td valign="top">The encoding of the script as a file. <em>since Ant 1.10.2</em>.</td>
+    <td valign="top" align="center">No - defaults to default JVM encoding</td>
+  </tr>
+  <tr>
+    <td valign="top">compiled</td>
+    <td valign="top">If true, the script is compiled before the first
+    evaluation for faster multiple executions, on the condition that the <em>manager</em> is "javax" and the
+    target engine implements <code>javax.script.Compilable</code>.
+    Note that the <code>bsf</code> manager may automatically compiles the script.
+    <em>since Ant 1.10.2</em>.</td>
+    <td valign="top" align="center">No - defaults to false</td>
+  </tr>
+  <tr>
     <td valign="top">uri</td>
     <td valign="top">
       The XML namespace uri that this definition should live in.
@@ -138,7 +152,7 @@
     <tr>
       <td valign="top">loaderRef</td>
       <td valign="top">the name of the loader that is
-        used to load the script, constructed from the specified 
+        used to load the script, constructed from the specified
         classpath. This allows multiple script definitions
         to reuse the same class loader.
       </td>
@@ -148,7 +162,7 @@
 
 <h3>Nested elements</h3>
 <h4>attribute</h4>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -162,7 +176,7 @@
 </table>
 
 <h4>element</h4>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -192,8 +206,8 @@
   </tr>
   <tr>
     <td valign="top">any resource or resource collection</td>
-    <td valign="top">Since Ant1.7.1, this task can load scripts
-    from any resource supplied as a nested element. when </td>
+    <td valign="top"><em>Since Ant 1.7.1</em>, this task can load scripts
+    from any resource supplied as a nested element.</td>
     <td valign="top" align="center">No</td>
   </tr>
 
@@ -275,10 +289,10 @@
 Script errors are only detected when a script task is actually executed.
 </p>
 <p>
-    The next example does uses nested text in Jython. It also declares 
-    the script in a new xml namespace, which must be used to refer to 
-    the task. Declaring scripts in a new namespace guarantees that Ant will 
-    not create a task of the same (namespace,localname) name pair. 
+    The next example does uses nested text in Jython. It also declares
+    the script in a new xml namespace, which must be used to refer to
+    the task. Declaring scripts in a new namespace guarantees that Ant will
+    not create a task of the same (namespace,localname) name pair.
 </p>
 
 <pre>
@@ -321,12 +335,9 @@
 <h3>Testing Scripts</h3>
 
 <p>
-The easiest way to test scripts is to use the 
+The easiest way to test scripts is to use the
 <a href="http://ant.apache.org/antlibs/antunit/">AntUnit</a> ant library.
-This will run all targets in a script that begin with "test" (and their dependencies). </p>
-
-
-
+This will run all targets in a script that begin with "test" (and their dependencies).</p>
 
 </body>
 </html>
diff --git a/manual/Tasks/sequential.html b/manual/Tasks/sequential.html
index d3deda6..3551d60 100644
--- a/manual/Tasks/sequential.html
+++ b/manual/Tasks/sequential.html
@@ -26,13 +26,13 @@
 
 <h2>Sequential</h2>
 <h3>Description</h3>
-<p>Sequential is a container task - it can contain other Apache Ant tasks. The nested 
-tasks are simply executed in sequence. Sequential's primary use is to support 
-the sequential execution of a subset of tasks within the 
+<p>Sequential is a container task - it can contain other Apache Ant tasks. The nested
+tasks are simply executed in sequence. Sequential's primary use is to support
+the sequential execution of a subset of tasks within the
 <a href="parallel.html">parallel</a> task</p>
 
-<p>The sequential task has no attributes and does not support any nested 
-elements apart from Ant tasks. Any valid Ant task may be embedded within the 
+<p>The sequential task has no attributes and does not support any nested
+elements apart from Ant tasks. Any valid Ant task may be embedded within the
 sequential task.</p>
 
 <h3>Example</h3>
@@ -47,9 +47,7 @@
 &lt;/parallel&gt;
 </pre>
 <p>This example shows how the sequential task is used to execute three tasks in
-sequence, while another task is being executed in a separate thread. </p>
-
+sequence, while another task is being executed in a separate thread.</p>
 
 </body>
 </html>
-
diff --git a/manual/Tasks/serverdeploy.html b/manual/Tasks/serverdeploy.html
index 87d0777..bfe738e 100644
--- a/manual/Tasks/serverdeploy.html
+++ b/manual/Tasks/serverdeploy.html
@@ -25,7 +25,7 @@
 
 <body>
 
-<h1><a name="serverdeploy">Apache Ant ServerDeploy User Manual</a></h1>
+<h1 id="serverdeploy">Apache Ant ServerDeploy User Manual</h1>
 <p>by</p>
 <!-- Names are in alphabetical order, on last name -->
 <ul>
@@ -33,21 +33,21 @@
 <li>Cyrille Morvan (<a href="mailto:cmorvan@ingenosya.com">cmorvan@ingenosya.com</a>)</li>
 </ul>
 
-</p>
-<hr>
-<p> At present the tasks support:<br>
+<hr/>
+<p>At present the tasks support:</p>
 
 <ul>
 <li><a href="http://www.bea.com" target="_top">Weblogic</a> servers</li>
 <li><a href="http://www.objectweb.org/jonas/" target="_top">JOnAS</a>
 2.4 Open Source EJB server</li>
 </ul>
+<p>
 Over time we expect further optional tasks  to support additional J2EE Servers.
 </p>
 
-<hr>
+<hr/>
 
-<table border="1" cellpadding="5">
+<table>
 <tr><td>Task</td><td colspan="2">Application Servers</td></tr>
 <tr><td rowspan="4"><a href="#serverdeploy_element">serverdeploy</a></td><td colspan="2" align="center"><b>Nested Elements</b></td></tr>
 <tr><td><a href="#serverdeploy_generic">generic</a></td><td>Generic task</td></tr>
@@ -56,8 +56,7 @@
 
 </table>
 
-<a name="serverdeploy_element">
-<h2>ServerDeploy element</h2>
+<h2 id="serverdeploy_element">ServerDeploy element</h2>
 
 <h3><b>Description:</b></h3>
 
@@ -69,7 +68,7 @@
 </p>
 
 <h3>Parameters:</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -98,7 +97,7 @@
 <h3>Vendor-specific nested elements</h3>
 
 <h3>Parameters used for all tools:</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -129,8 +128,7 @@
 
 <p>Also supported are nested vendor-specific elements.</p>
 
-<a name="serverdeploy_generic">
-<h3>Generic element</h3>
+<h3 id="serverdeploy_generic">Generic element</h3>
 This element is provided for generic Java-based deployment tools.
 The generic task accepts (but does not require) nested <code>arg</code>
 and <code>jvmarg</code> elements.
@@ -138,8 +136,7 @@
 that a vendor-specific element be used over the generic one if at all
 possible.
 <p>The following attributes are supported by the generic element.</p>
-<p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -152,7 +149,6 @@
     <td>Yes</td>
   </tr>
 </table>
-</p>
 
 <h3>Nested Elements</h3>
 <p>The generic element supports nested <code>&lt;arg&gt;</code> and <code>&lt;jvmarg&gt;</code> elements.</p>
@@ -176,8 +172,7 @@
     &lt;/serverdeploy&gt;
 </pre>
 
-<a name="serverdeploy_weblogic">
-<h3>WebLogic element</h3>
+<h3 id="serverdeploy_weblogic">WebLogic element</h3>
 <p>
 The WebLogic element contains additional attributes to run the
 <code>weblogic.deploy</code> deployment tool.
@@ -190,7 +185,7 @@
 attribute is omitted, it defaults to "system".  The <code>password</code> attribute is
 required for all actions.
 <p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -247,17 +242,16 @@
     &lt;/serverdeploy&gt;
 </pre>
 
-<a name="serverdeploy_jonas">
-<h3>JOnAS (Java Open Application Server) element</h3>
+<h3 id="serverdeploy_jonas">JOnAS (Java Open Application Server) element</h3>
 <p>
 The JOnAS element contains additional attributes to run the
 <code>JonasAdmin</code> deployment tool.
 <p>Valid actions for the tool are <code>deploy</code>, <code>undeploy</code>,
 <code>list</code> and <code>update</code>.
-<p>You can't use <code>user</code> and <code>password</code> property with this 
+<p>You can't use <code>user</code> and <code>password</code> property with this
 task.
 <p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -272,7 +266,7 @@
     <td valign="top">orb</td>
     <td valign="top">Choose your ORB : RMI, JEREMIE, DAVID, ... If omitted, it defaults
      to the one present in classpath. The corresponding JOnAS JAR is
-     automatically added to the classpath. If your orb is DAVID (RMI/IIOP) you must 
+     automatically added to the classpath. If your orb is DAVID (RMI/IIOP) you must
      specify davidhost and davidport properties.</td>
     <td>No</td>
   </tr>
@@ -329,7 +323,5 @@
     &lt;/serverdeploy&gt;
 </pre>
 
-
-
 </body>
 </html>
diff --git a/manual/Tasks/setpermissions.html b/manual/Tasks/setpermissions.html
new file mode 100644
index 0000000..28bf999
--- /dev/null
+++ b/manual/Tasks/setpermissions.html
@@ -0,0 +1,109 @@
+<!--
+   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.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>SetPermissions Task</title>
+</head>
+
+<body>
+
+<h2 id="setpermissions">SetPermissions</h2>
+<p><em>Since Ant 1.10.0</em>.</p>
+<h3>Description</h3>
+<p>Changes the file permissions using Java's NIO support for
+  permissions.</p>
+<p>This task provides a subset of the platform specific abilities of
+  <a href="chmod.html">chmod</a> and <a href="attrib.html">attrib</a>
+  in a platform independent way.</p>
+<p>If no permissions are specified either via the mode or the
+  permissions attribute, then all permissions will be removed from the
+  nested resources.</p>
+<p>The task accepts arbitrary resources as part of the nested
+  resource collections, but not all resources support setting
+  permissions. This task won't do anything for resources that don't
+  support setting permissions - for example URLs.</p>
+<p>The permissions are applied to all resources contained within the
+  nested resources collections. You may want to ensure the collection
+  only returns files or directories if you want different sets of
+  permissions to apply to either type of resource.</p>
+
+<h3>Parameters</h3>
+<table>
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">permissions</td>
+    <td valign="top">The permissions to set as comma separated list of
+    names
+    of <a href="http://docs.oracle.com/javase/8/docs/api/java/nio/file/attribute/PosixFilePermission.html">PosixFilePermission</a>
+    values.</td>
+    <td valign="top" align="center">No</td>
+  </tr>
+  <tr>
+    <td valign="top">mode</td>
+    <td valign="top">The permissions to set as traditional Unix
+      three-digit octal number.</td>
+    <td valign="top" align="center">No</td>
+  </tr>
+  <tr>
+    <td valign="top">nonPosixMode</td>
+    <td valign="top">What to do if changing the permissions of a file
+      is not possible because the file-system doesn't support POSIX
+      file permissions. Possible options are <code>fail</code> (fail
+      the build), <code>pass</code> (just log an
+      error), <code>tryDosOrFail</code> (at least try to set the
+      read-only flag on DOS file systems, fail if that isn't possible
+      either) and <code>tryDosOrPass</code> (at least try to set the
+      read-only flag on DOS file systems, just log an error if that
+      isn't possible either).</td>
+    <td valign="top" align="center">No, defaults to <code>fail</code></td>
+  </tr>
+  <tr>
+    <td valign="top">failonerror</td>
+    <td valign="top">Whether to stop the build if setting permissions
+      fails.</td>
+    <td valign="top" align="center">No, defaults to true</td>
+  </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>any resource collection</h4>
+<p><a href="../Types/resources.html#collection">Resource
+Collection</a>s are used to select groups of resources.</p>
+<h3>Examples</h3>
+  <blockquote><pre>
+&lt;setpermissions mode=&quot;755&quot;&gt;
+  &lt;file file=&quot;${dist}/start.sh&quot;/&gt;
+&lt;/setpermissions&gt;
+  </pre></blockquote>
+<p>makes the &quot;start.sh&quot; file readable and executable for
+  anyone and in addition writable by the owner.</p>
+  <blockquote><pre>
+&lt;setpermissions permissions=&quot;OWNER_READ,OWNER_WRITE,OWNER_EXECUTE,OTHERS_READ,OTHERS_EXECUTE,GROUP_READ,GROUP_EXECUTE&quot;&gt;
+  &lt;file file=&quot;${dist}/start.sh&quot;/&gt;
+&lt;/setpermissions&gt;
+  </pre></blockquote>
+<p>makes the &quot;start.sh&quot; file readable and executable for
+  anyone and in addition writable by the owner.</p>
+</body>
+</html>
diff --git a/manual/Tasks/setproxy.html b/manual/Tasks/setproxy.html
index 245924c..a191dda 100644
--- a/manual/Tasks/setproxy.html
+++ b/manual/Tasks/setproxy.html
@@ -14,207 +14,127 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-    
+
 <html>
 <head>
   <meta http-equiv="Content-Language" content="en-us">
+  <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
   <title>Setproxy Task</title>
 </head>
 
-<body bgcolor="#ffffff" text="#000000" link="#525D76"
-      alink="#525D76" vlink="#525D76">
+<body>
+<h2>Setproxy Task</h2>
 
-<table border="0" width="100%" cellspacing="4">
+<h3 id="description">Description</h3>
+Sets Java's web proxy properties, so that tasks and code run in the same JVM can have through-the-firewall access to remote web sites, and remote ftp sites. You can nominate an http and ftp proxy, or a socks server, reset the server settings, or do nothing at all.
 
-  <!-- PAGE HEADER -->
+<h3>Examples</h3>
+<pre>&lt;setproxy/&gt;</pre> do nothing
+<pre>&lt;setproxy proxyhost="firewall"/&gt;</pre> set the proxy to firewall:80
+<pre>&lt;setproxy proxyhost="firewall" proxyport="81"/&gt;</pre> set the proxy to firewall:81
+<pre>&lt;setproxy proxyhost=""/&gt;</pre> stop using the http proxy; don't change the socks settings
+<pre>&lt;setproxy socksproxyhost="socksy"/&gt;</pre> use socks via socksy:1080
+<pre>&lt;setproxy socksproxyhost=""/&gt;</pre> stop using the socks server.
+<p>
+You can set a username and password for http with the <tt>proxyHost</tt> and <tt>proxyPassword</tt> attributes. On Java 1.4 and above these can also be used against SOCKS5 servers.
+</p>
+
+<h3 id="attributes">Parameters</h3>
+<table>
   <tr>
-    <td>
-      <table border="0" width="100%"><tr>
-          <td valign="bottom">
-            <font size="+3" face="arial,helvetica,sanserif"><strong>Setproxy Task</strong></font>
-            <br><font face="arial,helvetica,sanserif">Sets Java's web proxy properties, so that tasks and code run in the same JVM can have through-the-firewall access to remote web sites, and remote ftp sites.</font>
-          </td>
-          <td>
-            <!-- PROJECT LOGO -->
-            <a href="http://ant.apache.org/">
-              <img src="../images/ant_logo_large.gif" align="right" alt="Apache Ant" border="0">
-            </a>
-          </td>
-      </tr></table>
+    <td valign="top" align="left">
+      <b>Attribute</b>
+    </td>
+    <td valign="top" align="left">
+      <b>Description</b>
+    </td>
+    <td valign="top" align="left">
+      <b>Type</b>
+    </td>
+    <td valign="top" align="left">
+      <b>Requirement</b>
     </td>
   </tr>
-
-  <!-- START RIGHT SIDE MAIN BODY -->
   <tr>
-    <td  valign="top" align="left">
-
-          <!-- Applying task/long-description -->
-    <!-- Start Description -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-
-      <tr><td bgcolor="#525D76">
-        <font color="#ffffff" face="arial,helvetica.sanserif">
-          <a name="description">
-          <strong>Description</strong></a></font>
-      </td></tr>
-
-      <tr><td><blockquote>
-        Sets Java's web proxy properties, so that tasks and code run in the same JVM can have through-the-firewall access to remote web sites, and remote ftp sites. You can nominate an http and ftp proxy, or a socks server, reset the server settings, or do nothing at all. <p> Examples <pre>&lt;setproxy/&gt;</pre> do nothing <pre>&lt;setproxy proxyhost="firewall"/&gt;</pre> set the proxy to firewall:80 <pre>&lt;setproxy proxyhost="firewall" proxyport="81"/&gt;</pre> set the proxy to firewall:81 <pre>&lt;setproxy proxyhost=""/&gt;</pre> stop using the http proxy; don't change the socks settings <pre>&lt;setproxy socksproxyhost="socksy"/&gt;</pre> use socks via socksy:1080 <pre>&lt;setproxy socksproxyhost=""/&gt;</pre> stop using the socks server. <p> You can set a username and password for http with the <tt>proxyHost</tt> and <tt>proxyPassword</tt> attributes. On Java1.4 and above these can also be used against SOCKS5 servers. </p>
-      </blockquote></td></tr>
-
-    </table>
-    <!-- End Description -->
-
- <!-- Ignore -->
-
-
-
-    <!-- Start Attributes -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#525D76">
-        <font color="#ffffff" face="arial,helvetica.sanserif">
-          <a name="attributes">
-          <strong>Parameters</strong></a></font>
-      </td></tr>
-      <tr><td><blockquote>
-        <table>
-          <tr>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Attribute</b></font>
-        </td>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Description</b></font>
-        </td>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Type</b></font>
-        </td>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Requirement</b></font>
-        </td>
-          </tr>
-    <!-- Attribute Group -->    
-    
-    <!-- Attribute Group -->    
-        <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">nonproxyhosts</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">A list of hosts to bypass the proxy on. These should be separated with the vertical bar character '|'. Only in Java 1.4 does ftp use this list. e.g. fozbot.corp.sun.com|*.eng.sun.com</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left" rowspan="7">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Optional</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">proxyhost</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">the HTTP/ftp proxy host. Set this to "" for the http proxy option to be disabled</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">proxypassword</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Set the password for the proxy. Used only if the proxyUser is set.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">proxyport</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">the HTTP/ftp proxy port number; default is 80</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">int</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">proxyuser</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">set the proxy user. Probably requires a password to accompany this setting. Default=""</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">socksproxyhost</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">The name of a Socks server. Set to "" to turn socks proxying off.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">socksproxyport</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Set the ProxyPort for socks connections. The default value is 1080</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">int</font>
-        </td>
-    </tr>
-
-
-        </table>
-      </blockquote></td></tr>
-
-    </table>
-    <!-- End Attributes -->
-
-    <!-- Start Elements -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-
-      <tr><td bgcolor="#525D76">
-        <font color="#ffffff" face="arial,helvetica.sanserif">
-          <a name="elements">
-          <strong>Parameters as nested elements</strong></a></font>
-      </td></tr>
-
-      <tr><td><blockquote>
-
-      </blockquote></td></tr>
-
-    </table>
-    <!-- End Elements -->
-
-
+    <td valign="top" align="left">
+      nonproxyhosts
+    </td>
+    <td valign="top" align="left">
+      A list of hosts to bypass the proxy on. These should be separated with the vertical bar character '|'. Only in Java 1.4 does ftp use this list. e.g. fozbot.corp.sun.com|*.eng.sun.com
+    </td>
+    <td valign="top" align="left">
+      String
+    </td>
+    <td valign="top" align="left" rowspan="7">
+      Optional
     </td>
   </tr>
-  <!-- END RIGHT SIDE MAIN BODY -->
-
+  <tr>
+    <td valign="top" align="left">
+      proxyhost
+    </td>
+    <td valign="top" align="left">
+      the HTTP/ftp proxy host. Set this to "" for the http proxy option to be disabled
+    </td>
+    <td valign="top" align="left">
+      String
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      proxypassword
+    </td>
+    <td valign="top" align="left">
+      Set the password for the proxy. Used only if the proxyUser is set.
+    </td>
+    <td valign="top" align="left">
+      String
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      proxyport
+    </td>
+    <td valign="top" align="left">
+      the HTTP/ftp proxy port number; default is 80
+    </td>
+    <td valign="top" align="left">
+      int
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      proxyuser
+    </td>
+    <td valign="top" align="left">
+      set the proxy user. Probably requires a password to accompany this setting. Default=""
+    </td>
+    <td valign="top" align="left">
+      String
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      socksproxyhost
+    </td>
+    <td valign="top" align="left">
+      The name of a Socks server. Set to "" to turn socks proxying off.
+    </td>
+    <td valign="top" align="left">
+      String
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      socksproxyport
+    </td>
+    <td valign="top" align="left">
+      Set the ProxyPort for socks connections. The default value is 1080
+    </td>
+    <td valign="top" align="left">
+      int
+    </td>
+  </tr>
 </table>
-
 </body>
 </html>
diff --git a/manual/Tasks/signjar.html b/manual/Tasks/signjar.html
index 0f9d778..a422b9f 100644
--- a/manual/Tasks/signjar.html
+++ b/manual/Tasks/signjar.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="signjar">SignJar</a></h2>
+<h2 id="signjar">SignJar</h2>
 <h3>Description</h3>
 <p>Signing a jar allows users to authenticate the publisher.</p>
 <p>Signs JAR files with the <a target="_blank" href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jarsigner.html"><tt>jarsigner</tt> command line tool</a>.
@@ -47,7 +47,7 @@
 </ul>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -138,13 +138,13 @@
   <tr>
     <td valign="top">tsaurl</td>
     <td valign="top">URL for a timestamp authority for timestamped
-    JAR files in Java1.5+</td>
+    JAR files in Java 5+</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
     <td valign="top">tsacert</td>
     <td valign="top">alias in the keystore for a timestamp authority for
-    timestamped JAR files in Java1.5+</td>
+    timestamped JAR files in Java 5+</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -184,9 +184,14 @@
     <td valign="top">name of digest algorithm</td>
     <td valign="top" align="center">No</td>
   </tr>
+  <tr>
+    <td valign="top">tsadigestalg</td>
+    <td valign="top">name of tsa digest algorithm. <em>since Ant 1.10.2</em></td>
+    <td valign="top" align="center">No</td>
+  </tr>
 </table>
 <h3>Parameters as nested elements</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -199,7 +204,7 @@
   </tr>
   <tr>
     <td valign="top">fileset</td>
-    <td valign="top">fileset of JAR files to sign. </td>
+    <td valign="top">fileset of JAR files to sign.</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -210,7 +215,7 @@
   <tr>
     <td valign="top">sysproperty</td>
     <td valign="top">JVM system properties, with the syntax of Ant
-    <a href="exec.html#env">environment variables</a> </td>
+    <a href="exec.html#env">environment variables</a></td>
     <td valign="top" align="center">No, and only one can be supplied</td>
   </tr>
  </table>
@@ -282,18 +287,17 @@
 With trusted timestamping, users can verify that signing occurred before a certificate's expiration or revocation. Without this timestamp, users can only verify the signature as of their current date.</p>
 
 <p>
-Timestamped JAR files were introduced in Java1.5 and supported in Ant since
-Ant 1.7. Since Ant 1.9.5, Ant can use unauthenticated proxies for this signing process.
+Timestamped JAR files were introduced in Java 5 and supported <em>since Ant 1.7</em>.
+<em>Since Ant 1.9.5</em>, Ant can use unauthenticated proxies for this signing process.
 </p>
 
-<p>Common public timestamp authorities include
+<p>Common public timestamp authorities include</p>
   <ul>
     <li>http://timestamp.verisign.com</li>
 	<li>http://tsa.starfieldtech.com</li>
 	<li>https://timestamp.geotrust.com/tsa</li>
 	<li>Others (see your certificate authority)</li>
-  </ul></p>
+  </ul>
 
 </body>
 </html>
-
diff --git a/manual/Tasks/sleep.html b/manual/Tasks/sleep.html
index 80827b5..d6e4d10 100644
--- a/manual/Tasks/sleep.html
+++ b/manual/Tasks/sleep.html
@@ -23,63 +23,63 @@
 
 <body>
 
-<h2><a name="sleep">Sleep</a></h2>
+<h2 id="sleep">Sleep</h2>
 <h3>Description</h3>
-<p> A task for sleeping a short period of time, useful when a build or deployment 
-  process requires an interval between tasks.</p>
+<p>
+A task for sleeping a short period of time, useful when a build or deployment
+process requires an interval between tasks.
+</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
-  <tr> 
+<table>
+  <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
     <td align="center" valign="top"><b>Required</b></td>
   </tr>
-  <tr> 
+  <tr>
     <td valign="top">hours</td>
     <td valign="top">hours to to add to the sleep time</td>
     <td valign="top" align="center">No</td>
   </tr>
-  <tr> 
+  <tr>
     <td valign="top">minutes</td>
     <td valign="top"> minutes to add to the sleep time</td>
     <td valign="top" align="center">No</td>
   </tr>
-  <tr> 
+  <tr>
     <td valign="top">seconds</td>
     <td valign="top">seconds to add to the sleep time</td>
     <td align="center" valign="top">No</td>
   </tr>
-  <tr> 
+  <tr>
     <td valign="top">milliseconds</td>
     <td valign="top">milliseconds to add to the sleep time</td>
     <td align="center" valign="top">No</td>
   </tr>
-  <tr> 
+  <tr>
     <td valign="top">failonerror</td>
-    <td valign="top">flag controlling whether to break the build on an error. 
+    <td valign="top">flag controlling whether to break the build on an error.
     </td>
     <td align="center" valign="top">No</td>
   </tr>
 </table>
-<p>The sleep time is the sum of specified values, hours, minutes seconds and milliseconds. 
-  A negative value can be supplied to any of them provided the total sleep time 
+<p>The sleep time is the sum of specified values, hours, minutes seconds and milliseconds.
+  A negative value can be supplied to any of them provided the total sleep time
   is positive</p>
-<p>Note that sleep times are always hints to be interpred by the OS how it feels 
-  - small times may either be ignored or rounded up to a minimum timeslice. Note 
-  also that the system clocks often have a fairly low granularity too, which complicates 
+<p>Note that sleep times are always hints to be interpreted by the OS how it feels
+  - small times may either be ignored or rounded up to a minimum timeslice. Note
+  also that the system clocks often have a fairly low granularity too, which complicates
   measuring how long a sleep actually took.</p>
 <h3>Examples</h3>
 <pre>   &lt;sleep milliseconds=&quot;10&quot;/&gt;</pre>
-Sleep for about 10 mS. 
+Sleep for about 10 mS.
 <pre>   &lt;sleep seconds=&quot;2&quot;/&gt;</pre>
-Sleep for about 2 seconds. 
+Sleep for about 2 seconds.
 <pre>   &lt;sleep hours=&quot;1&quot; minutes=&quot;-59&quot; seconds=&quot;-58&quot;/&gt;</pre>
-<p>Sleep for one hour less 59:58, or two seconds again </p>
+<p>Sleep for one hour less 59:58, or two seconds again</p>
 <pre>   &lt;sleep/&gt;</pre>
-Sleep for no time at all. This may yield the CPU time to another thread or process. 
-
+Sleep for no time at all. This may yield the CPU time to another thread or process.
 
 </body>
 </html>
-
diff --git a/manual/Tasks/sos.html b/manual/Tasks/sos.html
index c068263..9908290 100644
--- a/manual/Tasks/sos.html
+++ b/manual/Tasks/sos.html
@@ -14,14 +14,10 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <html>
 <head>
-
-  <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
   <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
-<title>SOS Tasks</title>
-
+  <title>SOS Tasks</title>
 </head>
 <body>
 
@@ -32,21 +28,19 @@
 <ul>
 <li><a href="mailto:jesse@cryptocard.com">Jesse Stockall</a></li>
 </ul>
+<p>
 Version 1.1 2002/01/23
-<br>
-<br>
-
-<hr width="100%" size="2">
+</p>
+<hr/>
 <h2>Contents</h2>
 
 <ul>
     <li><a href="#intro">Introduction</a></li>
     <li><a href="#tasks">The Tasks</a></li>
-
 </ul>
 <br>
 
-<h2><a name="intro">Introduction</a> </h2>
+<h2 id="intro">Introduction</h2>
 
 <p>These tasks provide an interface to the <a href="http://msdn.microsoft.com/ssafe/default.asp" target="_top">
 Microsoft Visual SourceSafe</a> SCM via <a href="http://www.sourcegear.com">
@@ -63,9 +57,9 @@
 SourceOffSite  version 3.5.1 connecting to VisualSourceSafe 6.0. The tasks
 have been tested with Linux, Solaris &amp; Windows2000.</p>
 
-<h2><a name="tasks">The Tasks</a> </h2>
+<h2 id="tasks">The Tasks</h2>
 
-<table border="0" cellspacing="0" cellpadding="3">
+<table>
        <tbody>
          <tr>
            <td><a href="#SOSGet">sosget</a></td>
@@ -88,20 +82,17 @@
 
   </tbody>
 </table>
-     <br>
-
-<hr width="100%" size="2">
+<hr/>
 <h2>Task Descriptions</h2>
 
-<h2><a name="SOSGet"></a>SOSGet<br>
-     </h2>
+<h2 id="SOSGet">SOSGet</h2>
 <h3>Description</h3>
              Task to perform GET commands with SOS<br>
 <h3>Parameters</h3>
      </div>
      </div>
 
-<table border="1">
+<table>
      <tbody>
        <tr>
           <th>Attribute</th>
@@ -200,22 +191,23 @@
         sosserverpath=&quot;192.168.10.6:8888&quot;
         vssserverpath=&quot;d:\vss\srcsafe.ini&quot;/&gt;
 </pre>
+<p>
 <small>Connects to a SourceOffsite server on 192.168.10.6:8888 with
 build,build as the username &amp; password. The SourceSafe  database resides
 on the same box as the SOS server  &amp; the VSS database  is at
 &quot;d:\vss\srcsafe.ini&quot; Does a recursive GetProject on
 $/SourceRoot/project1, using tmp as the working
-directory. </small><br>
-<br>
+directory. </small>
+</p>
 
-<hr width="100%" size="2">
-<h2><a name="SOSLabel"></a>SOSLabel</h2>
+<hr/>
+<h2 id="SOSLabel">SOSLabel</h2>
 
 <h3>Description</h3>
              Task to perform Label commands with SOS<br>
 <h3>Parameters</h3>
 
-<table border="1">
+<table>
     <tbody><tr>
       <th>Attribute</th>
       <th>Values</th>
@@ -279,22 +271,21 @@
           sosserverpath=&quot;192.168.10.6:8888&quot;
           vssserverpath=&quot;d:\vss\srcsafe.ini&quot;/&gt;
 </pre>
-
+<p>
 <small>Connects to a SourceOffsite server on 192.168.10.6:8888 with
 build,build as the username &amp; password. The SourceSafe database resides
 on the same box as  the  SOS server  &amp; the VSS database is at
 &quot;d:\vss\srcsafe.ini&quot;. Labels the $/SourceRoot/project1
-project with &quot;test label&quot;.</small><br>
-<br>
+project with &quot;test label&quot;.</small>
+</p>
 
-<hr width="100%" size="2"><br>
-
-<h2><a name="SOSCheckIn"></a>SOSCheckIn</h2>
+<hr/>
+<h2 id="SOSCheckIn">SOSCheckIn</h2>
 
 <h3>Description</h3>
         Task to perform CheckIn commands with SOS<br>
 <h3>Parameters</h3>
-<table border="1">
+<table>
        <tbody>
     <tr>
       <th>Attribute</th>
@@ -386,23 +377,24 @@
             vssserverpath=&quot;\\server2\vss\srcsafe.ini&quot;/&gt;
 </pre>
 
+<p>
 <small>Connects to a SourceOffsite server on server1:8888 with build,build as
 the username &amp; password. The SourceSafe database resides on a different
 box (server2) &amp; the VSS database is on a share called
 &quot;vss&quot;. Checks-in only the &quot;foobar.txt&quot; file adding
 a comment of &quot;comment abc&quot;. Extra status messages will be
-displayed on screen.</small><br>
-<br>
+displayed on screen.</small>
+</p>
 
-<hr width="100%" size="2">
-<h2><a name="SOSCheckOut"></a>SOSCheckOut</h2>
+<hr/>
+<h2 id="SOSCheckOut">SOSCheckOut</h2>
 
 <h3>Description</h3>
        Task to perform CheckOut commands with SOS<br>
 
 <h3>Parameters</h3>
 
-<table border="1">
+<table>
        <tbody>
     <tr>
       <th>Attribute</th>
@@ -489,15 +481,15 @@
              sosserverpath=&quot;192.168.10.6:8888&quot;
              vssserverpath=&quot;\\server2\vss\srcsafe.ini&quot;/&gt;
 </pre>
-
+<p>
 <small>Connects to a SourceOffsite server on server1:8888 with build,build as
 the username &amp; password. The SourceSafe database resides on a different
 box (server2) &amp; the VSS database is on a share called
 &quot;vss&quot;. Checks-out &quot;project1&quot;, Only the
 &quot;project1&quot; directory will be locked as the recursive option
 was not set. Extra status messages will be displayed on screen. The
-soscmd(.exe) file to be used resides in /usr/local/bin.</small><br>
-<br>
+soscmd(.exe) file to be used resides in /usr/local/bin.</small>
+</p>
 
 </body>
 </html>
diff --git a/manual/Tasks/sound.html b/manual/Tasks/sound.html
index 1095f80..f0de67d 100644
--- a/manual/Tasks/sound.html
+++ b/manual/Tasks/sound.html
@@ -24,22 +24,22 @@
 
 <body>
 
-<h2><a name="sound">Sound</a></h2>
+<h2 id="sound">Sound</h2>
 <h3>Description</h3>
 <p>Plays a sound-file at the end of the build, according to whether
 the build failed or succeeded. You can specify either a specific
 sound-file to play, or, if a directory is specified, the
 <code>&lt;sound&gt;</code> task will randomly select a file to play.
-Note: At this point, the random selection is based on all the files
+<strong>Note</strong>: At this point, the random selection is based on all the files
 in the directory, not just those ending in appropriate suffixes
-for sound-files, so be sure you only have sound-files in the 
+for sound-files, so be sure you only have sound-files in the
 directory you specify.</p>
 <p>More precisely <code>&lt;sound&gt;</code> registers a hook that is
 triggered when the build finishes. Therefore you have to place this
 task as top level or inside a target which is always executed.</p>
 <p>
 Unless you are running on Java 1.3 or later, you need the Java Media Framework
-on the classpath (javax.sound). 
+on the classpath (javax.sound).
 </p>
 
 
@@ -51,9 +51,9 @@
 
 <h3>Nested Element Parameters</h3>
 <p>
-The following attributes may be used on the <code>&lt;success&gt;</code> 
+The following attributes may be used on the <code>&lt;success&gt;</code>
 and <code>&lt;fail&gt;</code> elements:</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -116,8 +116,5 @@
 </blockquote>
 randomly selects a sound-file to play when the build succeeds or fails.
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/splash.html b/manual/Tasks/splash.html
index e158bd2..cf8bcad 100644
--- a/manual/Tasks/splash.html
+++ b/manual/Tasks/splash.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="Splash">Splash</a></h2>
+<h2 id="splash">Splash</h2>
 <p>by Les Hughes (leslie.hughes@rubus.com)
 <h3>Description</h3>
 <p>This task creates a splash screen. The splash screen is displayed
@@ -32,7 +32,7 @@
 well. Use in conjunction with the sound task to provide interest
 whilst waiting for your builds to complete...</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -45,7 +45,7 @@
     <td valign="top" align="center">No</td>
     <td valign="top" align="center">antlogo.gif from the classpath</td>
   </tr>
- 
+
   <tr>
     <td valign="top">showduration</td>
     <td valign="top">Initial period to pause the build to show the
@@ -76,11 +76,11 @@
 
 The following properties can be used to configure the proxy settings to retrieve
 an image from behind a firewall. However, the settings apply not just to this
-task, but to all following tasks. Therefore they are now deprecated in 
+task, but to all following tasks. Therefore they are now deprecated in
 preference to the <code>&lt;setproxy&gt;</code> task, that makes it clear to readers of
 the build exactly what is going on.
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top">useproxy</td>
     <td valign="top">Use a proxy to access imgurl. Note: Only tested
@@ -147,8 +147,5 @@
         &lt;/target&gt;
 </pre></blockquote>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/sql.html b/manual/Tasks/sql.html
index bade590..cf94ac8 100644
--- a/manual/Tasks/sql.html
+++ b/manual/Tasks/sql.html
@@ -22,39 +22,39 @@
 </head>
 <body>
 
-<h2><a name="sql">Sql</a></h2>
+<h2 id="sql">Sql</h2>
 <h3>Description</h3>
-<p>Executes a series of SQL statements via JDBC to a database. Statements can 
-either be read in from a text file using the <i>src</i> attribute or from 
+<p>Executes a series of SQL statements via JDBC to a database. Statements can
+either be read in from a text file using the <i>src</i> attribute or from
 between the enclosing SQL tags.</p>
 
-<p>Multiple statements can be provided, separated by semicolons (or the 
-defined <i>delimiter</i>). Individual lines within the statements can be 
+<p>Multiple statements can be provided, separated by semicolons (or the
+defined <i>delimiter</i>). Individual lines within the statements can be
 commented using either --, // or REM at the start of the line.</p>
 
-<p>The <i>autocommit</i> attribute specifies whether auto-commit should be 
-turned on or off whilst executing the statements. If auto-commit is turned 
-on each statement will be executed and committed. If it is turned off the 
+<p>The <i>autocommit</i> attribute specifies whether auto-commit should be
+turned on or off whilst executing the statements. If auto-commit is turned
+on each statement will be executed and committed. If it is turned off the
 statements will all be executed as one transaction.</p>
 
-<p>The <i>onerror</i> attribute specifies how to proceed when an error occurs 
-during the execution of one of the statements. 
+<p>The <i>onerror</i> attribute specifies how to proceed when an error occurs
+during the execution of one of the statements.
 The possible values are: <b>continue</b> execution, only show the error;
 <b>stop</b> execution, log the error but don't fail the task
 and <b>abort</b> execution and transaction and fail task.</p>
 
 <p>
-<b>Proxies</b>. Some JDBC drivers (including the Oracle thin driver), 
+<b>Proxies</b>. Some JDBC drivers (including the Oracle thin driver),
     use the JVM's proxy settings to route their JDBC operations to the database.
-    Since Apache Ant1.7, Ant running on Java1.5 or later defaults to 
+    <em>Since Apache Ant 1.7</em>, Ant running on Java 5 or later defaults to
     <a href="../proxy.html">using
-    the proxy settings of the operating system</a>. 
+    the proxy settings of the operating system</a>.
     Accordingly, the OS proxy settings need to be valid, or Ant's proxy
     support disabled with <code>-noproxy</code> option.
 </p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -93,7 +93,7 @@
 <tr>
   <td valign="top">outputencoding</td>
   <td valign="top">The encoding of the files holding
-    results.  <em>since 1.9.4</em</td>
+    results.  <em>since 1.9.4</em></td>
   <td align="center">No - defaults to default JVM encoding</td>
 </tr>
 <tr>
@@ -123,8 +123,8 @@
 </tr>
 <tr>
   <td width="12%" valign="top">output</td>
-  <td width="78%" valign="top">Output file for result sets (defaults to System.out)
-    <b>Since Ant 1.8</b> can specify any Resource that supports output (see
+  <td width="78%" valign="top">Output file for result sets (defaults to System.out).
+    <em>Since Ant 1.8</em> can specify any Resource that supports output (see
     <a href="../develop.html#set-magic">note</a>).
   </td>
   <td width="10%" valign="top">No (print to System.out by default)</td>
@@ -226,7 +226,7 @@
   <td width="12%" valign="top">showWarnings</td>
   <td width="78%" valign="top">If true, SQLWarnings will be logged at
     the WARN level.  <em>Since Ant 1.8.0</em>.<br/>
-    <b>Note:</b> even if the attribute is set to false, warnings that
+    <strong>Note</strong>: even if the attribute is set to false, warnings that
     apply to the connection will be logged at the verbose level.</td>
   <td width="10%" valign="top">No, default <em>false</em></td>
 </tr>
@@ -256,7 +256,7 @@
     quote character itself will be surrounded by the quote character.
     The quote character itself will be doubled if it appears inside of
     the column's value.<br/>
-    <b>Note:</b> BLOB values will never be quoted.
+    <strong>Note</strong>: BLOB values will never be quoted.
     <em>Since Ant 1.8.0</em>.</td>
   <td width="10%" valign="top">No, default is not set (i.e. no quoting
     ever occurs)</td>
@@ -292,12 +292,12 @@
 
 <h3>Parameters specified as nested elements</h3>
 <h4>transaction</h4>
-<p>Use nested <code>&lt;transaction&gt;</code> 
+<p>Use nested <code>&lt;transaction&gt;</code>
 elements to specify multiple blocks of commands to the executed
 executed in the same connection but different transactions. This
 is particularly useful when there are multiple files to execute
 on the same schema.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -333,7 +333,7 @@
 <p>Use nested <code>&lt;connectionProperty&gt;</code> elements to
   specify additional JDBC properties that need to be set when
   connecting to the database.</p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -357,12 +357,11 @@
     url=&quot;jdbc:database-url&quot;
     userid=&quot;sa&quot;
     password=&quot;pass&quot;
-    src=&quot;data.sql&quot;
-/&gt;
+    src=&quot;data.sql&quot;/&gt;
 </pre></blockquote>
 
-<p>Connects to the database given in <i>url</i> as the sa user using the 
-org.database.jdbcDriver and executes the SQL statements contained within 
+<p>Connects to the database given in <i>url</i> as the sa user using the
+org.database.jdbcDriver and executes the SQL statements contained within
 the file data.sql</p>
 
 <blockquote><pre>&lt;sql
@@ -384,8 +383,7 @@
     driver=&quot;org.database.jdbcDriver&quot;
     url=&quot;jdbc:database-url&quot;
     userid=&quot;sa&quot;
-    password=&quot;pass&quot;
-    &gt;
+    password=&quot;pass&quot;&gt;
 insert
 into table some_table
 values(1,2,3,4);
@@ -395,7 +393,7 @@
 </pre></blockquote>
 
 <p>Connects to the database given in <i>url</i> as the sa
- user using the org.database.jdbcDriver and executes the two SQL statements 
+ user using the org.database.jdbcDriver and executes the two SQL statements
  inserting data into some_table and truncating some_other_table. Ant Properties
  in the nested text will not be expanded.</p>
 
@@ -408,8 +406,7 @@
     driver=&quot;org.database.jdbcDriver&quot;
     url=&quot;jdbc:database-url&quot;
     userid=&quot;sa&quot;
-    password=&quot;pass&quot;
-    &gt;&lt;![CDATA[
+    password=&quot;pass&quot;&gt;&lt;![CDATA[
 
 update some_table set column1 = column1 + 1 where column2 &lt; 42;
 
@@ -417,32 +414,30 @@
 </pre></blockquote>
 
 The following command turns property expansion in nested text on (it is off purely for backwards
-compatibility), then creates a new user in the HSQLDB database using Ant properties. 
+compatibility), then creates a new user in the HSQLDB database using Ant properties.
 
 <blockquote><pre>&lt;sql
     driver="org.hsqldb.jdbcDriver";
     url="jdbc:hsqldb:file:${database.dir}"
     userid="sa"
     password=""
-    expandProperties="true"
-    &gt;
+    expandProperties="true"&gt;
   &lt;transaction&gt;
     CREATE USER ${newuser} PASSWORD ${newpassword}
   &lt;/transaction&gt;
 &lt;/sql&gt;
 </pre></blockquote>
 
-
-<p>The following connects to the database given in url as the sa user using 
-the org.database.jdbcDriver and executes the SQL statements contained within 
-the files data1.sql, data2.sql and data3.sql and then executes the truncate 
+<p>The following connects to the database given in url as the sa user using
+the org.database.jdbcDriver and executes the SQL statements contained within
+the files data1.sql, data2.sql and data3.sql and then executes the truncate
 operation on <i>some_other_table</i>.</p>
 
 <blockquote><pre>&lt;sql
     driver=&quot;org.database.jdbcDriver&quot;
     url=&quot;jdbc:database-url&quot;
     userid=&quot;sa&quot;
-    password=&quot;pass&quot; &gt;
+    password=&quot;pass&quot;&gt;
   &lt;transaction  src=&quot;data1.sql&quot;/&gt;
   &lt;transaction  src=&quot;data2.sql&quot;/&gt;
   &lt;transaction  src=&quot;data3.sql&quot;/&gt;
@@ -473,9 +468,9 @@
 &lt;/sql&gt;
 </pre></blockquote>
 
-<p>The following connects to the database given in url as the sa user using the 
-org.database.jdbcDriver and executes the SQL statements contained within the 
-file data.sql, with output piped to outputfile.txt, searching /some/jdbc.jar 
+<p>The following connects to the database given in url as the sa user using the
+org.database.jdbcDriver and executes the SQL statements contained within the
+file data.sql, with output piped to outputfile.txt, searching /some/jdbc.jar
 as well as the system classpath for the driver class.</p>
 
 <blockquote><pre>&lt;sql
@@ -485,15 +480,14 @@
     password=&quot;pass&quot;
     src=&quot;data.sql&quot;
     print=&quot;yes&quot;
-    output=&quot;outputfile.txt&quot;
-    &gt;
+    output=&quot;outputfile.txt&quot;&gt;
 &lt;classpath&gt;
 	&lt;pathelement location=&quot;/some/jdbc.jar&quot;/&gt;
 &lt;/classpath&gt;
 &lt;/sql&gt;
 </pre></blockquote>
 
-<p>The following will only execute if the RDBMS is &quot;oracle&quot; and the version 
+<p>The following will only execute if the RDBMS is &quot;oracle&quot; and the version
 starts with &quot;8.1.&quot;</p>
 
 <blockquote><pre>&lt;sql
@@ -503,8 +497,7 @@
     password=&quot;pass&quot;
     src=&quot;data.sql&quot;
     rdbms=&quot;oracle&quot;
-    version=&quot;8.1.&quot;
-    &gt;
+    version=&quot;8.1.&quot;&gt;
 insert
 into table some_table
 values(1,2,3,4);
@@ -513,6 +506,5 @@
 &lt;/sql&gt;
 </pre></blockquote>
 
-
 </body>
 </html>
diff --git a/manual/Tasks/sshexec.html b/manual/Tasks/sshexec.html
index d085abd..6c37b17 100644
--- a/manual/Tasks/sshexec.html
+++ b/manual/Tasks/sshexec.html
@@ -24,15 +24,14 @@
 
 <body>
 
-<h2><a name="sshexec">SSHEXEC</a></h2>
+<h2 id="sshexec">SSHEXEC</h2>
 <h3>Description</h3>
 
 <p><em>since Apache Ant 1.6</em></p>
 
-<p>Runs a command on a remote machine running SSH daemon.
-</p>
+<p>Runs a command on a remote machine running SSH daemon.</p>
 
-<p><b>Note:</b> This task depends on external libraries not included
+<p><strong>Note</strong>: This task depends on external libraries not included
 in the Ant distribution.  See <a
 href="../install.html#librarydependencies">Library Dependencies</a>
 for more information.  This task has been tested with jsch-0.1.29 and above
@@ -42,7 +41,7 @@
 <p>See also the <a href="scp.html">scp task</a></p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -61,34 +60,34 @@
   <tr>
     <td valign="top">command</td>
     <td valign="top">The command to run on the remote host.</td>
-    <td valian="top" align="center">Either this or commandResource must be set</td>
+    <td valign="top" align="center">Either this or commandResource must be set</td>
   </tr>
   <tr>
     <td valign="top">commandResource</td>
     <td valign="top">The resource (file) that contains the commands to run on the remote host.
-    Since Ant 1.7.1</td>
-    <td valian="top" align="center">Either this or command must be set</td>
+      <em>Since Ant 1.7.1</em></td>
+    <td valign="top" align="center">Either this or command must be set</td>
   </tr>
   <tr>
     <td valign="top">port</td>
     <td valign="top">The port to connect to on the remote host.</td>
-    <td valian="top" align="center">No, defaults to 22.</td>
+    <td valign="top" align="center">No, defaults to 22.</td>
   </tr>
   <tr>
     <td valign="top">trust</td>
 
     <td valign="top">This trusts all unknown hosts if set to yes/true.<br>
-      <strong>Note</strong> If you set this to false (the default), the
+      <strong>Note</strong>: If you set this to false (the default), the
       host you connect to must be listed in your knownhosts file, this
       also implies that the file exists.</td>
-    <td valian="top" align="center">No, defaults to No.</td>
+    <td valign="top" align="center">No, defaults to No.</td>
   </tr>
   <tr>
     <td valign="top">knownhosts</td>
     <td valign="top">This sets the known hosts file to use to validate
     the identity of the remote host.  This must be a SSH2 format file.
     SSH1 format is not supported.</td>
-    <td valian="top" align="center">No, defaults to
+    <td valign="top" align="center">No, defaults to
     ${user.home}/.ssh/known_hosts.</td>
   </tr>
   <tr>
@@ -152,7 +151,7 @@
   </tr>
   <tr>
     <td valign="top">outputproperty</td>
-    <td valign="top">The name of a property in which the output of the 
+    <td valign="top">The name of a property in which the output of the
       command should be stored.  If you use the commandResource
       attribute, each command's output will be prefixed by the
       command itself.</td>
@@ -191,8 +190,8 @@
   </tr>
   <tr>
     <td valign="top">verbose</td>
-    <td valign="top">Determines whether sshexec outputs verbosely to the user.<br/> 
-    Similar output is generated as the ssh commandline tool wit the -v option. 
+    <td valign="top">Determines whether sshexec outputs verbosely to the user.<br/>
+    Similar output is generated as the ssh commandline tool wit the -v option.
     <em>since Ant 1.8.0</em></td>
     <td align="center">No, defaults to false</td>
   </tr>
@@ -283,21 +282,20 @@
 	commandResource=&quot;to_run&quot;/&gt;
 </pre>
 
-
-<p><strong>Security Note:</strong>  Hard coding passwords and/or usernames
+<p><strong>Security Note</strong>:  Hard coding passwords and/or usernames
 in sshexec task can be a serious security hole.  Consider using variable
-substitution and include the password on the command line.  For example:<br>
+substitution and include the password on the command line.  For example:</p>
 <pre>
   &lt;sshexec host=&quot;somehost&quot;
 	username=&quot;${username}&quot;
 	password=&quot;${password}&quot;
 	command=&quot;touch somefile&quot;/&gt;
 </pre>
-Invoking ant with the following command line:
+Invoking Ant with the following command line:
 <pre>
     ant -Dusername=me -Dpassword=mypassword target1 target2
 </pre>
-
+<p>
 Is slightly better, but the username/password is exposed to all users
 on an Unix system (via the ps command). The best approach is to use
 the
diff --git a/manual/Tasks/sshsession.html b/manual/Tasks/sshsession.html
index e9696d1..8c9052d 100644
--- a/manual/Tasks/sshsession.html
+++ b/manual/Tasks/sshsession.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="sshsession">SSHSESSION</a></h2>
+<h2 id="sshsession">SSHSESSION</h2>
 <h3>Description</h3>
 
 <p><em>since Apache Ant 1.8.0</em></p>
@@ -35,7 +35,7 @@
 before taking down the connection.
 </p>
 
-<p><b>Note:</b> This task depends on external libraries not included
+<p><strong>Note</strong>: This task depends on external libraries not included
 in the Ant
 distribution. See <a href="../install.html#librarydependencies">Library
 Dependencies</a> for more information.  This task has been tested with
@@ -46,7 +46,7 @@
 and <a href="scp.html">scp</a> tasks</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -65,7 +65,7 @@
   <tr>
     <td valign="top">port</td>
     <td valign="top">The port to connect to on the remote host.</td>
-    <td valian="top" align="center">No, defaults to 22.</td>
+    <td valign="top" align="center">No, defaults to 22.</td>
   </tr>
   <tr>
   <tr>
@@ -75,7 +75,7 @@
       local port forwarding.<br>  If
       nested <a href="#LocalTunnel">localtunnel</a> elements are also
       provided, both sets of tunnels will be established.</td>
-    <td valian="top" align="center">No</td>
+    <td valign="top" align="center">No</td>
   </tr>
   <tr>
     <td valign="top">remotetunnels</td>
@@ -84,23 +84,23 @@
       remote port forwarding.<br>  If
       nested <a href="#RemoteTunnel">remotetunnel</a> elements are
       also provided, both sets of tunnels will be established.</td>
-    <td valian="top" align="center">No</td>
+    <td valign="top" align="center">No</td>
   </tr>
   <tr>
     <td valign="top">trust</td>
-    
+
     <td valign="top">This trusts all unknown hosts if set to yes/true.<br>
-      <strong>Note</strong> If you set this to false (the default), the
+      <strong>Note</strong>: If you set this to false (the default), the
       host you connect to must be listed in your knownhosts file, this
       also implies that the file exists.</td>
-    <td valian="top" align="center">No, defaults to No.</td>
+    <td valign="top" align="center">No, defaults to No.</td>
   </tr>
   <tr>
     <td valign="top">knownhosts</td>
     <td valign="top">This sets the known hosts file to use to validate
       the identity of the remote host.	This must be a SSH2 format file.
       SSH1 format is not supported.</td>
-    <td valian="top" align="center">No, defaults to
+    <td valign="top" align="center">No, defaults to
       ${user.home}/.ssh/known_hosts.</td>
   </tr>
   <tr>
@@ -138,13 +138,13 @@
 
 <h3>Parameters specified as nested elements</h3>
 
-<a name="LocalTunnel"><h4>localtunnel</h4></a>
+<h4 id="LocalTunnel">localtunnel</h4>
 <p>Optionally, any number of localtunnel elements can be used to
 define local port forwarding over the SSH connection.  If the
 localtunnels parameter was also specified, both sets of tunnels will
 be established.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -169,13 +169,13 @@
   </tr>
 </table>
 
-<a name="RemoteTunnel"><h4>remotetunnel</h4></a>
+<h4 id="RemoteTunnel">remotetunnel</h4>
 <p>Optionally, any number of remotetunnel elements can be used to
 define remote port forwarding over the SSH connection.  If the
 remotetunnels parameter was also specified, both sets of tunnels will
 be established.</p>
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -200,7 +200,7 @@
   </tr>
 </table>
 
-<a name="Sequential"><h4>sequential</h4></a>
+<h4 id="Sequential">sequential</h4>
 <p>The sequential element is a required parameter.  It is a container
 for nested Tasks which are to be executed once the SSH connection is
 established and all local and/or remote tunnels established.</p>
@@ -213,14 +213,12 @@
   &lt;sshsession host=&quot;somehost&quot;
     username=&quot;dude&quot;
     password=&quot;yo&quot;
-    localtunnels=&quot;2401:localhost:2401&quot;
-  &gt;
+    localtunnels=&quot;2401:localhost:2401&quot;&gt;
     &lt;sequential&gt;
-      &lt;cvs  command=&quot;update ${cvs.parms} ${module}&quot;
+      &lt;cvs command=&quot;update ${cvs.parms} ${module}&quot;
         cvsRoot=&quot;${cvs.root}&quot;
         dest=&quot;${local.root}&quot;
-        failonerror=&quot;true&quot;
-      /&gt;
+        failonerror=&quot;true&quot;/&gt;
     &lt;/sequential&gt;
   &lt;/sshsession&gt;
 </pre>
@@ -229,15 +227,13 @@
 <pre>
   &lt;sshsession host=&quot;somehost&quot;
     username=&quot;dude&quot;
-    password=&quot;yo&quot;
-  &gt;
+    password=&quot;yo&quot;&gt;
     &lt;localtunnel lport=&quot;2401&quot; rhost=&quot;localhost&quot; rport=&quot;2401&quot;/&gt;
     &lt;sequential&gt;
-      &lt;cvs  command=&quot;update ${cvs.parms} ${module}&quot;
+      &lt;cvs command=&quot;update ${cvs.parms} ${module}&quot;
         cvsRoot=&quot;${cvs.root}&quot;
         dest=&quot;${local.root}&quot;
-        failonerror=&quot;true&quot;
-    /&gt;
+        failonerror=&quot;true&quot;/&gt;
     &lt;/sequential&gt;
   &lt;/sshsession&gt;
 </pre>
@@ -257,11 +253,10 @@
   &lt;/sshsession&gt;
 </pre>
 
-
-<p><strong>Security Note:</strong> Hard coding passwords or
+<p><strong>Security Note</strong>: Hardcoding passwords or
 passphrases and/or usernames in sshsession task can be a serious
 security hole. Consider using variable substitution and include the
-password on the command line. For example:<br>
+password on the command line. For example:</p>
 <pre>
   &lt;sshsession host=&quot;somehost&quot;
   username=&quot;${username}&quot;
@@ -273,11 +268,11 @@
   &lt;/sshsession&gt;
 </pre>
 
-Invoking ant with the following command line:
+Invoking Ant with the following command line:
 <pre>
     ant -Dusername=me -Dpassword=mypassword target1 target2
 </pre>
-
+<p>
 Is slightly better, but the username/password is exposed to all users
 on an Unix system (via the ps command). The best approach is to use
 the
diff --git a/manual/Tasks/style.html b/manual/Tasks/style.html
index 81e7e6b..2dbe9d5 100644
--- a/manual/Tasks/style.html
+++ b/manual/Tasks/style.html
@@ -24,13 +24,13 @@
 
 <body>
 
-<h2><a name="style">XSLT</a></h2>
+<h2 id="style">XSLT</h2>
 <p><em>The name <code>style</code> is a deprecated name for the same task.</em></p>
 <h3>Description</h3>
 <p>Process a set of documents via XSLT.</p>
 <p>This is useful for building views of XML based documentation,
 or for generating code.</p>
-<p><b>Note:</b> If you are using JDK 1.4 or higher, this task does not require external libraries
+<p><strong>Note</strong>: If you are using JDK 1.4 or higher, this task does not require external libraries
 not supplied in the Apache Ant distribution. However, often the built in XSL engine is not as up
 to date as a fresh download, so an update is still highly recommended
   in particular since the built-in XSLT processors of Java 5 (and to a
@@ -50,7 +50,7 @@
   as well as the nested <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code>
   and <code>&lt;patternset&gt;</code> elements.</p>
 
-<p><b>Note</b>: Unlike other similar tasks, this task treats
+<p><strong>Note</strong>: Unlike other similar tasks, this task treats
 directories that have been matched by the include/exclude patterns of
 the implicit fileset in a special way.  It will apply the stylesheets
 to all files contain in them as well.  Since the default include
@@ -60,7 +60,7 @@
 been matched.  If this behavior is not what you want, set the
 scanincludedirectories attribute to false.</p>
 
-<p>Starting with Ant 1.7 this task supports nested <a
+<p><em>Since Ant 1.7</em>, this task supports nested <a
 href="../Types/resources.html#collection">resource collection</a>s
 in addition to (or instead of, depending on the useImplicitFileset
 attribute) the implicit fileset formed by this task.</p>
@@ -86,7 +86,7 @@
   classloader (reference to an Ant PATH-like structure).</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -117,11 +117,11 @@
     <td valign="top">name of the stylesheet to use - given either relative
       to the project's basedir or as an absolute path.<br/>
       <br/>
-      Alternatively, a nested element which ant can interpret as a resource
+      Alternatively, a nested element which Ant can interpret as a resource
       can be used to indicate where to find the stylesheet<br/>
       <em>deprecated variation :</em> <br/>
       If the stylesheet cannot be found, and if you have specified the
-      attribute basedir for the task, ant will assume that the style
+      attribute basedir for the task, Ant will assume that the style
       attribute is relative to the basedir of the task.
     </td>
     <td align="center" valign="top">No, if the location of
@@ -147,14 +147,13 @@
   </tr>
   <tr>
     <td valign="top">processor</td>
-
     <td valign="top">name of the XSLT processor to use.
       Permissible value is :<ul>
       <li>&quot;trax&quot; for a TraX compliant processor (ie JAXP interface
       implementation such as Xalan 2 or Saxon)</li></ul>
       Defaults to trax.
       <br/>
-      Support for xalan1 has been removed in ant 1.7.
+      Support for Xalan 1 has been removed in Ant 1.7.
       </td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -237,7 +236,7 @@
     <td valign="top">Specifies a xsl parameter for accessing the directory
     of the current processed file. For files in the current directory a
     value of '.' will be passed to the transformation.
-    If not set, the directory is not passed to the transformation. 
+    If not set, the directory is not passed to the transformation.
     <em>Since Ant 1.7</em>.</td>
     <td valign="top" align="center">No</td>
   </tr>
@@ -245,7 +244,7 @@
     <td valign="top">suppressWarnings</td>
     <td valign="top">Whether processor warnings shall be suppressed.
     This option requires support by the processor, it is supported by
-    the trax processor bundled with Ant. 
+    the trax processor bundled with Ant.
     <em>Since Ant 1.8.0</em>.</td>
     <td valign="top" align="center">No, default is false.</td>
   </tr>
@@ -286,7 +285,7 @@
 should be applied to.  Use a nested mapper and the task's destdir
 attribute to specify the output files.</p>
 
-<h4><a name="classpath">classpath</a></h4>
+<h4 id="classpath">classpath</h4>
 <p>The classpath to load the processor from can be specified via a
 nested <code>&lt;classpath&gt;</code>, as well - that is, a
 <a href="../using.html#path">path</a>-like structure.</p>
@@ -297,9 +296,9 @@
 
 <h4>param</h4>
 <p>Param is used to pass a parameter to the XSL stylesheet.</p>
-<blockquote>
-<h4>Parameters</h4>
-<table width="60%" border="1" cellpadding="2" cellspacing="0">
+
+<h5>Parameters</h5>
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -348,11 +347,9 @@
     <td valign="top">The param will not be passed <a href="../properties.html#if+unless">if this property is set</a>.</td>
     <td align="center" valign="top">No</td>
   </tr>
-
 </table>
-</blockquote>
 
-  <p>      
+  <p>
       The <code>XPATH_*</code> types says that the <code>expression</code> is not just a primitive-type value but an XPath expression.
       This expression will be evaluated on an empty XML document and the result will be passed to the XSLT transformer as a parameter of given type.
       In these expressions the declared Ant properties can be used as XPath variables e.g. <code>$someProperty</code>.
@@ -368,9 +365,9 @@
 <p>Used to specify how you wish the result tree to be output
 as specified in the <a href="http://www.w3.org/TR/xslt#output">
 XSLT specifications</a>.
-<blockquote>
-<h4>Parameters</h4>
-<table width="60%" border="1" cellpadding="2" cellspacing="0">
+
+<h5>Parameters</h5>
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -387,13 +384,12 @@
     <td align="center" valign="top">Yes</td>
   </tr>
 </table>
-</blockquote>
 
-<h4><a name="factory">factory ('trax' processors only)</a></h4>
+<h4 id="factory">factory ('trax' processors only)</h4>
 Used to specify factory settings.
-<blockquote>
-<h4>Parameters</h4>
-<table width="60%" border="1" cellpadding="2" cellspacing="0">
+
+<h5>Parameters</h5>
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -410,8 +406,8 @@
     <td align="center" valign="top">No. Defaults to the JAXP lookup mechanism.</td>
   </tr>
 </table>
-<h3>Parameters specified as nested elements</h3>
-<h4>attribute</h4>
+<h5>Parameters specified as nested elements</h5>
+<h6>attribute</h6>
 <p>Used to specify settings of the processor factory.
 The attribute names and values are entirely processor specific
 so you must be aware of the implementation to figure them out.
@@ -432,8 +428,8 @@
 <li>...</li>
 </ul>
 <blockquote>
-<h4>Parameters</h4>
-<table width="60%" border="1" cellpadding="2" cellspacing="0">
+<h6>Parameters</h6>
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -461,8 +457,9 @@
       with the given id. <em>since Ant 1.9.8</em></td>
   </tr>
 </table>
+</blockquote>
 
-<h4>Examples</h4>
+<h5>Examples</h5>
 
 <pre>
   &lt;path id="extension-path"&gt;
@@ -479,10 +476,10 @@
 </pre>
 <p>Sets the classloader to use when loading extension functions to a
   classloader using the <code>path</code> with the
-  id <code>extension-path</code>.
-</blockquote>
-<h4>feature</h4>
+  id <code>extension-path</code>.</p>
 <p><em>since Ant 1.9.8</em></p>
+
+<h6>feature</h6>
 <p>Used to specify settings of the processor factory.  The feature
 names are mostly processor specific so you must be aware of the
 implementation to figure them out.  Read the documentation of your
@@ -490,8 +487,8 @@
 support
 is <code>http://javax.xml.XMLConstants/feature/secure-processing</code>.
 <blockquote>
-<h4>Parameters</h4>
-<table width="60%" border="1" cellpadding="2" cellspacing="0">
+<h6>Parameters</h6>
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -505,12 +502,12 @@
   <tr>
     <td valign="top">value</td>
     <td valign="top">value of the feature. A boolean value
-    (i.e. permitted values are true,false,yes,no,on,off).</td>
+    (i.e. permitted values are true, false, yes, no, on, off).</td>
     <td align="center" valign="top">No, defaults to false</td>
   </tr>
 </table>
 </blockquote>
-</blockquote>
+
 <h4>mapper</h4>
 
 <p><em>since Ant 1.6.2</em></p>
@@ -548,7 +545,6 @@
 <p><em>since Ant 1.8.0</em>.</p>
 
 <h3>Examples</h3>
-<blockquote>
   <pre>
 &lt;xslt basedir=&quot;doc&quot; destdir=&quot;build/doc&quot;
        extension=&quot;.html&quot; style=&quot;style/apache.xsl&quot;/&gt;</pre>
@@ -580,9 +576,9 @@
   element &lt;xsl:param name=&quot;date&quot;/&gt;, the variable
   <code>$date</code> will subsequently have the value 07-01-2000.
   </p>
-  
+
   <p>Various data types and XPath expressions:</p>
-  
+
   <pre>&lt;property name="antProperty1" value="ANT_PROPERTY_1"/&gt;
 &lt;property name="antProperty2" value="ANT_PROPERTY_2"/&gt;
 &lt;property name="antProperty3" value="3"/&gt;
@@ -594,38 +590,38 @@
 --&gt;
 
 &lt;xslt in="in.xml" out="out.xml" style="template.xsl"&gt;
-  
+
   &lt;!-- Simple String parameter: --&gt;
   &lt;param name="p0" expression="some nice string" type="STRING"/&gt;
-  
+
   &lt;!-- A value substituted by Ant --&gt;
   &lt;param name="p1" expression="some string with ${antProperty1} constructed by Ant" type="STRING"/&gt;
-  
+
   &lt;!-- XPath resulting in: and this is done in XPath: ANT_PROPERTY_2 --&gt;
   &lt;param name="p2" expression="concat('and this is done in XPath: ', $antProperty2)" type="XPATH_STRING"/&gt;
-  
+
   &lt;!-- Some XPath math, result: 42 --&gt;
   &lt;param name="p3" expression="64 * 64 div 128 + 10" type="XPATH_NUMBER"/&gt;
-  
+
   &lt;!-- Some numeric parameter: --&gt;
   &lt;param name="p4" expression="123.45" type="DOUBLE"/&gt;
-  
+
   &lt;!-- XPath expression, result: true boolean --&gt;
   &lt;param name="p5" expression="$antProperty1 = 'ANT_PROPERTY_1'" type="XPATH_BOOLEAN"/&gt;
-  
+
   &lt;!-- First one is an XPath variable, second one is a text substituted by Ant, result: true boolean --&gt;
   &lt;param name="p6" expression="$antProperty2 = '${antProperty2}'" type="XPATH_BOOLEAN"/&gt;
-  
+
   &lt;!-- Some XPath math with a variable, result: 64 --&gt;
   &lt;param name="p7" expression="$antProperty3 * 4 * 5 + 4" type="XPATH_NUMBER"/&gt;
-  
-  &lt;!-- 
+
+  &lt;!--
     XPath expression with substituted function name and a variable:
     substring-before($antProperty2, '_')
     result: ANT
   --&gt;
   &lt;param name="p8" expression="${antProperty4}($antProperty2, '_')" type="XPATH_STRING"/&gt;
-  
+
   &lt;!-- Without type attribute: --&gt;
   &lt;param name="p9" expression="default type is String"/&gt;
 &lt;/xslt&gt;</pre>
@@ -671,8 +667,7 @@
 &lt;project&gt;
   &lt;xslt style=&quot;printFilename.xsl&quot; destdir=&quot;out&quot; basedir=&quot;in&quot; extension=&quot;.txt&quot;
         filenameparameter=&quot;filename&quot;
-        filedirparameter=&quot;filedir&quot;
-  /&gt;
+        filedirparameter=&quot;filedir&quot;/&gt;
 &lt;/project&gt;
 
 &lt;xsl:stylesheet
@@ -694,12 +689,9 @@
 <pre>
 &lt;xslt ...&gt;
     &lt;sysproperty key="org.apache.xerces.xni.parser.XMLParserConfiguration"
-                 value="org.apache.xerces.parsers.XIncludeParserConfiguration"
-     /&gt;
+                 value="org.apache.xerces.parsers.XIncludeParserConfiguration"/&gt;
 &lt;xslt&gt;
 </pre>
-</blockquote>
-
 
 </body>
 </html>
diff --git a/manual/Tasks/subant.html b/manual/Tasks/subant.html
index 424bb67..c5bc952 100644
--- a/manual/Tasks/subant.html
+++ b/manual/Tasks/subant.html
@@ -18,76 +18,35 @@
 <html>
 <head>
   <meta http-equiv="Content-Language" content="en-us">
+  <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
   <title>Subant Task</title>
 </head>
 
-<body bgcolor="#ffffff" text="#000000" link="#525D76"
-      alink="#525D76" vlink="#525D76">
-
-<table border="0" width="100%" cellspacing="4">
-
-  <!-- PAGE HEADER -->
-  <tr>
-    <td>
-      <table border="0" width="100%"><tr>
-          <td valign="bottom">
-            <font size="+3" face="arial,helvetica,sanserif"><strong>Subant Task</strong></font>
-            <br><font face="arial,helvetica,sanserif">Calls a given target for all defined sub-builds.</font>
-          </td>
-          <td>
-            <!-- PROJECT LOGO -->
-            <a href="http://ant.apache.org/">
-              <img src="../images/ant_logo_large.gif" align="right" alt="Apache Ant" border="0">
-            </a>
-          </td>
-      </tr></table>
-    </td>
-  </tr>
-
-  <!-- START RIGHT SIDE MAIN BODY -->
-  <tr>
-    <td  valign="top" align="left">
-
-          <!-- Applying task/description -->
-    <!-- Start Description -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-
-      <tr><td bgcolor="#525D76">
-        <font color="#ffffff" face="arial,helvetica.sanserif">
-          <a name="description">
-          <strong>Description</strong></a></font>
-      </td></tr>
-
-      <tr><td><blockquote>
+<body>
+<h2>Subant Task</h2>
+<h3 id="description">Description</h3>
 <p>
             Calls a given target for all defined sub-builds.
             This is an extension
-            of ant for bulk project execution.
+            of Ant for bulk project execution.
 
             <strong>This task must not be used outside of a
                 <code>target</code> if it invokes the same build file it is
                 part of.</strong>
-        </p>
-        <p><em>Since Apache Ant 1.6</em></p>
+</p>
+<p><em>Since Apache Ant 1.6</em></p>
 
-<p><code>subant</code> uses <code>ant</code> internally so many things
+<p>
+  <code>subant</code> uses <code>ant</code> internally so many things
   said in <a href="ant.html"><code>ant</code>'s manual page</a> apply
-  here as well.</p>
+  here as well.
+</p>
 
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <!-- Subsection heading -->
-      <tr><td bgcolor="#828DA6">
-          <font color="#ffffff" face="arial,helvetica.sanserif">
-                              <a name="Use with directories">
-          <strong>Use with directories</strong></a></font>
-      </td></tr>
-      <!-- Subsection body -->
-      <tr><td>
-        <p>
+<h3 id="Use with directories">Use with directories</h3>
+<p>
                 subant can be used with directory sets to execute a build from different directories.
                 2 different options are offered :
-            </p>
+</p>
 <ul>
                 <li>
                     to run the same build file <code>/somepath/otherpath/mybuild.xml</code>
@@ -96,381 +55,196 @@
                 <li>if you want to run <code>directory1/mybuild.xml</code>, <code>directory2/mybuild.xml</code>, <code>....</code>,
                     use the antfile attribute. The subant task does not set the base directory for you in this case, because you can specify it in each build file.
                 </li>
-            </ul>
+</ul>
 
-      </td></tr>
-    </table>
-
-      </blockquote></td></tr>
-
-    </table>
-    <!-- End Description -->
-
- <!-- Ignore -->
-
-
-
-    <!-- Start Attributes -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#525D76">
-        <font color="#ffffff" face="arial,helvetica.sanserif">
-          <a name="attributes">
-          <strong>Parameters</strong></a></font>
-      </td></tr>
-      <tr><td><blockquote>
-        <table>
-          <tr>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Attribute</b></font>
-        </td>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Description</b></font>
-        </td>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Type</b></font>
-        </td>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Requirement</b></font>
-        </td>
-          </tr>
-    <!-- Attribute Group -->
-
-    <!-- Attribute Group -->
-        <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">antfile</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Build file name, to use in conjunction with directories.<br> Defaults to "build.xml".<br> If <code>genericantfile</code> is set, this attribute is ignored.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left" rowspan="10">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Optional</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">buildpath</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Set the buildpath to be used to find sub-projects.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Path</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">buildpathref</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Buildpath to use, by reference.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Reference</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">failonerror</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Sets whether to fail with a build exception on error, or go on.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">genericantfile</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Build file path, to use in conjunction with directories.<br> Use <code>genericantfile</code>, in order to run the same build file with different basedirs.<br> If this attribute is set, <code>antfile</code> is ignored.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">File</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">inheritall</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1"
-                        face="arial,helvetica,sanserif">Corresponds to
-                        <code>&lt;ant&gt;</code>'s
-                        <code>inheritall</code> attribute but defaults
-                        to false in this task..</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">inheritrefs</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Corresponds to <code>&lt;ant&gt;</code>'s <code>inheritrefs</code> attribute.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">output</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Corresponds to <code>&lt;ant&gt;</code>'s <code>output</code> attribute.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">target</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"></font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
-        </td>
-    </tr>
-
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">verbose</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">
-            Enable/ disable log messages showing when each sub-build path is entered/ exited.
-            The default value is false.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
-        </td>
-    </tr>
-
-
-        </table>
-      </blockquote></td></tr>
-
-    </table>
-    <!-- End Attributes -->
-
-    <!-- Start Elements -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-
-      <tr><td bgcolor="#525D76">
-        <font color="#ffffff" face="arial,helvetica.sanserif">
-          <a name="elements">
-          <strong>Parameters as nested elements</strong></a></font>
-      </td></tr>
-
-      <tr><td><blockquote>
-    <!-- Start Element -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#828DA6">
-        <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
-          <strong>any filesystem based <a href="../Types/resources.html#collection">resource collection</a></strong></font>
-      </td></tr>
-      <tr><td><blockquote>
+<h3 id="attributes">Parameters</h3>
+<table>
+  <tr>
+    <td valign="top" align="left">
+      <b>Attribute</b>
+    </td>
+    <td valign="top" align="left">
+      <b>Description</b>
+    </td>
+    <td valign="top" align="left">
+      <b>Type</b>
+    </td>
+    <td valign="top" align="left">
+      <b>Requirement</b>
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      antfile
+    </td>
+    <td valign="top" align="left">
+      Build file name, to use in conjunction with directories.<br> Defaults to "build.xml".<br> If <code>genericantfile</code> is set, this attribute is ignored.
+    </td>
+    <td valign="top" align="left">
+      String
+    </td>
+    <td valign="top" align="left" rowspan="10">
+      Optional
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      buildpath
+    </td>
+    <td valign="top" align="left">
+      Set the buildpath to be used to find sub-projects.
+    </td>
+    <td valign="top" align="left">
+      Path
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      buildpathref
+    </td>
+    <td valign="top" align="left">
+      Buildpath to use, by reference.
+    </td>
+    <td valign="top" align="left">
+      Reference
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      failonerror
+    </td>
+    <td valign="top" align="left">
+      Sets whether to fail with a build exception on error, or go on.
+    </td>
+    <td valign="top" align="left">
+      boolean
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      genericantfile
+    </td>
+    <td valign="top" align="left">
+      Build file path, to use in conjunction with directories.<br> Use <code>genericantfile</code>, in order to run the same build file with different basedirs.<br> If this attribute is set, <code>antfile</code> is ignored.
+    </td>
+    <td valign="top" align="left">
+      File
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      inheritall
+    </td>
+    <td valign="top" align="left">
+      Corresponds to
+        <code>&lt;ant&gt;</code>'s
+        <code>inheritall</code> attribute but defaults
+        to false in this task..
+    </td>
+    <td valign="top" align="left">
+      boolean
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      inheritrefs
+    </td>
+    <td valign="top" align="left">
+      Corresponds to <code>&lt;ant&gt;</code>'s <code>inheritrefs</code> attribute.
+    </td>
+    <td valign="top" align="left">
+      boolean
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      output
+    </td>
+    <td valign="top" align="left">
+      Corresponds to <code>&lt;ant&gt;</code>'s <code>output</code> attribute.
+    </td>
+    <td valign="top" align="left">
+      String
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      target
+    </td>
+    <td valign="top" align="left">&nbsp;</td>
+    <td valign="top" align="left">
+      String
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      verbose
+    </td>
+    <td valign="top" align="left">
+        Enable/ disable log messages showing when each sub-build path is entered/ exited.
+        The default value is false.
+    </td>
+    <td valign="top" align="left">
+      boolean
+    </td>
+  </tr>
+</table>
+<h3 id="elements">Parameters as nested elements</h3>
+<h4>any filesystem based <a href="../Types/resources.html#collection">resource collection</a></h4>
         This includes <code>&lt;fileset&gt;</code>,
         <code>&lt;dirset&gt;</code> and <code>&lt;filelist&gt;</code>
         which are the nested resource collections supported prior
         to Ant 1.7.
- <!-- Ignore -->
- <!-- Ignore -->
-
-      </blockquote></td></tr>
-    </table>
-    <!-- End Element -->
-    <!-- Start Element -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#828DA6">
-        <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
-          <strong>dirset</strong> (org.apache.tools.ant.types.DirSet)</font>
-      </td></tr>
-      <tr><td><blockquote>
-        Adds a directory set to the implicit build path. <p> <em>Note that the directories will be added to the build path in no particular order, so if order is significant, one should use a file list instead!</em>
- <!-- Ignore -->
- <!-- Ignore -->
-
-      </blockquote></td></tr>
-    </table>
-    <!-- End Element -->
-    <!-- Start Element -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#828DA6">
-        <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
-          <strong>filelist</strong> (org.apache.tools.ant.types.FileList)</font>
-      </td></tr>
-      <tr><td><blockquote>
-        Adds an ordered file list to the implicit build path. <p> <em>Note that contrary to file and directory sets, file lists can reference non-existent files or directories!</em>
- <!-- Ignore -->
- <!-- Ignore -->
-
-      </blockquote></td></tr>
-    </table>
-    <!-- End Element -->
-    <!-- Start Element -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#828DA6">
-        <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
-          <strong>fileset</strong> (org.apache.tools.ant.types.FileSet)</font>
-      </td></tr>
-      <tr><td><blockquote>
-        Adds a file set to the implicit build path. <p> <em>Note that the directories will be added to the build path in no particular order, so if order is significant, one should use a file list instead!</em>
- <!-- Ignore -->
- <!-- Ignore -->
-
-      </blockquote></td></tr>
-    </table>
-    <!-- End Element -->
-    <!-- Start Element -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#828DA6">
-        <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
-          <strong>property</strong> (org.apache.tools.ant.taskdefs.Property)</font>
-      </td></tr>
-      <tr><td><blockquote>
-        Corresponds to <code>&lt;ant&gt;</code>'s nested <code>&lt;property&gt;</code> element.
-
-<p>When more than one nested <code>&lt;property&gt;</code> element
+<h4><strong>dirset</strong> (org.apache.tools.ant.types.DirSet)</h4>
+Adds a directory set to the implicit build path.
+<p>
+  <em>Note that the directories will be added to the build path in no particular order, so if order is significant, one should use a file list instead!</em>
+</p>
+<h4><strong>filelist</strong> (org.apache.tools.ant.types.FileList)</h4>
+Adds an ordered file list to the implicit build path.
+<p>
+  <em>Note that contrary to file and directory sets, file lists can reference non-existent files or directories!</em>
+</p>
+<h4><strong>fileset</strong> (org.apache.tools.ant.types.FileSet)</h4>
+Adds a file set to the implicit build path.
+<p>
+  <em>Note that the directories will be added to the build path in no particular order, so if order is significant, one should use a file list instead!</em>
+</p>
+<h4><strong>property</strong> (org.apache.tools.ant.taskdefs.Property)</h4>
+Corresponds to <code>&lt;ant&gt;</code>'s nested <code>&lt;property&gt;</code> element.
+<p>
+  When more than one nested <code>&lt;property&gt;</code> element
   would set a property of the same name, the one declared last will
   win.  This is for backwards compatibility reasons even so it is
   different from the way <code>&lt;property&gt;</code> tasks in build
-  files behave.</p>
-
- <!-- Ignore -->
- <!-- Ignore -->
-
-      </blockquote></td></tr>
-    </table>
-    <!-- End Element -->
-    <!-- Start Element -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#828DA6">
-        <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
-          <strong>propertyset</strong> (org.apache.tools.ant.types.PropertySet)</font>
-      </td></tr>
-      <tr><td><blockquote>
+  files behave.
+</p>
+<h4><strong>propertyset</strong> (org.apache.tools.ant.types.PropertySet)</h4>
         Corresponds to <code>&lt;ant&gt;</code>'s nested <code>&lt;propertyset&gt;</code> element.
- <!-- Ignore -->
- <!-- Ignore -->
-
-      </blockquote></td></tr>
-    </table>
-    <!-- End Element -->
-    <!-- Start Element -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#828DA6">
-        <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
-          <strong>buildpath</strong> (org.apache.tools.ant.types.Path)</font>
-      </td></tr>
-      <tr><td><blockquote>
+<h4><strong>buildpath</strong> (org.apache.tools.ant.types.Path)</h4>
         Creates a nested build path, and add it to the implicit build path.
- <!-- Ignore -->
- <!-- Ignore -->
-
-      </blockquote></td></tr>
-    </table>
-    <!-- End Element -->
-    <!-- Start Element -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#828DA6">
-        <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
-          <strong>buildpathelement</strong> (org.apache.tools.ant.types.Path.PathElement)</font>
-      </td></tr>
-      <tr><td><blockquote>
+<h4><strong>buildpathelement</strong> (org.apache.tools.ant.types.Path.PathElement)</h4>
         Creates a nested <code>&lt;buildpathelement&gt;</code>, and add it to the implicit build path.
- <!-- Ignore -->
- <!-- Ignore -->
-
-      </blockquote></td></tr>
-    </table>
-    <!-- End Element -->
-
-
-
-
-<!-- manually written -->
-    <!-- Start Element -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#828DA6">
-        <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
-          <strong>target</strong> (org.apache.tools.ant.taskdefs.Ant.TargetElement)</font>
-      </td></tr>
-      <tr><td><blockquote>
+<h4><strong>target</strong> (org.apache.tools.ant.taskdefs.Ant.TargetElement)</h4>
         You can specify multiple targets using nested <code>&lt;target&gt;</code> elements
         instead of using the target attribute.  These will be executed as if
         Ant had been invoked with a single target whose dependencies are the
         targets so specified, in the order specified.
- <!-- Ignore -->
- <!-- Ignore -->
-      <table border="1" cellpadding="2" cellspacing="0">
-        <tr>
-          <td valign="top"><b>Attribute</b></td>
-          <td valign="top"><b>Description</b></td>
-          <td align="center" valign="top"><b>Required</b></td>
-        </tr>
-        <tr>
-          <td valign="top">name</td>
-          <td valign="top">The name of the called target.</td>
-          <td valign="top" align="center">Yes</td>
-        </tr>
-      </table>
-      <p><em>since Ant 1.7</em>.</p>
-      </blockquote></td></tr>
-    </table>
-    <!-- End Element -->
-<!-- manually written end -->
-
-      </blockquote></td></tr>
-
-    </table>
-    <!-- End Elements -->
-
-
-
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-
-      <tr><td bgcolor="#525D76">
-          <font color="#ffffff" face="arial,helvetica.sanserif">
-                              <a name="examples">
-          <strong>Examples</strong></a></font>
-      </td></tr>
-
-      <tr><td><blockquote style="">
-        <pre>
+	<table>
+          <tr>
+            <td valign="top"><b>Attribute</b></td>
+            <td valign="top"><b>Description</b></td>
+            <td align="center" valign="top"><b>Required</b></td>
+          </tr>
+          <tr>
+            <td valign="top">name</td>
+            <td valign="top">The name of the called target.</td>
+            <td valign="top" align="center">Yes</td>
+          </tr>
+	</table>
+<p><em>since Ant 1.7</em>.</p>
+<h3 id="examples">Examples</h3>
+<pre>
         &lt;project name="subant" default="subant1"&gt;
             &lt;property name="build.dir" value="subant.build"/&gt;
             &lt;target name="subant1"&gt;
@@ -481,12 +255,12 @@
                 &lt;/subant&gt;
             &lt;/target&gt;
         &lt;/project&gt;
-        </pre>
+</pre>
 <p>
             this snippet build file will run ant in each subdirectory of the project directory,
             where a file called build.xml can be found.
             The property build.dir will have the value subant1.build in the ant projects called by subant.
-        </p>
+</p>
 <pre>
           &lt;subant target=""&gt;
               &lt;propertyset&gt;
@@ -495,27 +269,27 @@
               &lt;/propertyset&gt;
               &lt;fileset dir="." includes="*/build.xml"/&gt;
           &lt;/subant&gt;
-        </pre>
+</pre>
 <p>
             this snippet build file will run ant in each subdirectory of the project directory,
             where a file called build.xml can be found.
             All properties whose name starts with "foo" are passed, their names are changed to start with "bar" instead
-        </p>
+</p>
 <pre>
           &lt;subant target="compile" genericantfile="/opt/project/build1.xml"&gt;
               &lt;dirset dir="." includes="projects*"/&gt;
           &lt;/subant&gt;
-        </pre>
+</pre>
 <p>
             assuming the subdirs of the project dir are called projects1, projects2, projects3
             this snippet will execute the compile target of /opt/project/build1.xml,
             setting the basedir to projects1, projects2, projects3
-        </p>
-
-        <!-- manually written -->
-        <p>Now a little more complex - but useful - scenario. Assume that we have
-        a directory structure like this:</p>
-        <pre>
+</p>
+<p>
+  Now a little more complex - but useful - scenario. Assume that we have
+  a directory structure like this:
+</p>
+<pre>
         root
           |  common.xml
           |  build.xml
@@ -542,7 +316,6 @@
 
         <u><b>build.xml:</b></u><br>
         &lt;project&gt;
-
             &lt;macrodef name="iterate"&gt;
                 &lt;attribute name="target"/&gt;
                 &lt;sequential&gt;
@@ -564,45 +337,33 @@
         &lt;project name="modA"&gt;
             &lt;import file="../../common.xml"/&gt;
         &lt;/project&gt;
-        </pre>
+</pre>
 
-        <p>This results in very small buildfiles in the modules, maintainable
-        buildfile (common.xml) and a clear project structure. Additionally
-        the root buildfile is capable to run the whole build over all
-        modules.
-        </p>
+<p>
+  This results in very small buildfiles in the modules, maintainable
+  buildfile (common.xml) and a clear project structure. Additionally
+  the root buildfile is capable to run the whole build over all
+  modules.
+</p>
 
-        <pre>
+<pre>
         &lt;subant failonerror="false"&gt;
             &lt;fileset dir="." includes="**/build.xml" excludes="build.xml"/&gt;
             &lt;target name="clean"/&gt;
             &lt;target name="build"/&gt;
         &lt;/subant&gt;
-        </pre>
+</pre>
 
-        <p>Does a &quot;clean build&quot; for each subproject.</p>
-        <p><b>Hint:</b> because buildfiles are plain xml, you could generate the
-        masterbuildfile from the common buildfile by using a XSLT transformation:
-        </p>
+<p>Does a &quot;clean build&quot; for each subproject.</p>
+<p>
+  <b>Hint:</b> because buildfiles are plain xml, you could generate the
+  masterbuildfile from the common buildfile by using a XSLT transformation:
+</p>
 
-        <pre>
+<pre>
         &lt;xslt in=&quot;common.xml&quot;
               out=&quot;master.xml&quot;
-              style=&quot;${ant.home}/etc/common2master.xsl&quot;
-        /&gt;
-        </pre>
-
-        <!-- manually written -->
-
-      </blockquote></td></tr>
-
-    </table>
-
-    </td>
-  </tr>
-  <!-- END RIGHT SIDE MAIN BODY -->
-
-</table>
-
+              style=&quot;${ant.home}/etc/common2master.xsl&quot;/&gt;
+</pre>
 </body>
 </html>
diff --git a/manual/Tasks/symlink.html b/manual/Tasks/symlink.html
index df42abd..127514e 100644
--- a/manual/Tasks/symlink.html
+++ b/manual/Tasks/symlink.html
@@ -24,17 +24,20 @@
 
 <body>
 
-<h2><a name="symlink">Symlink</a></h2>
+<h2 id="symlink">Symlink</h2>
 <h3>Description</h3>
-<p> Manages symbolic links on Unix based platforms. Can be used to
-make an individual link, delete a link, create multiple links from properties files, 
-or create properties files describing links in the specified directories.
-Existing links are not overwritten by default.
-
-<p><a href="../Types/fileset.html">FileSet</a>s are used to select a
-set of links to record, or a set of property files to create links from. </p>
+<p>
+Manages symbolic links on platforms where Java supports symbolic links.
+Can be used to make an individual link, delete a link, create multiple links
+from properties files, or create properties files describing links in the
+specified directories. Existing files are not overwritten by default.
+</p>
+<p>
+<a href="../Types/fileset.html">FileSet</a>s are used to select a
+set of links to record, or a set of property files to create links from.
+</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -42,20 +45,20 @@
   </tr>
   <tr>
     <td valign="top">action</td>
-    <td valign="top">The type of action to perform, may be "single", 
+    <td valign="top">The type of action to perform, may be "single",
     "record", "recreate" or "delete".</td>
     <td valign="top" align="center">No, defaults to single.</td>
   </tr>
   <tr>
     <td valign="top">link</td>
     <td valign="top">The name of the link to be created or deleted.<br/>
-      <b>Note</b> this attribute is resolved against the current
+      <strong>Note</strong>: this attribute is resolved against the current
       working directory rather than the project's basedir for
       historical reasons.  It is recommended you always use an
       absolute path or a path like <code>${basedir}/some-path</code>
       as its value.
     </td>
-    <td valign="center" align="center" >required for 
+    <td valign="center" align="center" >required for
     action="single" or "delete". Ignored in other actions.</td>
   </tr>
   <tr>
@@ -65,14 +68,16 @@
   </tr>
   <tr>
     <td valign="top">linkfilename</td>
-    <td valign="top">The name of the properties file to create in 
+    <td valign="top">The name of the properties file to create in
     each included directory.</td>
-    <td valign="top" align="center">required for action="record". 
+    <td valign="top" align="center">required for action="record".
     Ignored in other actions.</td>
   </tr>
   <tr>
     <td valign="top">overwrite</td>
-    <td valign="top">Overwrite existing links or not.</td>
+    <td valign="top">Overwrite existing files or not. If overwrite is set to true, then
+    any existing file, specified by the link attribute, will be overwritten irrespective
+     of whether or not the existing file is a symbolic link.</td>
     <td valign="top" align="center">No; defaults to false.</td>
   </tr>
   <tr>
@@ -84,63 +89,51 @@
   </tr>
 </table>
 <h3>Parameters specified as nested elements</h3>
- 
+
 <h4>fileset</h4>
  <p><a href="../Types/fileset.html">FileSet</a>s
- are used when action = "record" to select directories and linknames to be recorded. 
- They are also used when action = "recreate" to specify both the name of the property 
- files to be processed, and the directories in which they can be found. At least one 
+ are used when action = "record" to select directories and linknames to be recorded.
+ They are also used when action = "recreate" to specify both the name of the property
+ files to be processed, and the directories in which they can be found. At least one
  fileset is required for each case.</p>
- 
+
 <h3>Examples</h3>
 
-  <p> Make a link named "foo" to a resource named "bar.foo" in subdir:</p>
+  <p>Make a link named "foo" to a resource named "bar.foo" in subdir:</p>
   <pre>
   &lt;symlink link="${dir.top}/foo" resource="${dir.top}/subdir/bar.foo"/&gt;
   </pre>
- 
-  <p> Record all links in subdir and it's descendants in files named
+
+  <p>Record all links in subdir and it's descendants in files named
   "dir.links"</p>
   <pre>
   &lt;symlink action="record" linkfilename="dir.links"&gt;
      &lt;fileset dir="${dir.top}" includes="subdir&#47;**"/&gt;
   &lt;/symlink&gt;
   </pre>
- 
-  <p> Recreate the links recorded in the previous example:</p>
+
+  <p>Recreate the links recorded in the previous example:</p>
   <pre>
   &lt;symlink action="recreate"&gt;
-     &lt;fileset dir="${dir.top}" includes="subdir&#47;**&#47;dir.links"/&gt;  
+     &lt;fileset dir="${dir.top}" includes="subdir&#47;**&#47;dir.links"/&gt;
   &lt;/symlink&gt;
   </pre>
- 
- <p> Delete a link named "foo":
+
+ <p>Delete a link named "foo":</p>
  <pre>
  &lt;symlink action="delete" link="${dir.top}/foo"/&gt;
  </pre>
 
-  <p><strong>Java 1.2 and earlier:</strong> Due to limitations on executing system
+  <p><strong>Java 1.2 and earlier</strong>: Due to limitations on executing system
   level commands in Java versions earlier than 1.3 this task may have difficulty
-  operating with a relative path in ANT_HOME. The typical symptom is an 
+  operating with a relative path in ANT_HOME. The typical symptom is an
   IOException where Apache Ant can't find /some/working/directory${ANT_HOME}/bin/antRun
   or something similar. The workaround is to change your ANT_HOME environment
   variable to an absolute path, which will remove the /some/working/directory portion
-  of the above path and allow ant to find the correct commandline execution script.
- 
-  <p><strong>LIMITATIONS:</strong> Because Java has no direct support for
-  handling symlinks this task divines them by comparing canonical and
-  absolute paths. On non-unix systems this may cause false positives.
-  Furthermore, any operating system on which the command
-  <code>ln -s &lt;linkname&gt; &lt;resourcename&gt;</code> is not a valid 
-  command on the command line will not be able to use action="single" or 
-  action="recreate". Action="record" and action=delete should still work. Finally, 
-  the lack of support for symlinks in Java means that all links are recorded as 
-  links to the <strong>canonical</strong> resource name. Therefore the link:
-  <code>link --> subdir/dir/../foo.bar</code> will be recorded as
-  <code>link=subdir/foo.bar</code> and restored as
-  <code>link --> subdir/foo.bar</code></p>
+  of the above path and allow Ant to find the correct commandline execution script.
 
-
+<p><strong>Note</strong>: <em>Since Ant 1.10.2</em>, this task relies on the symbolic
+    link support introduced in Java 7 through the java.nio.file.Files APIs</p>
 
 </body>
 </html>
diff --git a/manual/Tasks/sync.html b/manual/Tasks/sync.html
index 1d34aee..e315cec 100644
--- a/manual/Tasks/sync.html
+++ b/manual/Tasks/sync.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="get">Sync</a></h2>
+<h2 id="get">Sync</h2>
 <p><em>Since Apache Ant 1.6</em></p>
 <h3>Description</h3>
 
@@ -37,7 +37,7 @@
 dir, it will get removed from the target.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -47,7 +47,7 @@
     <td valign="top">todir</td>
     <td valign="top">the target directory to sync with the resource collections</td>
     <td align="center" valign="top">Yes</td>
-  </tr>  
+  </tr>
   <tr>
     <td valign="top">overwrite</td>
     <td valign="top">Overwrite existing files even if the destination
@@ -58,7 +58,7 @@
     <td valign="top">includeEmptyDirs</td>
      <td valign="top">Copy any empty directories included in the
        resource collection(s).<br/>
-       <b>Note</b> this attribute also controls the behavior for any
+       <strong>Note</strong> this attribute also controls the behavior for any
        nested &lt;preserveintarget&gt; element.  If this attribute is
        false (the default) empty directories that only exist in the
        target directory will be removed even if they are matched by
@@ -116,7 +116,7 @@
 defaults to false.</p>
 
 <h5>Additional Parameters</h5>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -132,7 +132,7 @@
       "wins".</td>
     <td align="center" valign="top">No, defaults to the value of the
       task's includeemptydirs attribute</td>
-  </tr>  
+  </tr>
 </table>
 
 <h3>Examples</h3>
@@ -159,8 +159,5 @@
 present in <em>generated-site</em> but keeps all files in any
 <em>CVS</em> sub-directory.</p>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/tar.html b/manual/Tasks/tar.html
index 4794d63..aa7a644 100644
--- a/manual/Tasks/tar.html
+++ b/manual/Tasks/tar.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="tar">Tar</a></h2>
+<h2 id="tar">Tar</h2>
 <h3>Description</h3>
 <p>Creates a tar archive.</p>
 <p>The <i>basedir</i> attribute is the reference directory from where to tar.</p>
@@ -78,14 +78,14 @@
 the limit.  It uses gnu rather than posix for backwards compatibility
   reasons.</p>
 
-<p>To achivieve best interoperability you should use
+<p>To achieve best interoperability you should use
   either <code>fail</code> or <code>posix</code> for the longfile attribute.</p>
 
 <p>This task can perform compression by setting the compression attribute to "gzip"
 or "bzip2".</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -141,8 +141,8 @@
   </tr>
   <tr>
     <td valign="top">compression</td>
-    <td valign="top">compression method.  Allowable values are 
-       &quot;none&quot;, &quot;gzip&quot; and &quot;bzip2&quot;.  Default is
+    <td valign="top">compression method.  Allowable values are
+       &quot;none&quot;, &quot;gzip&quot;, &quot;xz&quot; and &quot;bzip2&quot;.  Default is
        &quot;none&quot;.</td>
     <td valign="top" align="center">No</td>
   </tr>
@@ -165,7 +165,7 @@
 in addition to the standard elements, support one additional
 attributes
 
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -196,8 +196,7 @@
 <pre>
 &lt;tar destfile=&quot;${dist}/manual.tar&quot;
      basedir=&quot;htdocs/manual&quot;
-     excludes=&quot;mydocs/**, **/todo.html&quot;
-/&gt;</pre>
+     excludes=&quot;mydocs/**, **/todo.html&quot;/&gt;</pre>
 <p>tars all files in the <code>htdocs/manual</code> directory into a file called <code>manual.tar</code>
 in the <code>${dist}</code> directory. Files in the directory <code>mydocs</code>,
 or files with the name <code>todo.html</code> are excluded.</p>
@@ -242,15 +241,13 @@
 where some files need to be marked as executable (mode 755)
 and the rest are use the default mode (read-write by owner). The first
 fileset selects just the executable files. The second fileset must exclude
-the executable files and include all others. </p>
+the executable files and include all others.</p>
 
-
-
-<p><strong>Note: </strong> The tar task does not ensure that a file is only selected
+<p><strong>Note</strong>: The tar task does not ensure that a file is only selected
 by one resource collection. If the same file is selected by more than one collection, it will be included in the
 tar file twice, with the same path.</p>
 
-<p><strong>Note:</strong> The patterns in the include and exclude
+<p><strong>Note</strong>: The patterns in the include and exclude
 elements are considered to be relative to the corresponding dir
 attribute as with all other filesets.  In the example above,
 <code>${dist.name}</code> is not an absolute path, but a simple name
@@ -268,8 +265,8 @@
 will be retained in the resulting tar archive.</p>
 
 
-<p><strong>Note:</strong>
-  Please note the tar task creates a tar file, it does not append 
+<p><strong>Note</strong>:
+  Please note the tar task creates a tar file, it does not append
   to an existing tar file. The existing tar file is replaced instead.
   As with most tasks in Ant, the task only takes action if the output
   file (the tar file in this case) is older than the input files, or
@@ -278,4 +275,3 @@
 
 </body>
 </html>
-
diff --git a/manual/Tasks/taskdef.html b/manual/Tasks/taskdef.html
index 4f6f5d2..a83def4 100644
--- a/manual/Tasks/taskdef.html
+++ b/manual/Tasks/taskdef.html
@@ -24,12 +24,12 @@
 
 <body>
 
-<h2><a name="taskdef">Taskdef</a></h2>
+<h2 id="taskdef">Taskdef</h2>
 <h3>Description</h3>
   <p>Adds a task definition to the current project, such that this new task can be
     used in the current project.</p>
   <p>This task is a form of <a href="typedef.html">Typedef</a> with the
-    attributes "adapter" and "adaptto" set to the values 
+    attributes "adapter" and "adaptto" set to the values
     "org.apache.tools.ant.TaskAdapter" and "org.apache.tools.ant.Task"
     respectively.  Anything said in the <a href="typedef.html">manual
       page of typedef</a> applies to taskdef as well.</p>
@@ -38,7 +38,5 @@
 <p>makes a task called <code>myjavadoc</code> available to Apache Ant. The class <code>com.mydomain.JavadocTask</code>
 implements the task.</p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/telnet.html b/manual/Tasks/telnet.html
index 0ac65b3..af507fb 100644
--- a/manual/Tasks/telnet.html
+++ b/manual/Tasks/telnet.html
@@ -24,19 +24,19 @@
 
 <body>
 
-<h2><a name="telnet">Telnet</a></h2>
+<h2 id="telnet">Telnet</h2>
 <h3>Description</h3>
-Task to automate a remote telnet session. The task uses 
+Task to automate a remote telnet session. The task uses
 nested <tt>&lt;read&gt;</tt> to indicate strings to wait for, and
-<tt>&lt;write&gt;</tt> tags to specify text to send.  
+<tt>&lt;write&gt;</tt> tags to specify text to send.
 
-<p>If you do specify a userid and password, the system will 
+<p>If you do specify a userid and password, the system will
 assume a common unix prompt to wait on. This behavior can be easily over-ridden.</p>
-<p><b>Note:</b> This task depends on external libraries not included in the Apache Ant distribution.
+<p><strong>Note</strong>: This task depends on external libraries not included in the Apache Ant distribution.
 See <a href="../install.html#librarydependencies">Library Dependencies</a> for more information.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -73,16 +73,16 @@
      <td>No</td>
   </tr>
 </table>
-<h3><a name="nested">Nested Elements</a></h3>
+<h3 id="nested">Nested Elements</h3>
 The commands to send to the server, and responses to wait for, are
-described as nested elements.  
+described as nested elements.
 
 <h4>read</h4>
 
 <p>declare (as a text child of this element) a string to wait for.
 The element supports the timeout attribute, which overrides any
 timeout specified for the task as a whole. It also has a <tt>string</tt>
-attribute, which is an alternative to specifying the string as 
+attribute, which is an alternative to specifying the string as
 a text element.
 </p>
 <i>Always declare an opening and closing
@@ -93,7 +93,7 @@
 <h4>write</h4>
 
 <p>describes the text to send to the server. The <tt>echo</tt> boolean
-attribute controls whether the string is echoed to the local log; 
+attribute controls whether the string is echoed to the local log;
 this is "true" by default
 </p>
 <h3>Examples</h3>
@@ -122,8 +122,8 @@
 &lt;/telnet&gt;
 </pre></blockquote>
 
-A timeout can be specified at the <code>&lt;telnet&gt;</code> level or at the <code>&lt;read&gt;</code> level. 
-This will connect, issue a sleep command that is suppressed from displaying and wait 
+A timeout can be specified at the <code>&lt;telnet&gt;</code> level or at the <code>&lt;read&gt;</code> level.
+This will connect, issue a sleep command that is suppressed from displaying and wait
 10 seconds before quitting.
 <blockquote><pre>
 &lt;telnet userid=&quot;bob&quot; password=&quot;badpass&quot; server=&quot;localhost&quot; timeout=&quot;20&quot;&gt;
@@ -143,13 +143,11 @@
 &lt;/telnet&gt;
 </pre></blockquote>
 <p>
-To use this task against the WinNT telnet service, you need to configure the service to use 
-classic authentication rather than NTLM negotiated authentication. 
-This can be done in the Telnet Server Admin app: 
+To use this task against the WinNT telnet service, you need to configure the service to use
+classic authentication rather than NTLM negotiated authentication.
+This can be done in the Telnet Server Admin app:
 select "display/change registry settings", then "NTLM", then set the value of NTLM to 1.
 </p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/tempfile.html b/manual/Tasks/tempfile.html
index 1be00d0..e1c930a 100644
--- a/manual/Tasks/tempfile.html
+++ b/manual/Tasks/tempfile.html
@@ -14,60 +14,22 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-    
+
 <html>
 <head>
   <meta http-equiv="Content-Language" content="en-us">
+  <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
   <title>Tempfile Task</title>
 </head>
 
-<body bgcolor="#ffffff" text="#000000" link="#525D76"
-      alink="#525D76" vlink="#525D76">
-
-<table border="0" width="100%" cellspacing="4">
-
-  <!-- PAGE HEADER -->
-  <tr>
-    <td>
-      <table border="0" width="100%"><tr>
-          <td valign="bottom">
-            <font size="+3" face="arial,helvetica,sanserif"><strong>Tempfile  Task</strong></font>
-            <br><font face="arial,helvetica,sanserif">This task sets a property to the name of a temporary file.</font>
-          </td>
-          <td>
-            <!-- PROJECT LOGO -->
-            <a href="http://ant.apache.org/">
-              <img src="../images/ant_logo_large.gif" align="right" alt="Apache Ant" border="0">
-            </a>
-          </td>
-      </tr></table>
-    </td>
-  </tr>
-
-  <!-- START RIGHT SIDE MAIN BODY -->
-  <tr>
-    <td  valign="top" align="left">
-
-          <!-- Applying task/long-description -->
-    <!-- Start Description -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-
-      <tr><td bgcolor="#525D76">
-        <font color="#ffffff" face="arial,helvetica.sanserif">
-          <a name="description">
-          <strong>Description</strong></a></font>
-      </td></tr>
-
-      <tr><td><blockquote>
-
+<body>
+<h2>Tempfile Task</h2>
+<h3 id="description">Description</h3>
           This task sets a property to the name of a temporary file.
           Unlike <code>java.io.File.createTempFile</code>,
           this task does not actually create the temporary file, but it does guarantee that the
           file did not exist when the task was executed.
-
-          <p>Examples:
-
+<h3>Examples:</h3>
           <pre>&lt;tempfile property="temp.file"/&gt;</pre>
 
           create a temporary file
@@ -79,151 +41,94 @@
           <pre>&lt;tempfile property="temp.file" destDir="build"/&gt;</pre>
 
           create a temporary file in the <code>build</code> subdirectory
-
-      </blockquote></td></tr>
-
-    </table>
-    <!-- End Description -->
-
- <!-- Ignore -->
-
-
-
-    <!-- Start Attributes -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-      <tr><td bgcolor="#525D76">
-        <font color="#ffffff" face="arial,helvetica.sanserif">
-          <a name="attributes">
-          <strong>Parameters</strong></a></font>
-      </td></tr>
-      <tr><td><blockquote>
-        <table>
-          <tr>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Attribute</b></font>
-        </td>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Description</b></font>
-        </td>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Type</b></font>
-        </td>
-        <td bgcolor="#cccccc" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Requirement</b></font>
-        </td>
-          </tr>
-    <!-- Attribute Group -->    
-        <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">property</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Sets the property you wish to assign the temporary file to.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left" rowspan="1">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Required</font>
-        </td>
-    </tr>
-
-    <!-- Attribute Group -->    
-        <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">destdir</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Sets the destination directory. If not set, the basedir directory is used instead.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">File</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left" rowspan="5">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Optional</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">prefix</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Sets the optional prefix string for the temp file.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">suffix</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Sets the optional suffix string for the temp file.</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">deleteonexit</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Whether the temp file will be marked for deletion on normal exit of the Java Virtual Machine (even though the file may never be created); default <em>false</em>. <strong>Since Apache Ant 1.7</strong></font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
-        </td>
-    </tr>
-    <!-- Attribute -->
-    <tr>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">createfile</font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">Whether the temp file should be created by this task; default <em>false</em>.<strong>Since Ant 1.8</strong></font>
-        </td>
-        <td bgcolor="#eeeeee" valign="top" align="left">
-          <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
-        </td>
-    </tr>
-
-        </table>
-      </blockquote></td></tr>
-
-    </table>
-    <!-- End Attributes -->
-
-    <!-- Start Elements -->
-    <table border="0" cellspacing="0" cellpadding="2" width="100%">
-      <tr><td>&nbsp;</td></tr>
-
-      <tr><td bgcolor="#525D76">
-        <font color="#ffffff" face="arial,helvetica.sanserif">
-          <a name="elements">
-          <strong>Parameters as nested elements</strong></a></font>
-      </td></tr>
-
-      <tr><td><blockquote>
-
-      </blockquote></td></tr>
-
-    </table>
-    <!-- End Elements -->
-
-
+<h3 id="attributes">Parameters</h3>
+<table>
+  <tr>
+    <td valign="top" align="left">
+      <b>Attribute</b>
+    </td>
+    <td valign="top" align="left">
+      <b>Description</b>
+    </td>
+    <td valign="top" align="left">
+      <b>Type</b>
+    </td>
+    <td valign="top" align="left">
+      <b>Requirement</b>
     </td>
   </tr>
-  <!-- END RIGHT SIDE MAIN BODY -->
-
+  <tr>
+    <td valign="top" align="left">
+      property
+    </td>
+    <td valign="top" align="left">
+      Sets the property you wish to assign the temporary file to.
+    </td>
+    <td valign="top" align="left">
+      String
+    </td>
+    <td valign="top" align="left" rowspan="1">
+      Required
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      destdir
+    </td>
+    <td valign="top" align="left">
+      Sets the destination directory. If not set, the basedir directory is used instead.
+    </td>
+    <td valign="top" align="left">
+      File
+    </td>
+    <td valign="top" align="left" rowspan="5">
+      Optional
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      prefix
+    </td>
+    <td valign="top" align="left">
+      Sets the optional prefix string for the temp file.
+    </td>
+    <td valign="top" align="left">
+      String
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      suffix
+    </td>
+    <td valign="top" align="left">
+      Sets the optional suffix string for the temp file.
+    </td>
+    <td valign="top" align="left">
+      String
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      deleteonexit
+    </td>
+    <td valign="top" align="left">
+      Whether the temp file will be marked for deletion on normal exit of the Java Virtual Machine (even though the file may never be created); default <em>false</em>. <em>Since Apache Ant 1.7</em>
+    </td>
+    <td valign="top" align="left">
+      boolean
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" align="left">
+      createfile
+    </td>
+    <td valign="top" align="left">
+      Whether the temp file should be created by this task; default <em>false</em>. <em>Since Ant 1.8</em>
+    </td>
+    <td valign="top" align="left">
+      boolean
+    </td>
+  </tr>
 </table>
-
 </body>
 </html>
diff --git a/manual/Tasks/touch.html b/manual/Tasks/touch.html
index 8adee38..c265f50 100644
--- a/manual/Tasks/touch.html
+++ b/manual/Tasks/touch.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="touch">Touch</a></h2>
+<h2 id="touch">Touch</h2>
 <h3>Description</h3>
 
 <p>Changes the modification time of a resource and possibly creates it
@@ -32,7 +32,7 @@
 can also work on <a href="../Types/resources.html">resources</a> and
 resource collections (which also includes directories).  Prior to Apache Ant
 1.7 only FileSet or <a href="../Types/filelist.html">Filelist</a>
-(since Ant 1.6) have been supported.</p>
+(<em>since Ant 1.6</em>) have been supported.</p>
 
 <p>Ant uses the API of <code>java.io.File</code> to set the last
   modification time which has some limitations.  For example the
@@ -41,13 +41,13 @@
   milliseconds.  If you need more control you have to fall back to
   the <code>&lt;exec&gt;</code> task and native commands.</p>
 
-<p>Starting with Ant 1.8.2 Ant will log a warning message if it fails
+<p><em>Since Ant 1.8.2</em>, a warning message is logged upon failure
   to change the file modification time.  This will happen if you try
   to change the modification time of a file you do not own on many
   Unix systems, for example.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -68,9 +68,9 @@
   </tr>
   <tr>
     <td valign="top">datetime</td>
-    <td valign="top">Specifies the new modification time of the file. The 
-       special value &quot;now&quot; indicates the current time 
-       (now supported since Ant 1.8).</td>
+    <td valign="top">Specifies the new modification time of the file.
+       <em>since Ant 1.8</em>, the
+       special value &quot;now&quot; indicates the current time.</td>
   </tr>
   <tr>
     <td valign="top">pattern</td>
@@ -78,19 +78,19 @@
        the current locale.
        Defaults to "MM/dd/YYYY hh:mm a" or "MM/dd/yyyy hh:mm:ss a"
        using the US locale.
-       <b>Since Ant 1.6.3</b></td>
+       <em>Since Ant 1.6.3</em></td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
     <td valign="top">mkdirs</td>
     <td valign="top">Whether to create nonexistent parent
-       directories when touching new files. <b>Since Ant 1.6.3</b></td>
+       directories when touching new files. <em>Since Ant 1.6.3</em></td>
     <td valign="top" align="center">No, default <i>false</i>.</td>
   </tr>
   <tr>
     <td valign="top">verbose</td>
     <td valign="top">Whether to log the creation of new files.
-       <b>Since Ant 1.6.3</b></td>
+       <em>Since Ant 1.6.3</em></td>
     <td valign="top" align="center">No, default <i>true</i>.</td>
   </tr>
 </table>
@@ -99,7 +99,7 @@
 
 <p>You can use any number of nested resource collection elements to
 define the resources for this task and refer to resources defined
-elsewhere.  <b>Note:</b> resources passed to this task must implement
+elsewhere.  <strong>Note</strong>: resources passed to this task must implement
 the <code>org.apache.tools.ant.types.resources.Touchable</code>
 interface, this is true for all filesystem-based resources like those
 returned by path, fileset ot filelist.</p>
@@ -111,14 +111,14 @@
 collection.</p>
 
 <h4>mapper</h4>
-<p><em>Since Ant 1.6.3,</em> a nested <a href="../Types/mapper.html">
+<p><em>Since Ant 1.6.3</em>, a nested <a href="../Types/mapper.html">
     mapper</a> can be specified.  Files specified via nested
     <code>fileset</code>s, <code>filelist</code>s, or the <code>file</code>
     attribute are mapped using the specified mapper.  For each file mapped,
     the resulting files are touched. If no time has been specified and
     the original file exists its timestamp will be used.
-    If no time has been specified and the original file does not exist the 
-    current time is used. Since Ant 1.8 the task settings (<code>millis</code>,
+    If no time has been specified and the original file does not exist the
+    current time is used. <em>Since Ant 1.8</em> the task settings (<code>millis</code>,
     and <code>datetime</code>) have priority over the timestamp of the original
     file.</p>
 <h3>Examples</h3>
@@ -132,8 +132,8 @@
 <pre>  &lt;touch datetime=&quot;09/10/1974 4:30 pm&quot;&gt;
     &lt;fileset dir=&quot;src_dir&quot;/&gt;
   &lt;/touch&gt;</pre>
-<p>changes the modification time to Oct, 09 1974 4:30 pm of all files and directories 
-  found in <code>src_dir</code>. </p>
+<p>changes the modification time to Oct, 09 1974 4:30 pm of all files and directories
+  found in <code>src_dir</code>.</p>
 <pre>  &lt;touch file=&quot;myfile&quot; datetime=&quot;06/28/2000 2:02:17 pm&quot;/&gt;</pre>
 <p>creates <code>myfile</code> if it doesn't exist and changes the
 modification time to Jun, 28 2000 2:02:17 pm (14:02:17 for those used to 24
@@ -154,6 +154,5 @@
    <code>src</code> directory if it doesn't exist and changes the modification
    time of those files to the current time.</p>
 
-
 </body>
 </html>
diff --git a/manual/Tasks/translate.html b/manual/Tasks/translate.html
index 10e812a..ee5c2e4 100644
--- a/manual/Tasks/translate.html
+++ b/manual/Tasks/translate.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="translate">Translate</a></h2>
+<h2 id="translate">Translate</h2>
 <h3>Description</h3>
 <p>Identifies keys in files delimited by special tokens
 and translates them with values read from resource bundles.
@@ -76,7 +76,7 @@
 translate.
 </p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -160,8 +160,7 @@
 </p>
 <h3>Examples</h3>
 <p><b>Translate source file encoded in english into its japanese
-equivalent using a resource bundle encoded in japanese.
-</b></p>
+equivalent using a resource bundle encoded in japanese.</b></p>
 <pre>
   &lt;translate toDir=&quot;$(dest.dir}/ja&quot;
         starttoken=&quot;#&quot;
diff --git a/manual/Tasks/truncate.html b/manual/Tasks/truncate.html
index b7df3f7..2dabff6 100644
--- a/manual/Tasks/truncate.html
+++ b/manual/Tasks/truncate.html
@@ -24,18 +24,18 @@
 
 <body>
 
-<h2><a name="touch">Truncate</a></h2>
+<h2 id="touch">Truncate</h2>
 <h3>Description</h3>
 
 <p>Set the length of one or more files, as the intermittently available
 <code>truncate</code> Unix utility/function. In addition to working with
 a single file, this Task can also work on
 <a href="../Types/resources.html">resources</a> and resource collections.
-<strong>Since Apache Ant 1.7.1</strong>.
+<em>Since Apache Ant 1.7.1</em>.
 </p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -88,7 +88,7 @@
 
 <p>You can use any number of nested resource collection elements to
 define the resources for this task and refer to resources defined
-elsewhere.  <b>Note:</b> resources passed to this task are expected
+elsewhere.  <strong>Note</strong>: resources passed to this task are expected
 to be filesystem-based.</p>
 
 <h3>Examples</h3>
diff --git a/manual/Tasks/tstamp.html b/manual/Tasks/tstamp.html
index 6baa0c8..8a290ba 100644
--- a/manual/Tasks/tstamp.html
+++ b/manual/Tasks/tstamp.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="tstamp">Tstamp</a></h2>
+<h2 id="tstamp">Tstamp</h2>
 
 <h3>Description</h3>
 <p>Sets the <code>DSTAMP</code>, <code>TSTAMP</code>, and <code>TODAY</code>
@@ -40,14 +40,16 @@
 to indicate, for example, the release date. The best place for this task is
 probably in an initialization target.</p>
 
-<p><em>Since Ant 1.9.10</em> the magic
-  property <code>ant.tstamp.now</code> can be used to specify a fixed
-  date value in order to create reproducible builds. Its value must be
-  a number and is interpreted as seconds since the epoch (midnight
-  1970-01-01).</p>
+<p><em>Since Ant 1.10.2</em> the magic
+property <code>ant.tstamp.now</code> can be used to specify a fixed
+date value in order to create reproducible builds. Its value must be
+a number and is interpreted as seconds since the epoch (midnight
+1970-01-01). With <code>ant.tstamp.now.iso</code> you could also specify that
+value in ISO-8601 format (<code>1972-04-17T08:07:00Z</code>). If you specify a value
+in an invalid format an INFO message will be logged and the value will be ignored.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -61,13 +63,14 @@
 </table>
 
 <h3>Nested Elements</h3>
+<p>
 The Tstamp task supports a <code>&lt;format&gt;</code> nested element that
 allows a property to be set to the current date and time in a given format.
 The date/time patterns are as defined in the Java
 <a href="http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a> class.
 The format element also allows offsets to be applied to the time to generate different time values.
-<br><br>
-<table width="60%" border="1" cellpadding="2" cellspacing="0">
+</p>
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -160,8 +163,5 @@
 Sets three properties with the standard formats, prefixed with "start.":
 <code>start.DSTAMP</code>, <code>start.TSTAMP</code>, and <code>start.TODAY</code>.</p>
 
-
-
-
 </body>
 </html>
diff --git a/manual/Tasks/typedef.html b/manual/Tasks/typedef.html
index bdd58a7..3d4155d 100644
--- a/manual/Tasks/typedef.html
+++ b/manual/Tasks/typedef.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="typedef">Typedef</a></h2>
+<h2 id="typedef">Typedef</h2>
 <h3>Description</h3>
   <p>
     Adds a task or a data type definition to the current project
@@ -56,7 +56,7 @@
   <pre>
     typename=fully.qualified.java.classname
   </pre>
-    
+
   <p>
     The xml format is described in the
     <a href="../Types/antlib.html">Antlib</a> section.
@@ -84,7 +84,7 @@
     attribute to work.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -126,12 +126,13 @@
       to <a href="../Types/antlib.html">Antlib</a>.
       The default is "properties" unless the file/resource name ends with
       ".xml", in which case the format attribute will have the value "xml".
-      <b>since Apache Ant 1.6</b>
+      <em>Since Ant 1.6</em>
     </td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
-    <td valign="top">classpath</td> <td valign="top">the classpath to
+    <td valign="top">classpath</td>
+    <td valign="top">the classpath to
       use when looking up <code>classname</code>.</td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -147,7 +148,7 @@
     <td valign="top">the name of the loader that is
       used to load the class, constructed from the specified classpath. Use
       this to allow multiple tasks/types to be loaded with the same loader,
-      so they can call each other. <b>since Ant 1.5</b> </td>
+      so they can call each other. <em>Since Ant 1.5</em></td>
     <td align="center" valign="top">No</td>
   </tr>
   <tr>
@@ -155,11 +156,11 @@
     <td valign="top">The action to take if there was a failure in defining the
       type. The values are <i>fail</i>: cause a build exception; <i>report</i>:
       output a warning, but continue; <i>ignore</i>: do nothing.
-      <b>since Ant 1.6</b>
-      An additional value is <i>failall</i>: cause all behavior of fail,
+      <em>Since Ant 1.6</em>,
+      an additional value is <i>failall</i>: cause all behavior of fail,
       as well as a build exception for the resource or file attribute
-      if the resource or file is not found. <b>since Ant 1.7</b>
-      The default is <i>fail</i>.
+      if the resource or file is not found. <em>Since Ant 1.7</em>,
+      the default is <i>fail</i>.
     </td>
     <td valign="top" align="center">No</td>
   </tr>
@@ -171,7 +172,7 @@
       to wrap the defined class unless the defined class implements/extends
       the class defined by the attribute "adaptto".
       If "adaptto" is not set, the defined class will always be wrapped.
-      <b>since Ant 1.6</b>
+      <em>Since Ant 1.6</em>
     </td>
     <td valign="top" align="center">No</td>
   </tr>
@@ -181,7 +182,7 @@
       adapter attribute.
       If the defined class does not implement/extend the interface/class
       specified by this attribute, the adaptor class will be used
-      to wrap the class. <b>since Ant 1.6</b>
+      to wrap the class. <em>Since Ant 1.6</em>
     </td>
     <td valign="top" align="center">No</td>
   </tr>
@@ -189,24 +190,23 @@
     <td valign="top">uri</td>
     <td valign="top">
       The uri that this definition should live in.
-      <b>since Ant 1.6</b>
+      <em>Since Ant 1.6</em>
     </td>
     <td valign="top" align="center">No</td>
   </tr>
 </table>
   <h3>Parameters specified as nested elements</h3>
   <h4>classpath</h4>
-  <p><code>Typedef</code>'s <i>classpath</i> attribute is a 
+  <p><code>Typedef</code>'s <i>classpath</i> attribute is a
     <a href="../using.html#path">path-like structure</a> and can also be set
     via a nested <i>classpath</i> element.</p>
 
 <h3>Examples</h3>
   The following fragment defines define a type called <i>urlset</i>.
   <pre>
-    &lt;typedef name="urlset" classname="com.mydomain.URLSet"/&gt; </pre>
+    &lt;typedef name="urlset" classname="com.mydomain.URLSet"/&gt;</pre>
   The data type is now available to Ant. The
-  class <code>com.mydomain.URLSet</code> implements this type.</p>
-
+  class <code>com.mydomain.URLSet</code> implements this type.
 
   <p>
     Assuming a class <i>org.acme.ant.RunnableAdapter</i> that
@@ -234,15 +234,12 @@
     &lt;typedef name="filter1"
              classname="org.acme.filters.Filter1"
              classpathref="lib.path"
-             loaderref="lib.path.loader"
-             /&gt;
+             loaderref="lib.path.loader"/&gt;
     &lt;typedef name="filter2"
              classname="org.acme.filters.Filter2"
-             loaderref="lib.path.loader"
-             /&gt;
+             loaderref="lib.path.loader"/&gt;
   </pre>
-  
-  
+
   <p>
     If you want to load an antlib into a special xml-namespace, the <tt>uri</tt> attribute
     is important:
@@ -253,7 +250,7 @@
               resource="net/sf/antcontrib/antlib.xml"
               classpath="path/to/ant-contrib.jar"/&gt;
   </pre>
-            
+
 <p>Here the namespace
   declaration <code>xmlns:antcontrib="antlib:net.sf.antcontrib"</code>
   allows tasks and types of the AntContrib Antlib to be used with the
@@ -263,7 +260,5 @@
   prefix at any element to make it usable for the element it is
   declared on as well as all its child elements.</p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/unpack.html b/manual/Tasks/unpack.html
index dcc88a9..6537d31 100644
--- a/manual/Tasks/unpack.html
+++ b/manual/Tasks/unpack.html
@@ -24,19 +24,24 @@
 
 <body>
 
-<h2><a name="unpack">GUnzip/BUnzip2</a></h2>
+<h2 id="unpack">GUnzip/BUnzip2/UnXZ</h2>
 <h3>Description</h3>
-<p>Expands a resource packed using GZip or BZip2.</p>
+<p>Expands a resource packed using GZip, BZip2 or XZ.</p>
 
 <p>If <i>dest</i> is a directory the name of the destination file is
-the same as <i>src</i> (with the &quot;.gz&quot; or &quot;.bz2&quot;
+the same as <i>src</i> (with the &quot;.gz&quot;, &quot;.bz2&quot; or &quot;.xz&quot;
 extension removed if present). If <i>dest</i> is omitted, the parent
 dir of <i>src</i> is taken. The file is only expanded if the source
 resource is newer than the destination file, or when the destination file
 does not exist.</p>
 
+<p>XZ compression support has been added with Apache Ant 1.10.1 and
+depends on external libraries not included in the Ant distribution.
+See <a href="../install.html#librarydependencies">Library
+Dependencies</a> for more information.</p>
+
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -70,6 +75,10 @@
 </pre></blockquote>
 <p>expands <i>test.tar.bz2</i> to <i>test.tar</i></p>
 <blockquote><pre>
+&lt;unxz src=&quot;test.tar.xz&quot;/&gt;
+</pre></blockquote>
+<p>expands <i>test.tar.xz</i> to <i>test.tar</i></p>
+<blockquote><pre>
 &lt;gunzip src=&quot;test.tar.gz&quot; dest=&quot;test2.tar&quot;/&gt;
 </pre></blockquote>
 <p>expands <i>test.tar.gz</i> to <i>test2.tar</i></p>
@@ -104,14 +113,12 @@
 </pre>
 
 <p>The same is also true for <code>&lt;bunzip2&gt;</code> and
-<code>&lt;bzip2resource&gt;</code>.  <code>&lt;copy&gt;</code> offers
-additional features like <a
-href="../Types/filterchain.html">filtering files</a> on the fly,
-allowing a file to be mapped to multiple destinations, preserving the
-last modified time or a configurable file system timestamp
-granularity.</p>
-
-
+<code>&lt;bzip2resource&gt;</code> or <code>%lt;unxz&gt;</code>
+and <code>%lt;xzresource&gt;</code>.  <code>&lt;copy&gt;</code> offers
+additional features like <a href="../Types/filterchain.html">filtering
+files</a> on the fly, allowing a file to be mapped to multiple
+destinations, preserving the last modified time or a configurable file
+system timestamp granularity.</p>
 
 </body>
 </html>
diff --git a/manual/Tasks/untar.html b/manual/Tasks/untar.html
index bfaf28f..c087c5d 100644
--- a/manual/Tasks/untar.html
+++ b/manual/Tasks/untar.html
@@ -24,12 +24,11 @@
 
 <body>
 
-<h2><a name="untar">Untar</a></h2>
+<h2 id="untar">Untar</h2>
 <h3>Description</h3>
 <p>Untars a tarfile.</p>
 
-This document has moved <A HREF="unzip.html">here</A>
+This document has moved <a href="unzip.html">here</a>
 
 </body>
 </html>
-
diff --git a/manual/Tasks/unzip.html b/manual/Tasks/unzip.html
index 8d93b70..41b19e5 100644
--- a/manual/Tasks/unzip.html
+++ b/manual/Tasks/unzip.html
@@ -24,11 +24,11 @@
 
 <body>
 
-<h2><a name="unzip">Unjar/Untar/Unwar/Unzip</a></h2>
+<h2 id="unzip">Unjar/Untar/Unwar/Unzip</h2>
 <h3>Description</h3>
 <p>Unzips a zip-, war-, or jar file.</p>
 <p><a href="../Types/patternset.html">PatternSet</a>s are used to select files to extract
-<I>from</I> the archive.  If no patternset is used, all files are extracted.
+<i>from</i> the archive.  If no patternset is used, all files are extracted.
 </p>
 
 <p><a href="../Types/resources.html#collection">Resource
@@ -66,7 +66,7 @@
 
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -91,10 +91,10 @@
   </tr>
   <tr>
     <td valign="top">compression</td>
-    <td valign="top"><b>Note:</b> This attribute is only available for
+    <td valign="top"><strong>Note</strong>: This attribute is only available for
     the <code>untar</code> task.<br>
     compression method.  Allowable values are &quot;none&quot;,
-    &quot;gzip&quot; and &quot;bzip2&quot;.  Default is
+    &quot;gzip&quot;, &quot;xz&quot; and &quot;bzip2&quot;.  Default is
     &quot;none&quot;.</td>
     <td valign="top" align="center">No</td>
   </tr>
@@ -130,9 +130,9 @@
   </tr>
   <tr>
     <td valign="top">scanForUnicodeExtraFields</td>
-    <td valign="top"><b>Note:</b> This attribute is not available for
+    <td valign="top"><strong>Note</strong>: This attribute is not available for
     the <code>untar</code> task.<br>
-      If the archive contains uncode extra fields then use them to set
+      If the archive contains Unicode extra fields then use them to set
       the file names, ignoring the specified encoding.
       <br/>See also the <a href="zip.html#encoding">discussion in the
       zip task page</a></td>
diff --git a/manual/Tasks/uptodate.html b/manual/Tasks/uptodate.html
index c724f20..b5a8f5c 100644
--- a/manual/Tasks/uptodate.html
+++ b/manual/Tasks/uptodate.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="uptodate">Uptodate</a></h2>
+<h2 id="uptodate">Uptodate</h2>
 <h3>Description</h3>
 <p>Sets a property if a target file or set of target files is more up-to-date
 than a source file or set of source files. A single source file is specified
@@ -45,7 +45,7 @@
 <p>Normally, this task is used to set properties that are useful to avoid
 target execution depending on the relative age of the specified files.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -77,12 +77,12 @@
 </table>
 
 <h3>Parameters specified as nested elements</h3>
-<h4><a name="srcfiles">srcfiles</a></h4>
+<h4 id="srcfiles">srcfiles</h4>
 <p>The nested <code>&lt;srcfiles&gt;</code> element is a
 <a href="../Types/fileset.html">fileset</a> and allows you to
 specify a set of files to check against the target file(s).</p>
 
-<p><strong>Note:</strong> You can specify either the <code>srcfile</code>
+<p><strong>Note</strong>: You can specify either the <code>srcfile</code>
 attribute or nested <code>&lt;srcfiles&gt;</code> elements, but not both.
 
 <p>Note that the task will completely ignore any directories that seem
@@ -90,13 +90,13 @@
   files.  If you need logic that applies to directories as well, use a
   nested srcresource and a dirset (for example).</p>
 
-<h4><a name="srcresources">srcresources</a></h4>
+<h4 id="srcresources">srcresources</h4>
 <p>The nested <code>&lt;srcresources&gt;</code> element is a <a
 href="../Types/resources.html#union">union</a> and allows you to
 specify a collection of resources to check against the target file(s).
 <em>Since Apache Ant 1.7</em></p>
 
-<h4><a name="mapper">mapper</a></h4>
+<h4 id="mapper">mapper</h4>
 <p>The nested <code>&lt;mapper&gt;</code> element allows you to specify
 a set of target files to check for being up-to-date with respect to a
 set of source files.</p>
@@ -120,7 +120,7 @@
     &lt;srcfiles dir= &quot;${src}/xml&quot; includes=&quot;**/*.dtd&quot;/&gt;
     &lt;mapper type=&quot;merge&quot; to=&quot;${deploy}\xmlClasses.jar&quot;/&gt;
   &lt;/uptodate&gt;</pre>
-as well.
+<p>as well.
 
 The <code>xmlBuild.notRequired</code> property can then be used in a
 <code>&lt;target&gt;</code> tag's <code>unless</code> attribute to
@@ -130,6 +130,7 @@
   ...
 &lt;/target&gt;
 </pre>
+<p>
 will first run the <code>chkXmlBuild</code> target, which contains
 the <code>&lt;uptodate&gt;</code> task that determines whether
 <code>xmlBuild.notRequired</code> gets set. The property named in
@@ -138,7 +139,7 @@
 then the <code>xmlBuild</code> target won't be run.
 </p>
 
-<p> The following example shows a single source file being checked
+<p>The following example shows a single source file being checked
 against a single target file:</p>
 <pre>  &lt;uptodate property=&quot;isUpToDate&quot;
             srcfile=&quot;/usr/local/bin/testit&quot;
@@ -147,7 +148,6 @@
 <p>sets the property <code>isUpToDate</code> to <code>true</code>
 if <code>/usr/local/bin/testit</code> is not newer than
 <code>${build}/.flagfile</code>.</p>
-</p>
   <p>
     The following shows usage of a relative mapper.
   </p>
@@ -170,8 +170,5 @@
     &lt;/uptodate&gt;
   </pre>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/verifyjar.html b/manual/Tasks/verifyjar.html
index 4be2788..58a751b 100644
--- a/manual/Tasks/verifyjar.html
+++ b/manual/Tasks/verifyjar.html
@@ -24,16 +24,15 @@
 
 <body>
 
-<h2><a name="verifyjar">VerifyJar</a></h2>
+<h2 id="verifyjar">VerifyJar</h2>
 <h3>Description</h3>
 <p>Verifies JAR files with the <tt>jarsigner</tt> command line tool.
 It will take a named file in the <tt>jar</tt> attribute. Nested paths are also
 supported
 </p>
 
-
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -100,10 +99,10 @@
       jarsigner command.
       <em>since Ant 1.8.0</em>.</td>
     <td align="center" valign="top">No</td>
-  </tr>  
+  </tr>
 </table>
 <h3>Parameters as nested elements</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -116,13 +115,13 @@
   </tr>
   <tr>
     <td valign="top">fileset</td>
-    <td valign="top">fileset of JAR files to verify. </td>
+    <td valign="top">fileset of JAR files to verify.</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
     <td valign="top">sysproperty</td>
     <td valign="top">JVM system properties, with the syntax of Ant
-    <a href="exec.html#env">environment variables</a> </td>
+    <a href="exec.html#env">environment variables</a></td>
     <td valign="top" align="center">No, and only one can be supplied</td>
   </tr>
  </table>
@@ -138,8 +137,5 @@
   keystore and private key via &quot;secret&quot; password.
 </p>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Tasks/vss.html b/manual/Tasks/vss.html
index 2c0ed68..a11f8bb 100644
--- a/manual/Tasks/vss.html
+++ b/manual/Tasks/vss.html
@@ -41,7 +41,7 @@
     <li><a href="#tasks">The Tasks</a></li>
 </ul>
 <br>
-<h2><a name="intro">Introduction</a></h2>
+<h2 id="intro">Introduction</h2>
 <p>These tasks provide an interface to the
 <a href="http://msdn.microsoft.com/ssafe/default.asp" target="_top">Microsoft Visual SourceSafe</a> SCM.
 The <code>org.apache.tools.ant.taskdefs.optional.vss</code> package consists of a simple framework to support
@@ -53,9 +53,10 @@
 that ss.exe was not found. Check to see if you can run it from the
 command line -you may need to alter your path, or set the <tt>ssdir</tt>
 property.
-<h2><a name="tasks">The Tasks</a></h2>
+<h2 id="tasks">The Tasks</h2>
 
-<table border="0" cellspacing="0" cellpadding="3">
+<table>
+    <tr><td>Task</td><td>Description</td></tr>
     <tr>
         <td><a href="#vssget">vssget</a></td>
         <td>Retrieves a copy of the specified VSS file(s).</td>
@@ -95,13 +96,13 @@
 
 <!-- VSSGET -->
 
-<h2><a name="vssget">VssGet</a></h2>
+<h2 id="vssget">VssGet</h2>
 <h3>Description</h3>
 Task to perform GET commands to Microsoft Visual SourceSafe.
 <p>If you specify two or more attributes from version, date and
 label only one will be used in the order version, date, label.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -118,7 +119,7 @@
      <td>username[,password] - The username and password needed to get access
          to VSS. Note that you may need to specify both (if you have a password) -
          Ant/VSS will hang if you leave the password out and VSS does not accept
-         login without a password. </td>
+         login without a password.</td>
      <td>No</td>
   </tr>
   <tr>
@@ -155,7 +156,7 @@
   <tr>
      <td>version</td>
      <td>a version number to get</td>
-     <td rowspan="3">No, only one of these allowed</td>
+     <td rowspan="3">No; only one of these may be used</td>
   </tr>
   <tr>
      <td>date</td>
@@ -178,7 +179,7 @@
   </tr>
   <tr>
     <td>writablefiles</td>
-    <td>Behavior when local files are writable. Valid options are: <code>replace</code>, 
+    <td>Behavior when local files are writable. Valid options are: <code>replace</code>,
         <code>skip</code> and <code>fail</code>; Defaults to <code>fail</code>
         <br><code>skip</code> implies <code>failonerror=false</code></td>
     <td>No</td>
@@ -190,8 +191,8 @@
   </tr>
   <tr>
     <td>filetimestamp</td>
-    <td>Set the behavior for timestamps of local files. Valid options are <code>current</code>, 
-        <code>modified</code>, or <code>updated</code>. Defaults to <code>current</code>.</td> 
+    <td>Set the behavior for timestamps of local files. Valid options are <code>current</code>,
+        <code>modified</code>, or <code>updated</code>. Defaults to <code>current</code>.</td>
     <td>No</td>
   </tr>
 </table>
@@ -215,13 +216,13 @@
 
 <!-- VSSLABEL -->
 
-<h2><a name="vsslabel">VssLabel</a></h2>
+<h2 id="vsslabel">VssLabel</h2>
 <h3>Description</h3>
 Task to perform LABEL commands to Microsoft Visual SourceSafe.
 <p>Assigns a label to the specified version or current version of a file or
 project.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
    <tr>
      <th>Attribute</th>
      <th>Values</th>
@@ -238,7 +239,7 @@
      <td>username[,password] - The username and password needed to get access
          to VSS. Note that you may need to specify both (if you have a password) -
          Ant/VSS will hang if you leave the password out and VSS does not accept
-         login without a password. </td>
+         login without a password.</td>
      <td>No</td>
   </tr>
   <tr>
@@ -307,11 +308,11 @@
 
 <!-- VSSHISTORY -->
 
-<h2><a name="vsshistory">VssHistory</a></h2>
+<h2 id="vsshistory">VssHistory</h2>
 <h3>Description</h3>
 Task to perform HISTORY commands to Microsoft Visual SourceSafe.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -328,7 +329,7 @@
      <td>username[,password] - The username and password needed to get access
          to VSS. Note that you may need to specify both (if you have a password) -
          Ant/VSS will hang if you leave the password out and VSS does not accept
-         login without a password. </td>
+         login without a password.</td>
      <td>No</td>
   </tr>
   <tr>
@@ -404,7 +405,7 @@
 <h4>Specifying the time-frame</h4>
 <p>There are different ways to specify what time-frame you wish to evaluate:</p>
 <ul>
-  <li>Changes between two dates: Specify both <code>fromDate</code> and <code>toDate</code> </li>
+  <li>Changes between two dates: Specify both <code>fromDate</code> and <code>toDate</code></li>
   <li>Changes before a date: Specify <code>toDate</code></li>
   <li>Changes after a date: Specify <code>fromDate</code></li>
   <li>Changes X Days before a date: Specify <code>toDate</code> and (negative!) <code>numDays</code></li>
@@ -448,11 +449,11 @@
 
 <!-- VSSCHECKIN -->
 
-<h2><a name="vsscheckin">VssCheckin</a></h2>
+<h2 id="vsscheckin">VssCheckin</h2>
 <h3>Description</h3>
 Task to perform CHECKIN commands to Microsoft Visual SourceSafe.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -469,7 +470,7 @@
      <td>username[,password] - The username and password needed to get access
          to VSS. Note that you may need to specify both (if you have a password) -
          Ant/VSS will hang if you leave the password out and VSS does not accept
-         login without a password. </td>
+         login without a password.</td>
      <td>No</td>
   </tr>
   <tr>
@@ -529,13 +530,13 @@
 
 <!-- VSSCHECKOUT -->
 
-<h2><a name="vsscheckout">VssCheckout</a></h2>
+<h2 id="vsscheckout">VssCheckout</h2>
 <h3>Description</h3>
 Task to perform CHECKOUT commands to Microsoft Visual SourceSafe.
 <p>If you specify two or more attributes from version, date and
 label only one will be used in the order version, date, label.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -552,7 +553,7 @@
      <td>username[,password] - The username and password needed to get access
          to VSS. Note that you may need to specify both (if you have a password) -
          Ant/VSS will hang if you leave the password out and VSS does not accept
-         login without a password. </td>
+         login without a password.</td>
      <td>No</td>
   </tr>
   <tr>
@@ -584,7 +585,7 @@
   <tr>
      <td>version</td>
      <td>a version number to get</td>
-     <td rowspan="3">No, only one of these allowed</td>
+     <td rowspan="3">No; only one of these may be used</td>
   </tr>
   <tr>
      <td>date</td>
@@ -596,7 +597,7 @@
   </tr>
   <tr>
     <td>writablefiles</td>
-    <td>Behavior when local files are writable. Valid options are: <code>replace</code>, 
+    <td>Behavior when local files are writable. Valid options are: <code>replace</code>,
         <code>skip</code> and <code>fail</code>; Defaults to <code>fail</code>
         <br><code>skip</code> implies <code>failonerror=false</code></td>
     <td>No</td>
@@ -608,13 +609,13 @@
   </tr>
   <tr>
     <td>filetimestamp</td>
-    <td>Set the behavior for timestamps of local files. Valid options are <code>current</code>, 
-        <code>modified</code>, or <code>updated</code>. Defaults to <code>current</code>.</td> 
+    <td>Set the behavior for timestamps of local files. Valid options are <code>current</code>,
+        <code>modified</code>, or <code>updated</code>. Defaults to <code>current</code>.</td>
     <td>No</td>
   </tr>
   <tr>
     <td>getlocalcopy</td>
-    <td>Set the behavior to retrieve local copies of the files. Defaults to true.</td> 
+    <td>Set the behavior to retrieve local copies of the files. Defaults to true.</td>
     <td>No</td>
   </tr>
 </table>
@@ -634,11 +635,11 @@
 
 <!-- VSSADD -->
 
-<h2><a name="vssadd">VssAdd</a></h2>
+<h2 id="vssadd">VssAdd</h2>
 <h3>Description</h3>
 Task to perform ADD commands to Microsoft Visual SourceSafe.
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -654,7 +655,7 @@
      <td>username[,password] - The username and password needed to get access
          to VSS. Note that you may need to specify both (if you have a password) -
          Ant/VSS will hang if you leave the password out and VSS does not accept
-         login without a password. </td>
+         login without a password.</td>
      <td>No</td>
   </tr>
   <tr>
@@ -708,12 +709,12 @@
 
 <!-- VSSCP -->
 
-<h2><a name="vsscp">VssCp</a></h2>
+<h2 id="vsscp">VssCp</h2>
 <h3>Description</h3>
 <p>Task to perform CP (Change Project) commands to Microsoft Visual SourceSafe.</p>
 <p>This task is typically used before a VssAdd in order to set the target project</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -730,7 +731,7 @@
      <td>username[,password] - The username and password needed to get access
          to VSS. Note that you may need to specify both (if you have a password) -
          Ant/VSS will hang if you leave the password out and VSS does not accept
-         login without a password. </td>
+         login without a password.</td>
      <td>No</td>
   </tr>
   <tr>
@@ -762,12 +763,12 @@
 
 <!-- VSSCREATE -->
 
- <h2><a name="vsscreate">VssCreate</a></h2>
- <h3>Description</h3>
+<h2 id="vsscreate">VssCreate</h2>
+<h3>Description</h3>
  Task to perform CREATE commands to Microsoft Visual Source Safe.
  <p>Creates a new project in VSS.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <th>Attribute</th>
     <th>Values</th>
@@ -816,8 +817,6 @@
 </pre>
 </blockquote>
 <p>Creates the VSS-Project <i>$/existingProject/newProject</i>.</p>
-<hr>
 
-<!-- Footer -->
 </body>
 </html>
diff --git a/manual/Tasks/waitfor.html b/manual/Tasks/waitfor.html
index 54ff8ed..30dc465 100644
--- a/manual/Tasks/waitfor.html
+++ b/manual/Tasks/waitfor.html
@@ -37,7 +37,7 @@
 property of that name will be created if the condition didn't come
 true within the specified time.</p>
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -94,8 +94,8 @@
     <td valign="top" align="center">No</td>
   </tr>
 </table>
-<h3><a name="nested">Nested Elements</a></h3>
 
+<h3 id="nested">Nested Elements</h3>
 <p>The available conditions that satisfy the
 <code>&lt;waitfor&gt;</code> task are the same as those for the
 <a href="condition.html"><code>&lt;condition&gt;</code></a> task. See
@@ -127,7 +127,5 @@
   on port 1521 and for the http://webserver/mypage.html web page
   to become available.</p>
 
-
 </body>
 </html>
-
diff --git a/manual/Tasks/war.html b/manual/Tasks/war.html
index 2c92006..50b3c14 100644
--- a/manual/Tasks/war.html
+++ b/manual/Tasks/war.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="war">War</a></h2>
+<h2 id="war">War</h2>
 <h3>Description</h3>
 <p>An extension of the <a href="jar.html">Jar</a> task with special
 treatment for files that should end up in the
@@ -46,7 +46,7 @@
     it is not optional by default. The task will fail if the file is not
     included, unless the <code>needxmlfile</code> attribute
     is set to <code>false</code>. The task
-    will warn if more than one web.xml file is added to the JAR  
+    will warn if more than one web.xml file is added to the JAR
     through the filesets.
 </p>
 
@@ -58,7 +58,7 @@
 to a value other than its default, <code>&quot;add&quot;</code>.</b></p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -67,7 +67,7 @@
   <tr>
     <td valign="top">destfile</td>
     <td valign="top">the WAR file to create.</td>
-    <td align="center" valign="top" rowspan="2">Exactly one of the two.</td>
+    <td align="center" valign="top" rowspan="2">Exactly one of the two</td>
   </tr>
   <tr>
     <td valign="top">warfile</td>
@@ -87,7 +87,7 @@
         It should be set to false when generating
         servlet 2.5+ WAR files without a web.xml file.
         <em>Since Apache Ant 1.7</em></td>
-    <td valign="top" align="center">No -default "true"</td>
+    <td valign="top" align="center">No - default "true"</td>
   </tr>
   <tr>
     <td valign="top">basedir</td>
@@ -107,7 +107,7 @@
     <td valign="top">For entries coming from existing archives (like
     nested <em>zipfileset</em>s or while updating the archive), keep
     the compression as it has been originally instead of using the
-    <em>compress</em> attribute.  Defaults false.  <em>Since Ant
+    <em>compress</em> attribute.  Defaults to false.  <em>Since Ant
     1.6</em></td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -180,7 +180,7 @@
   </tr>
   <tr>
     <td valign="top">duplicate</td>
-    <td valign="top">behavior when a duplicate file is found.  Valid values are &quot;add&quot;, &quot;preserve&quot;, and &quot;fail&quot;.  The default value is &quot;add&quot;.  </td>
+    <td valign="top">behavior when a duplicate file is found.  Valid values are &quot;add&quot;, &quot;preserve&quot;, and &quot;fail&quot;.  The default value is &quot;add&quot;.</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -212,7 +212,7 @@
     that the permissions haven't been stored at all rather than real
     permissions and will instead apply its own default values.<br/>
     Set this attribute to true if you really want to preserve the
-      original permission field.<em>since Ant 1.8.0</em>
+      original permission field. <em>since Ant 1.8.0</em>
     </td>
     <td valign="top" align="center">No, default is false</td>
   </tr>
@@ -358,7 +358,5 @@
 Menu "Options" -> "Configuration",  "View" property/tab page, then "General" group box has an option called "Allow all uppercase file names".
 </p>
 
-
-
 </body>
 </html>
diff --git a/manual/Tasks/whichresource.html b/manual/Tasks/whichresource.html
index 5b2b54e..72eb2ee 100644
--- a/manual/Tasks/whichresource.html
+++ b/manual/Tasks/whichresource.html
@@ -14,19 +14,16 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-    
+
 <html>
   <head>
     <meta http-equiv="Content-Language" content="en-us">
-      <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
-        <title>Whichresource Task</title>
-      </link>
-    </meta>
+    <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+    <title>Whichresource Task</title>
   </head>
 
-
   <body>
-    <h2><a name="whichresource">Whichresource</a></h2>
+    <h2 id="whichresource">Whichresource</h2>
     <h3>Description</h3>
     <p>
       Find a class or resource on the supplied classpath, or the
@@ -38,7 +35,7 @@
   &lt;whichresource resource="/log4j.properties" property="log4j.url" &gt;
 </pre></blockquote>
     <h3>Parameters</h3>
-    <table border="1" cellpadding="2" cellspacing="0">
+    <table>
       <tr>
         <td valign="top"><b>Attribute</b></td>
         <td valign="top"><b>Description</b></td>
@@ -56,7 +53,7 @@
         <td valign="top">
           The name of the class to look for.
         </td>
-        <td valign="top" align="center" rowspan="2">Exactly one of these.</td>
+        <td valign="top" align="center" rowspan="2">Exactly one of these</td>
       </tr>
       <tr>
         <td valign="top">resource</td>
@@ -78,7 +75,7 @@
           The classpath to use, given as a
           <a href="../using.html#references">reference</a>
           to a path defined elsewhere.
-          <em>Since Apache Ant 1.7.1.</em>
+          <em>Since Apache Ant 1.7.1</em>.
         </td>
         <td align="center" valign="top">No</td>
       </tr>
@@ -116,5 +113,5 @@
   &lt;/whichresource&gt;
   &lt;echo&gt;${ant-contrib.antlib.location}&lt;/echo&gt;
 </pre></blockquote>
-  </body>
+</body>
 </html>
diff --git a/manual/Tasks/wljspc.html b/manual/Tasks/wljspc.html
index 5663494..5918012 100644
--- a/manual/Tasks/wljspc.html
+++ b/manual/Tasks/wljspc.html
@@ -15,15 +15,17 @@
    limitations under the License.
 -->
 <html>
-<head><link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
-<title>WLJSPC Task</title></head>
+  <head>
+    <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+    <title>WLJSPC Task</title>
+  </head>
 <body>
 <h1>wljspc</h1>
 <h3>Description</h3>
 <p>Class to precompile JSP's using weblogic's jsp compiler (weblogic.jspc)</p>
 Tested only on Weblogic 4.5.1 - NT4.0 and Solaris 5.7,5.8<br>
 <h3>Parameters</h3>
-<table border="1" cellPadding="2" cellSpacing="0">
+<table>
   <tbody>
     <tr>
       <th>Attribute</th>
@@ -38,13 +40,13 @@
     <tr>
       <td>
 dest</td>
-      <td> root of destination directory, what you have set as WorkingDir in the weblogic properties</td>
+      <td>root of destination directory, what you have set as WorkingDir in the weblogic properties</td>
       <td>Yes</td>
     </tr>
     <tr>
       <td>
 package</td>
-      <td> start package name under which your JSP's would be compiled</td>
+      <td>start package name under which your JSP's would be compiled</td>
       <td>Yes</td>
     </tr>
     <tr>
@@ -67,13 +69,10 @@
 only those files that have changed.<br>
 <br>
 It follows the weblogic naming convention of putting classes in<br>
-<b> _dirName/_fileName.class for dirname/fileName.jsp   </b><br>
+<b>_dirName/_fileName.class for dirname/fileName.jsp</b><br>
 <br>
 </p>
-<h3><br>
-Example<br>
-</h3>
-<p>
+<h3>Example</h3>
 <pre>
 &lt;target name="jspcompile" depends="compile"&gt;
   &lt;wljspc src="c:\\weblogic\\myserver\\public_html" dest="c:\\weblogic\\myserver\\serverclasses" package="myapp.jsp"&gt
@@ -85,8 +84,6 @@
 &lt;/target&gt;
 </pre>
 
-</p>
-
 <h3>Limitations</h3>
 <ul>
 <li>This works only on weblogic 4.5.1</li>
diff --git a/manual/Tasks/xmlproperty.html b/manual/Tasks/xmlproperty.html
index 293cf24..dc86912 100644
--- a/manual/Tasks/xmlproperty.html
+++ b/manual/Tasks/xmlproperty.html
@@ -22,7 +22,7 @@
 
 <body>
 
-<h2><a name="xmlproperty">XmlProperty</a></h2>
+<h2 id="xmlproperty">XmlProperty</h2>
 <h3>Description</h3>
 <p>
 Loads property values from a well-formed xml file. There are no other restrictions
@@ -45,9 +45,7 @@
 <a href="property.html">Property task</a>, property references
 (i.e., <samp>${foo}</samp>) are not resolved.
 <p>
-<a name="semanticAttributes">
-<h3>Semantic Attributes</h3>
-</a>
+<h3 id="semanticAttributes">Semantic Attributes</h3>
 Input processing can be enabled by using the <b>semanticAttributes</b>
 attribute.  If this attribute is set to <i>true</i> (its default is
 <i>false</i>), the following processing occurs as the input XML file
@@ -75,6 +73,7 @@
 <p>
 For example, with semantic attribute processing enabled, this XML property
 file:
+</p>
 <pre>
   &lt;root&gt;
     &lt;properties&gt;
@@ -89,10 +88,8 @@
   &lt;property name="root.properties.quux" value="${root.properties.foo}"/&gt;
 </pre>
 
-</p>
-
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -144,16 +141,16 @@
     <td valign="top">rootDirectory</td>
     <td valign="top">The directory to use for resolving file references. Ignored
                      if <i>semanticAttributes</i> is not set to <i>true</i>.</td>
-    <td valign="top" align="center">No, default is <i>${basedir}</i>.</td>
+    <td valign="top" align="center">No, default is <code>${basedir}</code>.</td>
   </tr>
   <tr>
     <td valign="top">delimiter</td>
-    <td valign="top">Delimiter for splitting multiple values.<br><i>since Apache Ant 1.7.1</i></td>
+    <td valign="top">Delimiter for splitting multiple values.<br><em>since Apache Ant 1.7.1</em></td>
     <td valign="top" align="center">No, defaults to comma</td>
   </tr>
 </table>
 
-<h3><a name="nested">Nested Elements</a></h3>
+<h3 id="nested">Nested Elements</h3>
 <h4>xmlcatalog</h4>
 <p>The <a href="../Types/xmlcatalog.html"><tt>&lt;xmlcatalog&gt;</tt></a>
 element is used to perform entity resolution.</p>
@@ -163,9 +160,7 @@
 
 <p>The specified resource will be used as input.</p>
 
-<a name="examples">
-<h3>Examples</h3>
-</a>
+<h3 id="examples">Examples</h3>
 
 <h4>Non-semantic Attributes</h4>
 
@@ -283,7 +278,5 @@
   &lt;/path&gt;
 </pre>
 
-
-
 </body>
 </html>
diff --git a/manual/Tasks/xmlvalidate.html b/manual/Tasks/xmlvalidate.html
index c362bbe..5981f29 100644
--- a/manual/Tasks/xmlvalidate.html
+++ b/manual/Tasks/xmlvalidate.html
@@ -23,7 +23,7 @@
 
 <body>
 
-<h2><a name="xmlvalidate">XMLValidate</a></h2>
+<h2 id="xmlvalidate">XMLValidate</h2>
 <h3>Description</h3>
 
 <p>This task checks that XML files are valid (or only well formed). The
@@ -31,24 +31,26 @@
 (probably the one that is used by Apache Ant itself), but one can specify any
 SAX1/2 parser if needed.</p>
 
-<p>This task supports the use of nested
+<p>This task supports the use of nested</p>
+<ul>
   <li><a href="../Types/xmlcatalog.html"><tt>&lt;xmlcatalog&gt;</tt></a> elements</li>
   <li><tt>&lt;dtd&gt;</tt> elements which are used to resolve DTDs and entities</li>
   <li><tt>&lt;attribute&gt;</tt> elements which are used to set features on the parser.
       These can be any number of
       <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"><tt>http://xml.org/sax/features/</tt></a>
       or other features that your parser may support.</li>
-  <li><tt>&lt;property&gt;</tt> elements, containing string properties
-</p>
+  <li><tt>&lt;property&gt;</tt> elements, containing string properties</li>
+</ul>
 
-<p><b>Warning</b> : JAXP creates by default a non namespace aware parser.
+<p><b>Warning</b>: By default, JAXP creates a non namespace aware parser.
 The <tt>"http://xml.org/sax/features/namespaces"</tt> feature is set
-by default to <tt>false</tt> by the JAXP implementation used by ant. To validate
+by default to <tt>false</tt> by the JAXP implementation used by Ant. To validate
 a document containing namespaces,
-set the namespaces feature to <tt>true</tt> explicitly by nesting the following element:
+set the namespaces feature to <tt>true</tt> explicitly by nesting the following element:</p>
 <pre>
   &lt;attribute name="http://xml.org/sax/features/namespaces" value="true"/&gt;
 </pre>
+<p>
 If you are using for instance a <tt>xsi:noNamespaceSchemaLocation</tt> attribute in your XML files,
 you will need this namespace support feature.
 </p>
@@ -57,7 +59,7 @@
 
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -98,12 +100,12 @@
   </tr>
 </table>
 
-<h3><a name="nested">Nested Elements</a></h3>
+<h3 id="nested">Nested Elements</h3>
 <h4>dtd</h4>
 <p>
 <tt>&lt;dtd&gt;</tt> is used to specify different locations for DTD resolution.
 </p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -130,9 +132,9 @@
  <a href="http://xml.apache.org/xerces-j/features.html">Setting features</a><br>
 
 SAX features are defined here:
- <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"><tt>http://xml.org/sax/features/</tt></a><br>
+<a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"><tt>http://xml.org/sax/features/</tt></a><br>
  </p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -149,7 +151,6 @@
     <td align="center" valign="top">Yes</td>
   </tr>
 </table>
-</p>
 
 <h4>property</h4>
 <p>The <tt>&lt;property&gt;</tt> element is used to set properties.
@@ -157,7 +158,7 @@
  <a href="http://xml.apache.org/xerces-j/properties.html">XML Parser properties</a>
 Properties can be used to set the schema used to validate the XML file.
 </p>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
 <tr>
   <td width="12%" valign="top"><b>Attribute</b></td>
   <td width="78%" valign="top"><b>Description</b></td>
@@ -174,8 +175,6 @@
     <td align="center" valign="top">Yes</td>
   </tr>
 </table>
-</p>
-
 
 <h3>Examples</h3>
 <pre>
@@ -199,8 +198,8 @@
 &lt;/xmlvalidate&gt;
 </pre>
 
-Validate a struts configuration, using a local copy of the DTD. 
-<pre> 
+Validate a struts configuration, using a local copy of the DTD.
+<pre>
 &lt;xmlvalidate failonerror="no"&gt;
   &lt;fileset dir="${project.dir}" includes="**/*.xml"/&gt;
   &lt;xmlcatalog refid="mycatalog"/&gt;
@@ -253,11 +252,8 @@
   value="${xsd.file}"/&gt;
 &lt;/xmlvalidate&gt;
 </pre>
-<br>
+<p>
 Validate the file xml/endpiece-noSchema.xml against the schema xml/doc.xsd.
-<br>
-
-
+</p>
 </body>
 </html>
-
diff --git a/manual/Tasks/zip.html b/manual/Tasks/zip.html
index 4d66851..46e9557 100644
--- a/manual/Tasks/zip.html
+++ b/manual/Tasks/zip.html
@@ -24,7 +24,7 @@
 
 <body>
 
-<h2><a name="zip">Zip</a></h2>
+<h2 id="zip">Zip</h2>
 <h3>Description</h3>
 <p>Creates a zipfile.</p>
 <p>The <i>basedir</i> attribute is the reference directory from where to zip.</p>
@@ -37,7 +37,7 @@
 finally with the <i>defaultexcludes</i> attribute, you can specify whether you
 want to use default exclusions or not. See the section on <a
 href="../dirtasks.html#directorybasedtasks">directory based tasks</a>, on how the
-inclusion/exclusion of files works, and how to write patterns. </p>
+inclusion/exclusion of files works, and how to write patterns.</p>
 <p>This task forms an implicit <a href="../Types/fileset.html">FileSet</a> and
 supports most attributes of <code>&lt;fileset&gt;</code>
 (<code>dir</code> becomes <code>basedir</code>) as well as the nested
@@ -49,9 +49,9 @@
 (with <code>basedir</code> set, and optional attributes like <code>includes</code>
 and optional subelements like <code>&lt;include&gt;</code>); explicit nested
 <code>&lt;fileset&gt;</code> elements so long as at least one fileset total is specified. The ZIP file will
-only reflect the relative paths of files <i>within</i> each fileset. The Zip task and its derivatives know a special form of a fileset named zipfileset that has additional attributes (described below). </p>
-<p>The Zip task also supports the merging of multiple zip files into the zip file. 
-This is possible through either the <i>src</i> attribute of any nested filesets 
+only reflect the relative paths of files <i>within</i> each fileset. The Zip task and its derivatives know a special form of a fileset named zipfileset that has additional attributes (described below).</p>
+<p>The Zip task also supports the merging of multiple zip files into the zip file.
+This is possible through either the <i>src</i> attribute of any nested filesets
 or by using the special nested fileset <i>zipgroupfileset</i>.</p>
 
 <p>The <code>update</code> parameter controls what happens if the ZIP
@@ -77,7 +77,7 @@
 Java.  For a more complete discussion,
 see <a href="#encoding">below</a></p>
 
-<p>Starting with Ant 1.5.2, <code>&lt;zip&gt;</code> can store Unix permissions
+<p><em>Since Ant 1.5.2</em>, <code>&lt;zip&gt;</code> can store Unix permissions
 inside the archive (see description of the filemode and dirmode
 attributes for <a href="../Types/zipfileset.html">&lt;zipfileset&gt;</a>).
 Unfortunately there is no portable way to store these permissions.
@@ -108,7 +108,7 @@
 archive.</p>
 
 <h3>Parameters</h3>
-<table border="1" cellpadding="2" cellspacing="0">
+<table>
   <tr>
     <td valign="top"><b>Attribute</b></td>
     <td valign="top"><b>Description</b></td>
@@ -117,7 +117,7 @@
   <tr>
     <td valign="top">destfile</td>
     <td valign="top">the zip-file to create.</td>
-    <td align="center" valign="top" rowspan="2">Exactly one of the two.</td>
+    <td align="center" valign="top" rowspan="2">Exactly one of the two</td>
   </tr>
   <tr>
     <td valign="top">zipfile</td>
@@ -141,7 +141,7 @@
     <td valign="top">For entries coming from existing archives (like
     nested <em>zipfileset</em>s or while updating the archive), keep
     the compression as it has been originally instead of using the
-    <em>compress</em> attribute.  Defaults false.  <em>Since Ant
+    <em>compress</em> attribute.  Defaults to false.  <em>Since Ant
     1.6</em></td>
     <td align="center" valign="top">No</td>
   </tr>
@@ -202,7 +202,7 @@
   </tr>
   <tr>
     <td valign="top">duplicate</td>
-    <td valign="top">behavior when a duplicate file is found.  Valid values are &quot;add&quot;, &quot;preserve&quot;, and &quot;fail&quot;. The default value is &quot;add&quot;.  </td>
+    <td valign="top">behavior when a duplicate file is found.  Valid values are &quot;add&quot;, &quot;preserve&quot;, and &quot;fail&quot;. The default value is &quot;add&quot;.</td>
     <td valign="top" align="center">No</td>
   </tr>
   <tr>
@@ -210,7 +210,7 @@
     <td valign="top">Whether the file modification times will be
     rounded up to the next even number of seconds.<br>
     Zip archives store file modification times with a granularity of
-    two seconds, so the times will either be rounded up or down.  If
+    two seconds, so the times will either be rounded up or down. If
     you round down, the archive will always seem out-of-date when you
     rerun the task, so the default is to round up.  Rounding up may
     lead to a different type of problems like JSPs inside a web
@@ -239,17 +239,17 @@
     that the permissions haven't been stored at all rather than real
     permissions and will instead apply its own default values.<br/>
     Set this attribute to true if you really want to preserve the
-      original permission field.<em>since Ant 1.8.0</em>
+    original permission field. <em>Since Ant 1.8.0</em>
     </td>
     <td valign="top" align="center">No, default is false</td>
   </tr>
   <tr>
     <td valign="top">useLanguageEncodingFlag</td>
     <td valign="top">Whether to set the language encoding flag if the
-      encoding is UTF-8.  This setting doesn't have any effect if the
+      encoding is UTF-8. This setting doesn't have any effect if the
       encoding is not UTF-8.
-      <em>Since Ant 1.8.0</em>.
-      <br/>See also the <a href="#encoding">discussion below</a></td>
+      <em>Since Ant 1.8.0</em>.<br/>
+      See also the <a href="#encoding">discussion below</a></td>
     <td align="center" valign="top">No, default is true</td>
   </tr>
   <tr>
@@ -259,8 +259,8 @@
       <br>Possible values are "never", "always" and "not-encodeable"
       which will only add Unicode extra fields if the file name cannot
       be encoded using the specified encoding.
-      <em>Since Ant 1.8.0</em>.
-      <br/>See also the <a href="#encoding">discussion below</a></td>
+      <em>Since Ant 1.8.0</em>.<br/>
+      See also the <a href="#encoding">discussion below</a></td>
     <td align="center" valign="top">No, default is "never"</td>
   </tr>
   <tr>
@@ -268,21 +268,21 @@
     <td valign="top">Whether to use UTF-8 and the language encoding
       flag instead of the specified encoding if a file name cannot be
       encoded using the specified encoding.
-      <em>Since Ant 1.8.0</em>.
-      <br/>See also the <a href="#encoding">discussion below</a></td>
+      <em>Since Ant 1.8.0</em>.<br/>
+      See also the <a href="#encoding">discussion below</a></td>
     <td align="center" valign="top">No, default is false</td>
   </tr>
   <tr>
     <td valign="top">zip64Mode</td>
     <td valign="top">When to use Zip64 extensions for entries.  The
       possible values are "never", "always" and "as-needed".
-      <em>Since Ant 1.9.1</em>.
-      <br/>See also the <a href="#zip64">discussion below</a></td>
+      <em>Since Ant 1.9.1</em>.<br/>
+      See also the <a href="#zip64">discussion below</a></td>
     <td align="center" valign="top">No, default is "as-needed"</td>
   </tr>
 </table>
 
-<h3><a name="encoding">Encoding of File Names</a></h3>
+<h3 id="encoding">Encoding of File Names</h3>
 
 <p>Traditionally the ZIP archive format uses CodePage 437 as encoding
   for file name, which is not sufficient for many international
@@ -294,30 +294,30 @@
 
 <p>Ant has been offering the encoding attribute of the zip and unzip
   task as a way to explicitly specify the encoding to use (or expect)
-  since Ant 1.4.  It defaults to the platform's default encoding for
+  <em>since Ant 1.4</em>.  It defaults to the platform's default encoding for
   zip and UTF-8 for jar and other jar-like tasks (war, ear, ...) as
   well as the unzip family of tasks.</p>
 
 <p>More recent versions of the ZIP specification introduce something
   called the &quot;language encoding flag&quot; which can be used to
-  signal that a file name has been encoded using UTF-8.  Starting with
-  Ant 1.8.0 all zip-/jar- and similar archives written by Ant will set
+  signal that a file name has been encoded using UTF-8. <em>Since
+  Ant 1.8.0</em>, all zip, jar and similar archives written by Ant will set
   this flag, if the encoding has been set to UTF-8.  Our
-  interoperabilty tests with existing archivers didn't show any ill
+  interoperability tests with existing archivers didn't show any ill
   effects (in fact, most archivers ignore the flag to date), but you
   can turn off the "language encoding flag" by setting the attribute
   <code>useLanguageEncodingFlag</code> to <code>false</code> on the
   zip-task if you should encounter problems.</p>
 
-<p>The unzip (and similar tasks) -task will recognize the language
+<p>The unzip task (and similar tasks) will recognize the language
   encoding flag and ignore the encoding set on the task if it has been
   found.</p>
 
 <p>The InfoZIP developers have introduced new ZIP extra fields that
   can be used to add an additional UTF-8 encoded file name to the
-  entry's metadata.  Most archivers ignore these extra fields.  The
-  zip family of tasks support an
-  option <code>createUnicodeExtraFields</code> since Ant 1.8.0 which
+  entry's metadata.  Most archivers ignore these extra fields.
+  <em>Since Ant 1.8.0</em>, the zip family of tasks support an
+  option <code>createUnicodeExtraFields</code>, which
   makes Ant write these extra fields either for all entries ("always")
   or only those whose name cannot be encoded using the specified
   encoding (not-encodeable), it defaults to "never" since the extra
@@ -337,7 +337,7 @@
 
 <p>The optimal setting of flags depends on the archivers you expect as
   consumers/producers of the ZIP archives.  Below are some test
-  results which may be superseeded with later versions of each
+  results which may be superseded with later versions of each
   tool.</p>
 
 <ul>
@@ -345,7 +345,7 @@
     jars from your CLASSPATH reads and writes UTF-8 names, it doesn't
     set or recognize any flags or unicode extra fields.</li>
 
-  <li>Starting with Java7 <code>java.util.zip</code> writes UTF-8 by
+  <li>Since Java 7, <code>java.util.zip</code> writes UTF-8 by
     default and uses the language encoding flag.  It is possible to
     specify a different encoding when reading/writing ZIPs via new
     constructors.  The package now recognizes the language encoding
@@ -381,7 +381,7 @@
 <p>If you are creating jars, then java.util.zip is your main
   consumer.  We recommend you set the encoding to UTF-8 and keep the
   language encoding flag enabled.  The flag won't help or hurt
-  java.util.zip prior to Java7 but archivers that support it will show
+  java.util.zip prior to Java 7 but archivers that support it will show
   the correct file names.</p>
 
 <p>For maximum interop it is probably best to set the encoding to
@@ -398,7 +398,7 @@
   so the tools that support them will extract the file names
   correctly.</p>
 
-<h3><a name="zip64">Zip64 extensions</a></h3>
+<h3 id="zip64">Zip64 extensions</h3>
 
 <p>Zip64 extensions provide a way to create archives bigger than 4GB
   or holding more than 65535 entries - or add individual entries
@@ -411,16 +411,16 @@
   will be written has to be made before writing the entry's
   content.</p>
 
-<p>Starting with Ant 1.9.0 Ant supports Zip64 extensions but didn't
-  provide any control over their usage, starting with Ant 1.9.1 a
+<p>Ant 1.9.0 introduced support for Zip64 extensions but didn't
+  provide any control over their usage. <em>Since Ant 1.9.1</em>, a
   new <em>zip64mode</em> attribute was added to the <code>zip</code>
   family of tasks.  It supports three values:
 
 <ul>
   <li><em>never</em> means no Zip64 extra fields will ever be
-    written, this is the behavior of Ant 1.8.x and earlier and the
+    written. This is the behavior of Ant prior to 1.9.0 and the
     default behavior of <code>jar</code>, <code>ear</code>
-    and <code>war</code> starting with Ant 1.9.1.</li>
+    and <code>war</code> <em>since Ant 1.9.1</em>.</li>
   <li><em>always</em> means Zip64 extra fields are written for all
     entries.</li>
   <li><em>as-needed</em> means Zip64 extra fields are written for all
@@ -438,9 +438,9 @@
   understand Zip64 extra fields or fail to parse archives with extra
   fields in local file headers that are not present in the central
   directory, one such implementation is the java.util.zip package of
-  Java5, that's why the <code>jar</code> tasks default
+  Java 5, that's why the <code>jar</code> tasks default
   to <em>never</em>.  Archives created with <em>as-needed</em> can be
-  read without problems with Java6 and later.</p>
+  read without problems with Java 6 and later.</p>
 
 <h3>Parameters specified as nested elements</h3>
 
@@ -450,41 +450,36 @@
 <p>Prior to Ant 1.7 only <code>&lt;fileset&gt;</code> and
 <code>&lt;zipfileset&gt;</code> have been supported as nested elements.</p>
 
-<a name="zipgroupfileset" />
-<h4>zipgroupfileset</h4>
-<p>A <code>&lt;zipgroupfileset&gt;</code> allows for multiple zip files to be 
-merged into the archive. Each file found in this fileset is added to the archive 
+<h4 id="zipgroupfileset">zipgroupfileset</h4>
+<p>A <code>&lt;zipgroupfileset&gt;</code> allows for multiple zip files to be
+merged into the archive. Each file found in this fileset is added to the archive
 the same way that <i>zipfileset src</i> files are added.</p>
 
 <p><code>&lt;zipgroupfileset&gt;</code> is
   a <a href="../Types/fileset.html">fileset</a> and supports all
-  of its attributes and nested elements.</a>
+  of its attributes and nested elements.</p>
 
 <h3>Examples</h3>
 <pre>  &lt;zip destfile=&quot;${dist}/manual.zip&quot;
-       basedir=&quot;htdocs/manual&quot;
-  /&gt;</pre>
+       basedir=&quot;htdocs/manual&quot;/&gt;</pre>
 <p>zips all files in the <code>htdocs/manual</code> directory into a file called <code>manual.zip</code>
 in the <code>${dist}</code> directory.</p>
 <pre>  &lt;zip destfile=&quot;${dist}/manual.zip&quot;
        basedir=&quot;htdocs/manual&quot;
-       update=&quot;true&quot;
-  /&gt;</pre>
+       update=&quot;true&quot;/&gt;</pre>
 <p>zips all files in the <code>htdocs/manual</code> directory into a file called <code>manual.zip</code>
 in the <code>${dist}</code> directory. If <code>manual.zip</code>
 doesn't exist, it is created; otherwise it is updated with the
 new/changed files.</p>
 <pre>  &lt;zip destfile=&quot;${dist}/manual.zip&quot;
        basedir=&quot;htdocs/manual&quot;
-       excludes=&quot;mydocs/**, **/todo.html&quot;
-  /&gt;</pre>
+       excludes=&quot;mydocs/**, **/todo.html&quot;/&gt;</pre>
 <p>zips all files in the <code>htdocs/manual</code> directory. Files in the directory <code>mydocs</code>,
 or files with the name <code>todo.html</code> are excluded.</p>
 <pre>  &lt;zip destfile=&quot;${dist}/manual.zip&quot;
        basedir=&quot;htdocs/manual&quot;
        includes=&quot;api/**/*.html&quot;
-       excludes=&quot;**/todo.html&quot;
-  /&gt;</pre>
+       excludes=&quot;**/todo.html&quot;/&gt;</pre>
 <p>zips all files in the <code>htdocs/manual</code> directory. Only html files under the directory <code>api</code>
 are zipped, and files with the name <code>todo.html</code> are excluded.</p>
 <pre>  &lt;zip destfile=&quot;${dist}/manual.zip&quot;&gt;
@@ -501,7 +496,7 @@
   &lt;/zip&gt;</pre>
 <p>zips all files in the <code>htdocs/manual</code> directory into the <code>docs/user-guide</code> directory
 in the archive, adds the file <code>ChangeLog27.txt</code> in the
-current directory as <code>docs/ChangeLog.txt</code>, and includes all the html files in <code>examples.zip</code> 
+current directory as <code>docs/ChangeLog.txt</code>, and includes all the html files in <code>examples.zip</code>
 under <code>docs/examples</code>.  The archive might end up containing the files:</p>
 <pre>    docs/user-guide/html/index.html
     docs/ChangeLog.txt
@@ -544,8 +539,5 @@
 permissions have been stored as part of the TAR file, they will be
 retained in the resulting ZIP archive.</p>
 
-
-
 </body>
 </html>
-
diff --git a/manual/Types/filterchain.html b/manual/Types/filterchain.html
index c83b106..8f4066f 100644
--- a/manual/Types/filterchain.html
+++ b/manual/Types/filterchain.html
@@ -423,7 +423,7 @@
   <tr>
     <td vAlign=top>regexp</td>
     <td vAlign=top align="center">Regular expression to be searched for.<br>
-      <em>Starting with 1.9.10 this also works as an attribute
+      <em>Starting with 1.10.2 this also works as an attribute
         on <code>linecontainsregexp</code>, in earlier versions of Ant
         you must use a nested element when using the convenience
         method.</em>
@@ -1571,6 +1571,11 @@
     <td vAlign=top align="center">No</td>
   </tr>
   <tr>
+    <td valign="top">encoding</td>
+    <td valign="top">The encoding of the script as a file. <em>since Ant 1.10.2.</em></td>
+    <td valign="top" align="center">No - defaults to default JVM encoding</td>
+  </tr>
+  <tr>
     <td valign="top">setbeans</td>
     <td valign="top">whether to have all properties, references and targets as
       global variables in the script.  <em>since Ant 1.8.0</em></td>
diff --git a/manual/Types/mapper.html b/manual/Types/mapper.html
index da3181c..b557360 100644
--- a/manual/Types/mapper.html
+++ b/manual/Types/mapper.html
@@ -806,6 +806,11 @@
       <td align="center" valign="top">No</td>
     </tr>
     <tr>
+      <td valign="top">encoding</td>
+      <td valign="top">The encoding of the script as a file. <em>since Ant 1.10.2.</em></td>
+      <td valign="top" align="center">No - defaults to default JVM encoding</td>
+    </tr>
+    <tr>
       <td valign="top">setbeans</td>
       <td valign="top">whether to have all properties, references and targets as
         global variables in the script.  <em>since Ant 1.8.0</em></td>
diff --git a/manual/Types/resources.html b/manual/Types/resources.html
index 8ba77aa..b90ee23 100644
--- a/manual/Types/resources.html
+++ b/manual/Types/resources.html
@@ -49,6 +49,7 @@
   <li><a href="#string">string</a> - a text string.</li>
   <li><a href="#tarentry">tarentry</a> - an entry in a tar file.</li>
   <li><a href="#url">url</a> - a URL.</li>
+  <li><a href="#xzresource">xzresource</a> - an XZ compressed resource.</li>
   <li><a href="#zipentry">zipentry</a> - an entry in a zip file.</li>
 </ul>
 
@@ -277,6 +278,18 @@
 A single element resource collection must be specified as a nested
 element.</p>
 
+<h4><a name="xzresource">xzresource</a></h4>
+
+<p>This is not a stand-alone resource, but a wrapper around another
+resource providing compression of the resource's contents on the fly.
+A single element resource collection must be specified as a nested
+element.</p>
+
+<p>XZ compression support has been added with Apache Ant 1.10.1 and
+depends on external libraries not included in the Ant distribution.
+See <a href="../install.html#librarydependencies">Library
+Dependencies</a> for more information.</p>
+
 <h4><a name="url">url</a></h4>
 
 <p>Represents a URL.</p>
diff --git a/manual/Types/selectors.html b/manual/Types/selectors.html
index 402c711..db2ec48 100644
--- a/manual/Types/selectors.html
+++ b/manual/Types/selectors.html
@@ -92,6 +92,12 @@
         Select files if they are readable.</li>
       <li><a href="#writable"><code>&lt;writable&gt;</code></a> -
         Select files if they are writable.</li>
+      <li><a href="#executable"><code>&lt;executable&gt;</code></a> -
+        Select files if they are executable.</li>
+      <li><a href="#symlink"><code>&lt;symlink&gt;</code></a> -
+        Select files if they are symlink.</li>
+      <li><a href="#ownedBy"><code>&lt;ownedBy&gt;</code></a> -
+        Select files if they are owned by a given user.</li>
     </ul>
 
     <h4><a name="containsselect">Contains Selector</a></h4>
@@ -1018,6 +1024,49 @@
         but the Java VM cannot detect this state, this selector will
         still select the file.</p>
 
+      <h4><a name="executable">Executable Selector</a></h4>
+
+      <p>The <code>&lt;executable&gt;</code> selector selects only files
+        that are executable.  Ant only invokes
+        <code>java.nio.file.Files#isExecutable</code> so if a file is not executable
+        but the Java VM cannot detect this state, this selector will
+        still select the file.</p>
+
+      <p><em>Since Ant 1.10.0</em></p>
+
+      <h4><a name="symlink">Symlink Selector</a></h4>
+
+      <p>The <code>&lt;symlink&gt;</code> selector selects only files
+        that are symbolic links.  Ant only invokes
+        <code>java.nio.file.Files#isSymbolicLink</code> so if a file
+        is a symbolic link but the Java VM cannot detect this state,
+        this selector will not select the file.</p>
+
+      <p><em>Since Ant 1.10.0</em></p>
+
+      <h4><a name="ownedBy">OwnedBy Selector</a></h4>
+
+      <p>The <code>&lt;ownedBy&gt;</code> selector selects only files
+        that are owned by the given user.  Ant only invokes
+        <code>java.nio.file.Files#getOwner</code> so if a file system
+        doesn't support the operation this selector will not select
+        the file.</p>
+
+      <p><em>Since Ant 1.10.0</em></p>
+
+      <table border="1" cellpadding="2" cellspacing="0">
+        <tr>
+          <td valign="top"><b>Attribute</b></td>
+          <td valign="top"><b>Description</b></td>
+          <td align="center" valign="top"><b>Required</b></td>
+        </tr>
+        <tr>
+          <td valign="top">owner</td>
+          <td valign="top">Username of the expected owner</td>
+          <td valign="top" align="center">yes</td>
+        </tr>
+      </table>
+
       <h4><a name="scriptselector">Script Selector</a></h4>
 
       <p>
@@ -1059,6 +1108,11 @@
           <td valign="top" align="center">no</td>
         </tr>
         <tr>
+          <td valign="top">encoding</td>
+          <td valign="top">The encoding of the script as a file. <em>since Ant 1.10.2.</em></td>
+          <td valign="top" align="center">No - defaults to default JVM encoding</td>
+        </tr>
+        <tr>
           <td valign="top">setbeans</td>
           <td valign="top">whether to have all properties, references and targets as
             global variables in the script.</td>
diff --git a/manual/cover.html b/manual/cover.html
index 15ae811..e4912d9 100644
--- a/manual/cover.html
+++ b/manual/cover.html
@@ -19,14 +19,14 @@
 <head>
 <meta http-equiv="Content-Language" content="en-us">
 <link rel="stylesheet" type="text/css" href="stylesheets/style.css">
-<title>Apache Ant 1.9.10 User Manual</title>
+<title>Apache Ant 1.10.2 User Manual</title>
 </head>
 
 <body bgcolor="#FFFFFF">
 <div align="center"> 
   <h1><img src="images/ant_logo_large.gif" width="190" height="120"></h1>
-  <h1>Apache Ant&trade; 1.9.10 Manual</h1>
-  <p align="left">This is the manual for version 1.9.10 of
+  <h1>Apache Ant&trade; 1.10.2 Manual</h1>
+  <p align="left">This is the manual for version 1.10.2 of
   <a target="_top" href="http://ant.apache.org/index.html">Apache Ant</a>. 
     If your version 
     of Ant (as verified with <tt>ant -version</tt>) is older or newer than this 
diff --git a/manual/credits.html b/manual/credits.html
index 85e92b6..f6cd947 100644
--- a/manual/credits.html
+++ b/manual/credits.html
@@ -62,7 +62,7 @@
 </ul>
 
 <center>
-<p>Version: 1.9.10</p>
+<p>Version: 1.10.2</p>
 </center>
 
 
diff --git a/manual/install.html b/manual/install.html
index 7bcab8c..7a382d8 100644
--- a/manual/install.html
+++ b/manual/install.html
@@ -226,7 +226,7 @@
 work best. As of Ant 1.7, Windows 9x is no longer supported.
 </p>
 <p>
-For the current version of Ant (1.9), you will also need a JDK installed on your system, version 1.5 or later required.
+For the current version of Ant (1.10), you will also need a JDK installed on your system, version 8 or later required.
 The more up-to-date the version of Java, the more Ant tasks you get.
 </p>
 <p>
@@ -234,7 +234,7 @@
 </p>
 <p>
   <strong>Note:</strong>
-    Ant 1.8.* works with JDK 1.4 and higher, Ant 1.7.* works with JDK 1.3 and higher,
+    Ant 1.9.* works with JDK 1.5, Ant 1.8.* works with JDK 1.4 and higher, Ant 1.7.* works with JDK 1.3 and higher,
     Ant 1.6.* works with JDK 1.2 and higher, Ant 1.2 to Ant 1.5.* work with JDK 1.1 and higher.
 </p>
 
@@ -962,10 +962,16 @@
     <td><a href="https://download.java.net/media/jai/builds/release/1_1_3/INSTALL.html"
     target="_top">https://download.java.net/media/jai/builds/release/1_1_3/INSTALL.html</a></td>
   </tr>
+  <tr>
+    <td>XZ - XZ for Java <b>1.6 or later</b></td>
+    <td><a href="Tasks/pack.html">xz</a> and <a href="Tasks/unpack.html">unxz</a>
+    tasks, <a href="Types/resources.html#xzresource">xzresource</a>, xz compression
+    in <a href="Tasks/tar.html">tar</a>/<a href="Tasks/unzip.html">untar</a> tasks</td>
+    <td><a href="https://www.tukaani.org/xz/java.html" target="_top">https://www.tukaani.org/xz/java.html</a></td>
+  </tr>
 </table>
 
-<li>Which optional tasks are available. If a task is not listed as being available, either it is not present, or
-libraries that it depends on are absent.</li>
+<h2 id="Troubleshooting">Troubleshooting</h2>
 
 <h3 id="diagnostics">Diagnostics</h3>
 
@@ -982,7 +988,8 @@
 
 <li>Which JAR files are in <code>ANT_HOME/lib</code></li>
 
-<h2 id="Troubleshooting">Troubleshooting</h2>
+<li>Which optional tasks are available. If a task is not listed as being available, either it is not present, or
+libraries that it depends on are absent.</li>
 
 <li>XML Parser information</li>
 
diff --git a/manual/running.html b/manual/running.html
index 3bfb500..dac2ef3 100644
--- a/manual/running.html
+++ b/manual/running.html
@@ -490,6 +490,10 @@
   <td>number, seconds since the epoch (midnight 1970-01-01)</td>
   <td>The value to use as current time and date for &lt;tstamp&gt;</td>
 </tr>
+<tr>
+  <td><code>ant.tstamp.now.iso</code></td>
+  <td>ISO-8601 timestamp string like <code>1972-04-17T08:07:00Z</code></td>
+</tr>
 </table>
 
 <p>
diff --git a/manual/stylesheets/style.css b/manual/stylesheets/style.css
index cf26c60..f1e8f84 100644
--- a/manual/stylesheets/style.css
+++ b/manual/stylesheets/style.css
@@ -17,50 +17,70 @@
  */
 h2 {
   font-size: 200%;
-  background-color: ffffff;
+  background-color: white;
 }
 
 h3 {
   font-size: 130%;
-  color:     #ffffff;
+  color: white;
   background-color: #525D76;
 }
 
 h4 {
-  color:  #ffffff;
+  color: white;
   background-color: #828DA6;
 }
 
+h5 {
+  font-size: 100%;
+  color: white;
+  background-color: #a6adbe;
+  margin-top: .5rem;
+  margin-bottom: .5rem;
+}
+
+h6 {
+  font-size: 100%;
+  color: white;
+  background-color: #c1c5d1;
+  margin-top: .5rem;
+  margin-bottom: .5rem;
+}
+
+h5 + p, h6 + p {
+  margin-top: .5rem;
+  margin-bottom: .5rem;
+}
+
 td {
-   background-color: eeeeee;
-   color:            000000;
+   background-color: #eeeeee;
+   color: black;
 }
 
 /* first row */
 table tr:first-child td {
-   background-color: cccccc;
-   color:            000000;
+   background-color: silver;
+   color: black;
 }
 
 /* or th as first row */
 table th {
-   background-color: cccccc;
-   color:            000000;
+   background-color: silver;
+   color: black;
 }
 
 pre {
-   background-color: efefef;
+   background-color: #efefef;
 }
 
 /* code snippets in examples and tutorials */
 .code { 
    background: #EFEFEF; 
-   margin-top: 
 }
 
 /* highlight console output */
 .output { 
-   color: #FFFFFF; 
+   color: white;
    background: #837A67; 
 }
 
diff --git a/manual/tasklist.html b/manual/tasklist.html
index 6578e55..f0b7b01 100644
--- a/manual/tasklist.html
+++ b/manual/tasklist.html
@@ -40,7 +40,6 @@
 <li><a href="Tasks/antstructure.html">AntStructure</a></li>
 <li><a href="Tasks/antversion.html">AntVersion</a></li>
 <li><a href="Tasks/apply.html">Apply/<i>ExecOn</i></a></li>
-<li><a href="Tasks/apt.html">Apt</a></li>
 <li><a href="Tasks/attrib.html">Attrib</a></li>
 <li><a href="Tasks/augment.html">Augment</a></li>
 <li><a href="Tasks/available.html">Available</a></li>
@@ -110,7 +109,7 @@
 <li><a href="Tasks/jjdoc.html">JJDoc</a></li>
 <li><a href="Tasks/jjtree.html">JJTree</a></li>
 <li><a href="Tasks/jlink.html"><i>Jlink</i></a></li>
-<li><a href="Tasks/jspc.html">JspC</a></li>
+<li><a href="Tasks/jspc.html"><i>JspC</i></a></li>
 <li><a href="Tasks/junit.html">JUnit</a></li>
 <li><a href="Tasks/junitreport.html">JUnitReport</a></li>
 <li><a href="Tasks/length.html">Length</a><br/></li>
@@ -148,6 +147,7 @@
 <li><a href="Tasks/rexec.html">RExec</a></li>
 <li><a href="Tasks/rmic.html">Rmic</a></li>
 <li><a href="Tasks/rpm.html">Rpm</a></li>
+<li><a href="Tasks/setpermissions.html">SetPermissions</a></li>
 <li><a href="Tasks/schemavalidate.html">SchemaValidate</a></li>
 <li><a href="Tasks/scp.html">Scp</a></li>
 <li><a href="Tasks/script.html">Script</a></li>
@@ -178,6 +178,7 @@
 <li><a href="Tasks/unzip.html">Unjar</a></li>
 <li><a href="Tasks/unzip.html">Untar</a></li>
 <li><a href="Tasks/unzip.html">Unwar</a></li>
+<li><a href="Tasks/unpack.html">UnXZ</a></li>
 <li><a href="Tasks/unzip.html">Unzip</a></li>
 <li><a href="Tasks/uptodate.html">Uptodate</a></li>
 <li><a href="Tasks/verifyjar.html">VerifyJar</a></li>
@@ -188,6 +189,7 @@
 <li><a href="Tasks/wljspc.html">Weblogic JSP Compiler</a></li>
 <li><a href="Tasks/xmlproperty.html">XmlProperty</a></li>
 <li><a href="Tasks/xmlvalidate.html">XmlValidate</a></li>
+<li><a href="Tasks/pack.html">XZ</a></li>
 <li><a href="Tasks/style.html">XSLT/<i>Style</i></a></li>
 <li><a href="Tasks/zip.html">Zip</a></li>
 </ul>
diff --git a/manual/tasksoverview.html b/manual/tasksoverview.html
index 99aa11b..776082c 100644
--- a/manual/tasksoverview.html
+++ b/manual/tasksoverview.html
@@ -67,13 +67,13 @@
   </tr>
 
   <tr valign="top">
-    <td nowrap><a href="Tasks/unpack.html">BUnzip2</a></td>
-    <td><p>Expands a file packed using GZip or BZip2.</p></td>
+    <td nowrap><a href="Tasks/unpack.html">GUnzip/BUnzip2/UnXZ</a></td>
+    <td><p>Expands a file packed using GZip, BZip2 or XZ.</p></td>
   </tr>
 
   <tr valign="top">
-    <td nowrap><a href="Tasks/pack.html">BZip2</a></td>
-    <td><p>Packs a file using the GZip or BZip2 algorithm. This task
+    <td nowrap><a href="Tasks/pack.html">GZip/BZip2/XZ</a></td>
+    <td><p>Packs a file using the GZip, BZip2 or XZ algorithm. This task
      does not do any dependency checking; the output file is always
      generated</p></td>
   </tr>
@@ -232,12 +232,6 @@
   </tr>
 
   <tr valign="top">
-    <td nowrap><a href="Tasks/apt.html">Apt</a></td>
-    <td><p>Runs the annotation processor tool (apt), and then optionally compiles
-   the original code, and any generated source code.</p></td>
-  </tr>
-
-  <tr valign="top">
     <td nowrap><a href="Tasks/jspc.html">JspC</a></td>
     <td><p>Runs the JSP compiler. It can be used to precompile JSP pages
      for fast initial invocation of JSP pages, deployment on a server without
@@ -582,6 +576,11 @@
   </tr>
 
   <tr valign="top">
+    <td nowrap><a href="Tasks/setpermissions.html">SetPermissions</a></td>
+    <td><p>Changes the permissions of a collection of resources.</p></td>
+  </tr>
+
+  <tr valign="top">
     <td nowrap><a href="Tasks/sync.html">Sync</a></td>
     <td><p>Synchronize two directory trees.</p></td>
   </tr>
diff --git a/release/build-osx-pkg.py b/release/build-osx-pkg.py
deleted file mode 100755
index 4144a03..0000000
--- a/release/build-osx-pkg.py
+++ /dev/null
@@ -1,179 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-# Builds a Mac OS X .pkg from a binary ZIP archive of Apache Ant.
-
-import collections
-import contextlib
-import os
-
-ApacheAntURL = collections.namedtuple(
-    'ApacheAntURL',
-    ('url', 'url_scheme', 'version', 'directory_name'))
-
-@contextlib.contextmanager
-def make_temp_directory():
-    '''Creates a temporary directory which is recursively deleted when out of scope.'''
-    import shutil
-    import tempfile
-    temp_dir = tempfile.mkdtemp()
-    yield temp_dir
-    shutil.rmtree(temp_dir)
-
-@contextlib.contextmanager
-def self_closing_url(url):
-    '''Opens a URL and returns a self-closing file-like object.'''
-    import urllib2
-    url_fp = urllib2.urlopen(url)
-    yield url_fp
-    url_fp.close()
-
-def apache_ant_url(url_string):
-    '''Parses a URL string into an ApacheAntURL object.'''
-    import argparse, collections, os.path, urlparse
-    parse_result = urlparse.urlparse(url_string)
-    filename = os.path.split(parse_result.path)[1]
-    if not (filename.startswith('apache-ant-') and filename.endswith('-bin.zip')):
-        raise argparse.ArgumentTypeError(
-            'Expected [%s] to end with apache-ant-X.Y.Z-bin.zip' % (url_string))
-    extracted_directory = filename.replace('-bin.zip', '')
-    extracted_version = extracted_directory.replace('apache-ant-', '')
-    return ApacheAntURL(
-        url=url_string,
-        url_scheme=parse_result.scheme,
-        version=extracted_version,
-        directory_name=extracted_directory)
-
-def fetch_url(url, local_output_file):
-    '''Downloads the contents of 'url' and writes them the opened file 'output_file'.'''
-    import shutil
-    import urllib2
-    CHUNK_SIZE = 16 * 1024
-    print 'Fetching {url}...'.format(url=url)
-    with self_closing_url(url) as url_input_file:
-        while True:
-            chunk = url_input_file.read(CHUNK_SIZE)
-            if not chunk:
-                break
-            local_output_file.write(chunk)
-        local_output_file.seek(0)
-
-def fetch_apache_ant_url(apache_ant_url, temp_dir):
-    '''If the ApacheAntURL object is remote, fetches and returns the local file object.
-    Otherwise, opens and returns a file object.'''
-    import tempfile
-    if apache_ant_url.url_scheme == '' or apache_ant_url.url_scheme == 'file':
-        return open(apache_ant_url.url, 'rb')
-    else:
-        fp = tempfile.TemporaryFile(dir=temp_dir)
-        fetch_url(apache_ant_url.url, fp)
-        return fp
-
-def uncompress_contents(temp_dir, archive_file, directory_name, path_prefix):
-    '''Uncompresses the contents of 'archive_file' to 'temp_dir'.
-
-    Strips the prefix 'directory_name' and prepends 'path_prefix' to each entry
-    of the zip file.
-    '''
-    import shutil, zipfile
-    output_path = os.path.join(temp_dir, 'pkg')
-    os.mkdir(output_path)
-    z = zipfile.ZipFile(archive_file)
-    print 'Extracting archive to {output_path}...'.format(
-        output_path=output_path)
-    for entry in z.infolist():
-        # We can't just extract directly, since we want to map:
-        #
-        # apache-ant-X.Y.Z/bin/foo
-        #
-        # to
-        #
-        # usr/local/ant/bin/foo
-        #
-        # So, we strip out the apache-ant-X.Y.Z prefix, then instead of
-        # using ZipFile.extract(), we use ZipFile.open() to get a read fd to
-        # the source file, then os.fdopen() with the appropriate permissions
-        # to geta write fd to the modified destination path.
-        expected_prefix = directory_name + '/'
-        if not entry.filename.startswith(expected_prefix):
-            raise Exeption('Unexpected entry in zip file: [{filename}]'.format(
-                    filename=entry.filename))
-        entry_path = entry.filename.replace(expected_prefix, '', 1)
-
-        # Using os.path.join is annoying here (we'd have to explode output_path
-        # and entry_path).
-        entry_output_path = output_path + path_prefix + '/' + entry_path
-
-        # Zip file paths are normalized with '/' at the end for directories.
-        if entry_output_path.endswith('/'):
-            print 'Creating directory {path}'.format(path=entry_output_path)
-            os.makedirs(entry_output_path)
-        else:
-            # Yes, this is really how you extract permissions from a ZipInfo entry.
-            perms = (entry.external_attr >> 16L) & 0777
-            print 'Extracting {entry_filename} to {path} with mode 0{mode:o}'.format(
-                entry_filename=entry.filename, path=entry_output_path, mode=perms)
-            with z.open(entry) as source:
-                with os.fdopen(
-                    os.open(entry_output_path, os.O_WRONLY | os.O_CREAT, perms), 'w') \
-                    as destination:
-                    shutil.copyfileobj(source, destination)
-    return output_path
-
-def write_paths_d_entry(paths_d_directory, filename):
-    os.makedirs(paths_d_directory)
-    output_file = os.path.join(paths_d_directory, filename)
-    with open(output_file, 'w') as f:
-        print >>f, '/usr/local/ant/bin'
-
-def make_pkg(pkg_dir, pkg_identifier, pkg_version, output_pkg_path):
-    import subprocess
-    print 'Building package at {output_pkg_path}...'.format(
-        output_pkg_path=output_pkg_path)
-    subprocess.call(
-        ['pkgbuild',
-         '--root', pkg_dir,
-         '--identifier', pkg_identifier,
-         '--version', pkg_version,
-         output_pkg_path])
-
-def main():
-    import argparse
-    parser = argparse.ArgumentParser(description='Builds a Mac OS X .pkg of ant.')
-    parser.add_argument(
-        'apache_ant_url',
-        metavar='file-or-url',
-        help='Source file or URL from which to uncompress apache-ant-X.Y.Z-bin.zip',
-        type=apache_ant_url)
-    parser.add_argument(
-        '--output-dir',
-        default='.',
-        help='Directory to which .pkg will be written. Defaults to current directory.')
-    args = parser.parse_args()
-    with make_temp_directory() as temp_dir:
-        archive_file = fetch_apache_ant_url(args.apache_ant_url, temp_dir)
-        pkg_dir = uncompress_contents(
-            temp_dir, archive_file, args.apache_ant_url.directory_name, '/usr/local/ant')
-        etc_paths_d_dir = os.path.join(pkg_dir, 'etc', 'paths.d')
-        write_paths_d_entry(etc_paths_d_dir, 'org.apache.ant')
-        pkg_identifier = 'org.apache.ant'
-        output_pkg_path = os.path.join(
-            args.output_dir, args.apache_ant_url.directory_name + '.pkg')
-        make_pkg(pkg_dir, pkg_identifier, args.apache_ant_url.version, output_pkg_path)
-
-if __name__ == '__main__':
-    main()
diff --git a/release/ivy.xml b/release/ivy.xml
index 2efe770..ac8c9d7 100644
--- a/release/ivy.xml
+++ b/release/ivy.xml
@@ -19,7 +19,7 @@
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
   <info organisation="org/apache"
-        module="ant" revision="1.9.10"/>
+        module="ant" revision="1.10.2"/>
   <publications xmlns:e="urn:ant.apache.org:ivy-extras">
     <artifact name="ant-parent" type="pom" ext="pom"/>
     <artifact name="ant-parent" type="pom.asc" ext="pom.asc"/>
@@ -157,6 +157,12 @@
     <artifact name="ant-testutil" type="jar.asc" ext="jar.asc"/>
     <artifact name="ant-testutil" type="source" ext="jar" e:classifier="sources"/>
     <artifact name="ant-testutil" type="source.asc" ext="jar.asc" e:classifier="sources"/>
+    <artifact name="ant-xz" type="pom" ext="pom"/>
+    <artifact name="ant-xz" type="pom.asc" ext="pom.asc"/>
+    <artifact name="ant-xz" type="jar" ext="jar"/>
+    <artifact name="ant-xz" type="jar.asc" ext="jar.asc"/>
+    <artifact name="ant-xz" type="source" ext="jar" e:classifier="sources"/>
+    <artifact name="ant-xz" type="source.asc" ext="jar.asc" e:classifier="sources"/>
   </publications>
-  <dependencies/> 
+  <dependencies/>
 </ivy-module>
diff --git a/sonar-project.properties b/sonar-project.properties
new file mode 100644
index 0000000..482880b
--- /dev/null
+++ b/sonar-project.properties
@@ -0,0 +1,6 @@
+sonar.projectKey=ant-master
+sonar.projectName=Apache Ant
+sonar.sources=src/main
+sonar.tests=src/tests/junit
+sonar.projectVersion=1.10.0-SNAPSHOT
+sonar.java.source=8
diff --git a/sonarqube.xml b/sonarqube.xml
new file mode 100644
index 0000000..4fae4f7
--- /dev/null
+++ b/sonarqube.xml
@@ -0,0 +1,26 @@
+<project default="sonar" basedir=".">
+
+  <!-- gets overridden by the jenkins job -->
+  <property name="sonar.host.url" value="http://localhost:9000" />
+
+  <!-- source SonarQube project properties -->
+  <property file="sonar-project.properties"/>
+
+  <property name="downloads" location="build/downloads"/>
+  <property name="sonarqube-ant-task-jar" location="${downloads}/sonarqube-ant-task.jar"/>
+  <property name="sonarqube-ant-task-url"
+            value="https://sonarsource.bintray.com/Distribution/sonarqube-ant-task/sonarqube-ant-task-2.5.jar"/>
+
+  <target name="download">
+    <mkdir dir="${downloads}"/>
+    <get dest="${sonarqube-ant-task-jar}" src="${sonarqube-ant-task-url}"/>
+  </target>
+
+  <target name="sonar" depends="download">
+    <taskdef uri="antlib:org.sonar.ant" resource="org/sonar/ant/antlib.xml">
+        <classpath path="${sonarqube-ant-task-jar}" />
+    </taskdef>
+
+    <sonar:sonar xmlns:sonar="antlib:org.sonar.ant"/>
+  </target>
+</project>
diff --git a/src/etc/poms/ant-antlr/pom.xml b/src/etc/poms/ant-antlr/pom.xml
index 7eb2863..f0b960c 100644
--- a/src/etc/poms/ant-antlr/pom.xml
+++ b/src/etc/poms/ant-antlr/pom.xml
@@ -27,13 +27,13 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-antlr</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + ANTLR</name>
   <description>antlr specific task.
     The implementation forks a java process, therefore the antlr jar file is only needed at runtime</description>
@@ -41,7 +41,7 @@
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <optional>true</optional>
       <scope>compile</scope>
     </dependency>
diff --git a/src/etc/poms/ant-apache-bcel/pom.xml b/src/etc/poms/ant-apache-bcel/pom.xml
index c526eab..11e068a 100644
--- a/src/etc/poms/ant-apache-bcel/pom.xml
+++ b/src/etc/poms/ant-apache-bcel/pom.xml
@@ -27,25 +27,25 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-apache-bcel</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + BCEL</name>
   <dependencies>
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>bcel</groupId>
+      <groupId>org.apache.bcel</groupId>
       <artifactId>bcel</artifactId>
-      <version>5.1</version>
+      <version>6.2</version>
       <scope>compile</scope>
     </dependency>
   </dependencies>
diff --git a/src/etc/poms/ant-apache-bsf/pom.xml b/src/etc/poms/ant-apache-bsf/pom.xml
index 0975ce4..5fdea3f 100644
--- a/src/etc/poms/ant-apache-bsf/pom.xml
+++ b/src/etc/poms/ant-apache-bsf/pom.xml
@@ -27,19 +27,19 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-apache-bsf</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + BSF</name>
   <dependencies>
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
diff --git a/src/etc/poms/ant-apache-log4j/pom.xml b/src/etc/poms/ant-apache-log4j/pom.xml
index b9b558e..e85dd38 100644
--- a/src/etc/poms/ant-apache-log4j/pom.xml
+++ b/src/etc/poms/ant-apache-log4j/pom.xml
@@ -26,19 +26,19 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>  
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-apache-log4j</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + Log4J</name>
   <dependencies>
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
diff --git a/src/etc/poms/ant-apache-oro/pom.xml b/src/etc/poms/ant-apache-oro/pom.xml
index 00c80c0..86ef6eb 100644
--- a/src/etc/poms/ant-apache-oro/pom.xml
+++ b/src/etc/poms/ant-apache-oro/pom.xml
@@ -27,19 +27,19 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-apache-oro</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + Apache Oro</name>
   <dependencies>
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
diff --git a/src/etc/poms/ant-apache-regexp/pom.xml b/src/etc/poms/ant-apache-regexp/pom.xml
index e1d29dc..e521878 100644
--- a/src/etc/poms/ant-apache-regexp/pom.xml
+++ b/src/etc/poms/ant-apache-regexp/pom.xml
@@ -26,19 +26,19 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-apache-regexp</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + Apache Regexp</name>
   <dependencies>
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
diff --git a/src/etc/poms/ant-apache-resolver/pom.xml b/src/etc/poms/ant-apache-resolver/pom.xml
index 0e86d84..5509194 100644
--- a/src/etc/poms/ant-apache-resolver/pom.xml
+++ b/src/etc/poms/ant-apache-resolver/pom.xml
@@ -26,19 +26,19 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-apache-resolver</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + Apache Resolver</name>
   <dependencies>
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
@@ -55,7 +55,7 @@
         <artifactId>maven-compiler-plugin</artifactId>
         <configuration>
           <includes>
-            <include>org/apache/tools/ant/types/resolver/**</include>
+            <include>org/apache/tools/ant/types/resolver/*.java</include>
           </includes>
         </configuration>
       </plugin>
diff --git a/src/etc/poms/ant-apache-xalan2/pom.xml b/src/etc/poms/ant-apache-xalan2/pom.xml
index 3c0b1a3..f02b876 100644
--- a/src/etc/poms/ant-apache-xalan2/pom.xml
+++ b/src/etc/poms/ant-apache-xalan2/pom.xml
@@ -26,20 +26,20 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>  
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-apache-xalan2</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + Xalan 2</name>
   <description>contains Xalan2-specific features</description>
   <dependencies>
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
diff --git a/src/etc/poms/ant-commons-logging/pom.xml b/src/etc/poms/ant-commons-logging/pom.xml
index 1a94d3d..5dfbb80 100644
--- a/src/etc/poms/ant-commons-logging/pom.xml
+++ b/src/etc/poms/ant-commons-logging/pom.xml
@@ -26,20 +26,20 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-commons-logging</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + Commons Logging</name>
   <description>Ant Listener based on commons-logging</description>
   <dependencies>
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
diff --git a/src/etc/poms/ant-commons-net/pom.xml b/src/etc/poms/ant-commons-net/pom.xml
index fe4d318..b8f9470 100644
--- a/src/etc/poms/ant-commons-net/pom.xml
+++ b/src/etc/poms/ant-commons-net/pom.xml
@@ -26,26 +26,26 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-commons-net</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + Commons Net</name>
   <description>ftp, rexec and telnet tasks</description>
   <dependencies>
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>commons-net</groupId>
       <artifactId>commons-net</artifactId>
-      <version>2.2</version>
+      <version>3.6</version>
       <scope>compile</scope>
     </dependency>
   </dependencies>
diff --git a/src/etc/poms/ant-jai/pom.xml b/src/etc/poms/ant-jai/pom.xml
index a156dc3..239f672 100644
--- a/src/etc/poms/ant-jai/pom.xml
+++ b/src/etc/poms/ant-jai/pom.xml
@@ -27,13 +27,13 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-jai</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + JAI</name>
   <description>image task and corresponding types.
   </description>
@@ -41,7 +41,7 @@
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
diff --git a/src/etc/poms/ant-javamail/pom.xml b/src/etc/poms/ant-javamail/pom.xml
index d6a3259..d782bd1 100644
--- a/src/etc/poms/ant-javamail/pom.xml
+++ b/src/etc/poms/ant-javamail/pom.xml
@@ -26,13 +26,13 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>  
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-javamail</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + JavaMail</name>
   <description>implementation of the mail task based on javamail.
     Required to send emails to SMTP servers using user/password combinations
@@ -41,19 +41,13 @@
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>javax.mail</groupId>
       <artifactId>javax.mail-api</artifactId>
-      <version>1.5.6</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>javax.activation</groupId>
-      <artifactId>activation</artifactId>
-      <version>1.1.1</version>
+      <version>1.6.0</version>
       <scope>compile</scope>
     </dependency>
   </dependencies> 
diff --git a/src/etc/poms/ant-jdepend/pom.xml b/src/etc/poms/ant-jdepend/pom.xml
index 1e7fbda..47b03e5 100644
--- a/src/etc/poms/ant-jdepend/pom.xml
+++ b/src/etc/poms/ant-jdepend/pom.xml
@@ -27,13 +27,13 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>  
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-jdepend</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + JDepend</name>
   <description>task jdepend invoking the jdepend parser. There is also a version 2.9.1 of the
     jdepend parser available on the maven repository</description>
@@ -41,7 +41,7 @@
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
diff --git a/src/etc/poms/ant-jmf/pom.xml b/src/etc/poms/ant-jmf/pom.xml
index eec1dca..d5fcf43 100644
--- a/src/etc/poms/ant-jmf/pom.xml
+++ b/src/etc/poms/ant-jmf/pom.xml
@@ -26,13 +26,13 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>  
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-jmf</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + JMF</name>
   <description>contains the sound task and a soundplayer listener
     download the dependency from http://java.sun.com/products/java-media/jmf/</description>
@@ -40,7 +40,7 @@
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
   </dependencies>
diff --git a/src/etc/poms/ant-jsch/pom.xml b/src/etc/poms/ant-jsch/pom.xml
index cb697fd..b11658e 100644
--- a/src/etc/poms/ant-jsch/pom.xml
+++ b/src/etc/poms/ant-jsch/pom.xml
@@ -26,13 +26,13 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>  
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-jsch</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + JSch</name>
   <description>contains the sshexec and scp tasks
   </description>
@@ -40,7 +40,7 @@
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
diff --git a/src/etc/poms/ant-junit/pom.xml b/src/etc/poms/ant-junit/pom.xml
index d201d70..b424a48 100644
--- a/src/etc/poms/ant-junit/pom.xml
+++ b/src/etc/poms/ant-junit/pom.xml
@@ -26,20 +26,20 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>  
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-junit</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + JUnit</name>
   <description>contains the junit and junirreport tasks</description>
   <dependencies>
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
diff --git a/src/etc/poms/ant-junit4/pom.xml b/src/etc/poms/ant-junit4/pom.xml
index 0f1dbfe..a1105c2 100644
--- a/src/etc/poms/ant-junit4/pom.xml
+++ b/src/etc/poms/ant-junit4/pom.xml
@@ -26,20 +26,20 @@
         <groupId>org.apache.ant</groupId>
         <artifactId>ant-parent</artifactId>
         <relativePath>../pom.xml</relativePath>
-        <version>1.9.10-SNAPSHOT</version>
+        <version>1.10.2-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <url>http://ant.apache.org/</url>
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-junit4</artifactId>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
     <name>Apache Ant + JUnit 4</name>
     <description>contains JUnit 4.x support</description>
     <dependencies>
         <dependency>
             <groupId>org.apache.ant</groupId>
             <artifactId>ant</artifactId>
-            <version>1.9.10-SNAPSHOT</version>
+            <version>1.10.2-SNAPSHOT</version>
             <scope>compile</scope>
         </dependency>
         <dependency>
diff --git a/src/etc/poms/ant-launcher/pom.xml b/src/etc/poms/ant-launcher/pom.xml
index cb5886a..fcce5a6 100644
--- a/src/etc/poms/ant-launcher/pom.xml
+++ b/src/etc/poms/ant-launcher/pom.xml
@@ -27,13 +27,13 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-launcher</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant Launcher</name>
   <build>
     <plugins>
@@ -44,7 +44,6 @@
           <includes>
             <include>org/apache/tools/ant/launch/*.java</include>
           </includes>
-
         </configuration>
       </plugin>
     </plugins>
diff --git a/src/etc/poms/ant-netrexx/pom.xml b/src/etc/poms/ant-netrexx/pom.xml
index bc5b82d..3c71be0 100644
--- a/src/etc/poms/ant-netrexx/pom.xml
+++ b/src/etc/poms/ant-netrexx/pom.xml
@@ -26,13 +26,13 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>  
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-netrexx</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + NetRexx</name>
   <description>NetRexxC task
     dependency can be downloaded from http://www.ibm.com/software/awdtools/netrexx/download.html</description>
@@ -40,7 +40,7 @@
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <!-- Processed too early, before maven-antrun-plugin gets a chance to work:
diff --git a/src/etc/poms/ant-swing/pom.xml b/src/etc/poms/ant-swing/pom.xml
index 9202675..50c6160 100644
--- a/src/etc/poms/ant-swing/pom.xml
+++ b/src/etc/poms/ant-swing/pom.xml
@@ -27,20 +27,20 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>  
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-swing</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant + Swing</name>
   <description>a listener and a splash task based on Swing</description>
   <dependencies>
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
   </dependencies>
diff --git a/src/etc/poms/ant-testutil/pom.xml b/src/etc/poms/ant-testutil/pom.xml
index b089d03..43577a8 100644
--- a/src/etc/poms/ant-testutil/pom.xml
+++ b/src/etc/poms/ant-testutil/pom.xml
@@ -27,20 +27,20 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>  
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-testutil</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant Test Utilities</name>
   <description>test utility classes</description>
   <dependencies>
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
      <dependency>
diff --git a/src/etc/poms/ant-xz/pom.xml b/src/etc/poms/ant-xz/pom.xml
new file mode 100644
index 0000000..258ed90
--- /dev/null
+++ b/src/etc/poms/ant-xz/pom.xml
@@ -0,0 +1,71 @@
+<?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.
+-->
+<!--
+  This POM has been created manually by the Ant Development Team.
+  Please contact us if you are not satisfied with the data contained in this POM.
+  URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <groupId>org.apache.ant</groupId>
+    <artifactId>ant-parent</artifactId>
+    <relativePath>../pom.xml</relativePath>
+    <version>1.10.2-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <url>http://ant.apache.org/</url>
+  <groupId>org.apache.ant</groupId>
+  <artifactId>ant-xz</artifactId>
+  <version>1.10.2-SNAPSHOT</version>
+  <name>Apache Ant + XZ for Java</name>
+  <description>contains the xz compression support</description>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.ant</groupId>
+      <artifactId>ant</artifactId>
+      <version>1.10.2-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.tukaani</groupId>
+      <artifactId>xz</artifactId>
+      <version>1.6</version>
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <includes>
+            <include>org/apache/tools/ant/taskdefs/optional/xz/*</include>
+            <include>org/apache/tools/ant/types/optional/xz/*</include>
+          </includes>
+        </configuration>
+      </plugin>
+    </plugins>
+    <sourceDirectory>../../../../src/main</sourceDirectory>
+    <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+    <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+    <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+    <directory>../../../../target/${project.artifactId}</directory>
+  </build>
+</project>
diff --git a/src/etc/poms/ant/pom.xml b/src/etc/poms/ant/pom.xml
index cb0e9ad..0217915 100644
--- a/src/etc/poms/ant/pom.xml
+++ b/src/etc/poms/ant/pom.xml
@@ -27,19 +27,19 @@
     <groupId>org.apache.ant</groupId>
     <artifactId>ant-parent</artifactId>
     <relativePath>../pom.xml</relativePath>
-    <version>1.9.10-SNAPSHOT</version>
+    <version>1.10.2-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <url>http://ant.apache.org/</url>
   <groupId>org.apache.ant</groupId>
   <artifactId>ant</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <name>Apache Ant Core</name>
   <dependencies>
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant-launcher</artifactId>
-      <version>1.9.10-SNAPSHOT</version>
+      <version>1.10.2-SNAPSHOT</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
@@ -114,46 +114,48 @@
         <configuration>
           <excludes>
             <exclude>org/apache/tools/ant/filters/util/JavaClassHelper*</exclude>
-            <exclude>org/apache/tools/ant/types/resolver/**</exclude>
-            <exclude>org/apache/tools/ant/listener/Log4jListener*</exclude>
-            <exclude>org/apache/tools/ant/listener/CommonsLoggingListener*</exclude>
-            <exclude>org/apache/tools/ant/util/regexp/JakartaRegexp*</exclude>
-            <exclude>org/apache/tools/ant/util/regexp/JakartaOro*</exclude>
-            <exclude>org/apache/tools/ant/taskdefs/email/MimeMailer*</exclude>
+            <exclude>org/apache/tools/ant/filters/util/JavaClassHelper*</exclude>
             <exclude>org/apache/tools/ant/launch/**</exclude>
+            <exclude>org/apache/tools/ant/listener/CommonsLoggingListener*</exclude>
+            <exclude>org/apache/tools/ant/listener/Log4jListener*</exclude>
+            <exclude>org/apache/tools/ant/taskdefs/email/MimeMailer*</exclude>
+            <exclude>org/apache/tools/ant/taskdefs/optional/NetRexxC*</exclude>
+            <exclude>org/apache/tools/ant/taskdefs/optional/Script*</exclude>
+            <exclude>org/apache/tools/ant/taskdefs/optional/Xalan2TraceSupport*</exclude>
+            <exclude>org/apache/tools/ant/taskdefs/optional/image/*</exclude>
+            <exclude>org/apache/tools/ant/taskdefs/optional/jdepend/*</exclude>
+            <exclude>org/apache/tools/ant/taskdefs/optional/junit/*</exclude>
             <exclude>org/apache/tools/ant/taskdefs/optional/net/FTP*</exclude>
             <exclude>org/apache/tools/ant/taskdefs/optional/net/RExec*</exclude>
             <exclude>org/apache/tools/ant/taskdefs/optional/net/TelnetTask*</exclude>
-            <exclude>org/apache/tools/ant/taskdefs/optional/junit/*</exclude>
-            <exclude>org/apache/tools/ant/taskdefs/optional/ssh/*</exclude>
-            <exclude>org/apache/tools/ant/taskdefs/optional/image/*</exclude>
-            <exclude>org/apache/tools/ant/types/optional/image/*</exclude>
-            <exclude>org/apache/tools/ant/taskdefs/optional/Script*</exclude>
             <exclude>org/apache/tools/ant/taskdefs/optional/script/**</exclude>
+            <exclude>org/apache/tools/ant/taskdefs/optional/ssh/*</exclude>
+            <exclude>org/apache/tools/ant/taskdefs/optional/xz/*</exclude>
             <exclude>org/apache/tools/ant/types/optional/*Script*</exclude>
+            <exclude>org/apache/tools/ant/types/optional/image/*</exclude>
+            <exclude>org/apache/tools/ant/types/optional/xz/*</exclude>
+            <exclude>org/apache/tools/ant/types/resolver/**</exclude>
             <exclude>org/apache/tools/ant/util/ScriptRunner.java</exclude>
-            <exclude>org/apache/tools/ant/util/optional/ScriptRunner.java</exclude>
-            <exclude>org/apache/tools/ant/filters/util/JavaClassHelper*</exclude>
             <exclude>org/apache/tools/ant/util/depend/bcel/*</exclude>
-            <exclude>org/apache/tools/ant/taskdefs/optional/NetRexxC*</exclude>
-            <exclude>org/apache/tools/ant/taskdefs/optional/Xalan2TraceSupport*</exclude>
-            <exclude>org/apache/tools/ant/taskdefs/optional/jdepend/*</exclude>
+            <exclude>org/apache/tools/ant/util/optional/ScriptRunner.java</exclude>
+            <exclude>org/apache/tools/ant/util/regexp/JakartaOro*</exclude>
+            <exclude>org/apache/tools/ant/util/regexp/JakartaRegexp*</exclude>
           </excludes>
           <testExcludes>
             <exclude>org/apache/tools/ant/filters/util/JavaClassHelper*</exclude>
-            <exclude>org/apache/tools/ant/types/resolver/**</exclude>
-            <exclude>org/apache/tools/ant/util/Script*</exclude>
-            <exclude>org/apache/tools/ant/listener/Log4jListener*</exclude>
-            <exclude>org/apache/tools/ant/listener/CommonsLoggingListener*</exclude>
-            <exclude>org/apache/tools/ant/util/regexp/JakartaRegexp*</exclude>
-            <exclude>org/apache/tools/ant/util/regexp/JakartaOro*</exclude>
-            <exclude>org/apache/tools/ant/util/regexp/Jdk14Regexp*</exclude>
-            <exclude>org/apache/tools/ant/taskdefs/email/MimeMailer*</exclude>
             <exclude>org/apache/tools/ant/launch/**</exclude>
+            <exclude>org/apache/tools/ant/listener/CommonsLoggingListener*</exclude>
+            <exclude>org/apache/tools/ant/listener/Log4jListener*</exclude>
             <exclude>org/apache/tools/ant/taskdefs/StyleTest*</exclude>
+            <exclude>org/apache/tools/ant/taskdefs/email/MimeMailer*</exclude>
             <exclude>org/apache/tools/ant/taskdefs/optional/junit/</exclude>
             <exclude>org/apache/tools/ant/taskdefs/optional/net/FTP*</exclude>
             <exclude>org/apache/tools/ant/taskdefs/optional/ssh/*</exclude>
+            <exclude>org/apache/tools/ant/types/resolver/**</exclude>
+            <exclude>org/apache/tools/ant/util/Script*</exclude>
+            <exclude>org/apache/tools/ant/util/regexp/JakartaOro*</exclude>
+            <exclude>org/apache/tools/ant/util/regexp/JakartaRegexp*</exclude>
+            <exclude>org/apache/tools/ant/util/regexp/Jdk14Regexp*</exclude>
           </testExcludes>
         </configuration>
       </plugin>
diff --git a/src/etc/poms/pom.xml b/src/etc/poms/pom.xml
index 95aa29a..e3f4d84 100644
--- a/src/etc/poms/pom.xml
+++ b/src/etc/poms/pom.xml
@@ -26,7 +26,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.apache.ant</groupId>
   <artifactId>ant-parent</artifactId>
-  <version>1.9.10-SNAPSHOT</version>
+  <version>1.10.2-SNAPSHOT</version>
   <packaging>pom</packaging>
   <description>master POM</description>
   <licenses>
@@ -103,12 +103,13 @@
     <module>ant-netrexx</module>
     <module>ant-swing</module>
     <module>ant-testutil</module>
+    <module>ant-xz</module>
   </modules>
   <dependencies>
      <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>3.8.2</version>
+      <version>4.12</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
@@ -122,26 +123,26 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-compiler-plugin</artifactId>
-          <version>2.3.2</version>
+          <version>3.7.0</version>
           <configuration>
-            <source>1.5</source>
-            <target>1.5</target>
+            <source>1.8</source>
+            <target>1.8</target>
           </configuration>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-jar-plugin</artifactId>
-          <version>2.4</version>
+          <version>3.0.2</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-surefire-plugin</artifactId>
-          <version>2.12</version>
+          <version>2.20.1</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-surefire-report-plugin</artifactId>
-          <version>2.12</version>
+          <version>2.20.1</version>
         </plugin>
       </plugins>
     </pluginManagement>
diff --git a/src/etc/testcases/core/antclassloader.xml b/src/etc/testcases/core/antclassloader.xml
index cafc823..045428d 100644
--- a/src/etc/testcases/core/antclassloader.xml
+++ b/src/etc/testcases/core/antclassloader.xml
@@ -56,11 +56,7 @@
 package org.example;
 public class Foo {}
 ]]></echo>
-      <available property="jdk1.6+" classname="java.net.CookieStore"/>
-      <condition property="source" value="6">
-        <isset property="jdk1.6+"/>
-      </condition>
-      <property name="source" value="1.4"/>
+      <property name="source" value="8"/>
       <javac srcdir="${tmp.dir.nonascii}"
              destdir="${tmp.dir.nonascii}" source="${source}"/>
       <tempfile property="test.jar" destdir="${tmp.dir}" suffix="test" prefix=".jar" deleteonexit="true"/>
diff --git a/src/etc/testcases/taskdefs/conditions/antversion.xml b/src/etc/testcases/taskdefs/conditions/antversion.xml
index ae274c8..f4d2e7e 100644
--- a/src/etc/testcases/taskdefs/conditions/antversion.xml
+++ b/src/etc/testcases/taskdefs/conditions/antversion.xml
@@ -32,11 +32,10 @@
                 <fail>
                         <condition>
                                 <not>
-                                        <antversion exactly="1.9.10" />
+                                        <antversion exactly="1.10.2" />
                                 </not>
                         </condition>
-                        Should be exactly 1.9.10
-
+                        Should be exactly 1.10.2
                 </fail>
         </target>
 
@@ -45,10 +44,10 @@
                 <fail>
                         <condition>
                                 <not>
-                                        <antversion atleast="1.9.10" />
+                                        <antversion atleast="1.9.8" />
                                 </not>
                         </condition>
-                Should be at least 1.9.10
+                Should be at least 1.9.8
                 </fail>
         </target>
 
@@ -57,10 +56,10 @@
                 <fail>
                         <condition>
                                 <not>
-                                        <antversion exactly="1.9.10" />
+                                        <antversion exactly="1.9.8" />
                                 </not>
                         </condition>
-                  Should be exactly 1.9.10
+                  Should be exactly 1.9.8
                 </fail>
         </target>
 </project>
diff --git a/src/etc/testcases/taskdefs/expected/asf-logo.gif.xz b/src/etc/testcases/taskdefs/expected/asf-logo.gif.xz
new file mode 100644
index 0000000..139eea4
--- /dev/null
+++ b/src/etc/testcases/taskdefs/expected/asf-logo.gif.xz
Binary files differ
diff --git a/src/etc/testcases/taskdefs/get.xml b/src/etc/testcases/taskdefs/get.xml
index b74e92a..188febd 100644
--- a/src/etc/testcases/taskdefs/get.xml
+++ b/src/etc/testcases/taskdefs/get.xml
@@ -98,6 +98,34 @@
     </fail>
   </target>
 
+  <target name="testTwoHeadersAreAddedOK">
+    <get src="http://www.apache.org/" dest="get.tmp">
+      <header name="header1" value="header1Value"/>
+      <header name="header2" value="header2Value"/>
+    </get>
+  </target>
+
+  <target name="testEmptyHeadersAreNeverAdded">
+    <get src="http://www.apache.org/" dest="get.tmp">
+      <header name="" value="headerValue"/>
+      <header name="header2" value=""/>
+    </get>
+  </target>
+
+  <target name="testThatWhenMoreThanOneHeaderHaveSameNameOnlyLastOneIsAdded">
+    <get src="http://www.apache.org/" dest="get.tmp">
+      <header name="header1" value="headerValue1"/>
+      <header name="header1" value="headerValue2"/>
+      <header name="header1" value="headerValue3"/>
+    </get>
+  </target>
+
+  <target name="testHeaderSpaceTrimmed">
+    <get src="http://www.apache.org/" dest="get.tmp">
+      <header name="  header1     " value="  headerValue1  "/>
+    </get>
+  </target>
+
   <target name="cleanup">
     <delete>
       <fileset dir="${basedir}" includes="get.tmp" />
diff --git a/src/etc/testcases/taskdefs/optional/junit.xml b/src/etc/testcases/taskdefs/optional/junit.xml
index cc66e20..314ba87 100644
--- a/src/etc/testcases/taskdefs/optional/junit.xml
+++ b/src/etc/testcases/taskdefs/optional/junit.xml
@@ -339,11 +339,7 @@
       public void bad() {
       throw new RuntimeException("failed");}
       }</echo>
-    <available property="jdk1.6+" classname="java.net.CookieStore"/>
-    <condition property="source" value="6">
-      <isset property="jdk1.6+"/>
-    </condition>
-    <property name="source" value="5"/>
+    <property name="source" value="8"/>
     <javac srcdir="${tmp.dir}" destdir="${tmp.dir}" includes="T1.java,T2.java"
            source="${source}">
 
diff --git a/src/etc/testcases/taskdefs/optional/script.xml b/src/etc/testcases/taskdefs/optional/script.xml
index 841f70d..c098289 100644
--- a/src/etc/testcases/taskdefs/optional/script.xml
+++ b/src/etc/testcases/taskdefs/optional/script.xml
@@ -17,6 +17,10 @@
 -->
 <project name="testproject" default="def" basedir=".">
 
+  <import file="../../buildfiletest-base.xml"/>
+
+  <property name="root" location="../../../../.."/>
+
   <target name="def">
     <fail>This build-file is intended to be run from the test cases</fail>
   </target>
@@ -43,4 +47,22 @@
     ]]></script>
   </target>
 
+  <target name="useSrcAndEncoding">
+    <mkdir dir="${output}" />
+    <property name="useSrcAndEncoding.encoding" value="UTF-8"/>
+    <property name="useSrcAndEncoding.reader.encoding" value="${useSrcAndEncoding.encoding}"
+      description="Set a different encoding to raise a failure (ex. ISO-8859-1)" />
+    <property name="useSrcAndEncoding.file" location="${output}/script.useSrcAndEncoding.js"/>
+    <property name="useSrcAndEncoding.expectedProp" value="eacute [&#233;]" />
+
+    <echo file="${useSrcAndEncoding.file}" encoding="${useSrcAndEncoding.encoding}"
+      message="project.setNewProperty('useSrcAndEncoding.prop', '${useSrcAndEncoding.expectedProp}');"/>
+
+    <script language="javascript" src="${useSrcAndEncoding.file}" encoding="${useSrcAndEncoding.reader.encoding}"/>
+    <condition property="useSrcAndEncoding.testOK" >
+      <equals arg1="${useSrcAndEncoding.expectedProp}" arg2="${useSrcAndEncoding.prop}" />
+    </condition>
+    <fail message="expected &lt;${useSrcAndEncoding.expectedProp}&gt; but was &lt;${useSrcAndEncoding.prop}&gt;" unless="useSrcAndEncoding.testOK" />
+  </target>
+
 </project>
\ No newline at end of file
diff --git a/src/etc/testcases/taskdefs/optional/script/heavy-script.js b/src/etc/testcases/taskdefs/optional/script/heavy-script.js
new file mode 100644
index 0000000..77eab1c
--- /dev/null
+++ b/src/etc/testcases/taskdefs/optional/script/heavy-script.js
@@ -0,0 +1,85 @@
+/*
+ *  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.
+ *
+ */
+
+var functions = [
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },function (value) { return value; },
+];
+
+var v = 'a';
+for (var i in functions) {
+  v = functions[i](v);
+}
+
+var echo = project.createTask("echo");
+echo.setMessage("heavy-script done");
+echo.perform();
diff --git a/src/etc/testcases/taskdefs/optional/script/scriptdef.xml b/src/etc/testcases/taskdefs/optional/script/scriptdef.xml
index 0d051ea..3b54e3e 100644
--- a/src/etc/testcases/taskdefs/optional/script/scriptdef.xml
+++ b/src/etc/testcases/taskdefs/optional/script/scriptdef.xml
@@ -17,6 +17,10 @@
 -->
 <project name="testproject" default="def" basedir=".">
 
+  <import file="../../../buildfiletest-base.xml"/>
+
+  <property name="root" location="../../../../../.."/>
+
   <target name="def">
     <fail>This build-file is intended to be run from the test cases</fail>
   </target>
@@ -141,5 +145,85 @@
     </scripttest>
   </target>
 
+  <target name="useBeanshell">
+    <script language="beanshell"><![CDATA[
+       self.log("I'm here", org.apache.tools.ant.Project.MSG_INFO);
+    ]]></script>
+  </target>
+
+  <target name="useSrcAndEncoding">
+    <mkdir dir="${output}" />
+    <property name="useSrcAndEncoding.encoding" value="UTF-8"/>
+    <property name="useSrcAndEncoding.reader.encoding" value="${useSrcAndEncoding.encoding}"
+      description="Set a different encoding to raise a failure (ex. ISO-8859-1)" />
+    <property name="useSrcAndEncoding.file" location="${output}/script.useSrcAndEncoding.js"/>
+    <property name="useSrcAndEncoding.expectedProp" value="eacute [&#233;]" />
+
+    <echo file="${useSrcAndEncoding.file}" encoding="${useSrcAndEncoding.encoding}"
+      message="project.setNewProperty('useSrcAndEncoding.prop', '${useSrcAndEncoding.expectedProp}');"/>
+
+    <scriptdef name="useSrcAndEncoding" language="javascript" src="${useSrcAndEncoding.file}" encoding="${useSrcAndEncoding.reader.encoding}"/>
+    <useSrcAndEncoding/>
+
+    <condition property="useSrcAndEncoding.testOK" >
+      <equals arg1="${useSrcAndEncoding.expectedProp}" arg2="${useSrcAndEncoding.prop}" />
+    </condition>
+    <fail message="expected &lt;${useSrcAndEncoding.expectedProp}&gt; but was &lt;${useSrcAndEncoding.prop}&gt;" unless="useSrcAndEncoding.testOK" />
+  </target>
+
+  <target name="useCompiled">
+
+    <!-- Test with 'javax' manager, 'bsf' manager already compiles the script. -->
+    <scriptdef manager="javax" name="heavyscript" language="javascript" src="heavy-script.js" encoding="UTF-8" compiled="true" />
+
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+    <heavyscript />
+
+  </target>
+
+  <target name="useNotCompiled">
+
+    <scriptdef manager="javax" name="heavyscriptNotCompiled" language="javascript" src="heavy-script.js" encoding="UTF-8" compiled="false" />
+
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+    <heavyscriptNotCompiled />
+
+  </target>
 
 </project>
diff --git a/src/etc/testcases/taskdefs/optional/unix/symlink.xml b/src/etc/testcases/taskdefs/optional/unix/symlink.xml
index f039a62..134f29f 100644
--- a/src/etc/testcases/taskdefs/optional/unix/symlink.xml
+++ b/src/etc/testcases/taskdefs/optional/unix/symlink.xml
@@ -302,7 +302,7 @@
 
     <sleep seconds="${delay}"/>  <!-- make sure OS has time to do the execs -->
 
-    <symlink action="recreate">
+    <symlink action="recreate" overwrite="true">
       <fileset dir="${output}/symtest1" includes="**/recorded.links"/>
     </symlink>
 
@@ -350,5 +350,17 @@
       <delete file="${output}/file2"/>
   </target>
 
+  <target name="test-overwrite-link" depends="setUp">
+    <mkdir dir="${output}/test-overwrite"/>
+    <mkdir dir="${output}/test-overwrite/dir1"/>
+    <property name="test.overwrite.link.target.dir" location="${output}/test-overwrite/dir1"/>
+    <!-- Create a symlink to the dir, this should work fine -->
+    <symlink link="${output}/test-overwrite/symlinked1" resource="${test.overwrite.link.target.dir}"/>
+    <!-- Create a symlink at the previously created symlink path with overwrite = false.
+      This *shouldn't* create a new link (within the target resource). See https://bz.apache.org/bugzilla/show_bug.cgi?id=58683 -->
+    <symlink link="${output}/test-overwrite/symlinked1" resource="${test.overwrite.link.target.dir}"/>
+
+
+  </target>
 
 </project>
diff --git a/src/etc/testcases/taskdefs/rmic/rmic.xml b/src/etc/testcases/taskdefs/rmic/rmic.xml
index 4670f43..1ef900d 100644
--- a/src/etc/testcases/taskdefs/rmic/rmic.xml
+++ b/src/etc/testcases/taskdefs/rmic/rmic.xml
@@ -212,12 +212,6 @@
     </condition>
     <property name="rmic.compiler" value="sun"/>
     <available property="wlrmic.present" classname="weblogic.rmic"/>
-    <condition property="rmic6.present">
-      <and>
-        <isset property="rmic.present"/>
-        <available classname="java.util.ServiceLoader"/>
-      </and>
-    </condition>
   </target>
 
   <target name="testDefault" depends="init">
@@ -435,23 +429,6 @@
     <assertBaseCompiled/>
   </target>
 
-  <!--
-  This test stamps on the XML parser settings on java6, so it is disabled.
-  -->
-  <target name="testXnew" if="rmic.present" unless="rmic6.present" depends="init">
-    <base-rmic compiler="${rmic.compiler}">
-      <compilerarg value="-Xnew"/>
-    </base-rmic>
-    <assertBaseCompiled/>
-  </target>
-
-  <target name="testXnewDest" if="rmic.present" unless="rmic6.present" depends="init">
-    <dest-rmic compiler="${rmic.compiler}">
-      <compilerarg value="-Xnew"/>
-    </dest-rmic>
-    <assertBaseCompiledInDest/>
-  </target>
-
   <target name="testXnewForked" if="rmic.present" depends="init">
     <base-rmic compiler="forking">
       <compilerarg value="-Xnew"/>
diff --git a/src/etc/testcases/types/assertions.xml b/src/etc/testcases/types/assertions.xml
index dee7ce7..a849a0b 100644
--- a/src/etc/testcases/types/assertions.xml
+++ b/src/etc/testcases/types/assertions.xml
@@ -21,11 +21,7 @@
   <import file="../buildfiletest-base.xml"/>
 
   <target name="setUp">
-    <available property="jdk1.6+" classname="java.net.CookieStore"/>
-    <condition property="source" value="6">
-      <isset property="jdk1.6+"/>
-    </condition>
-    <property name="source" value="1.4"/>
+    <property name="source" value="8"/>
     <mkdir dir="${output}"/>
     <javac srcdir="${src.dir}"
            includes="*.java"
diff --git a/src/main/org/apache/tools/ant/AntClassLoader.java b/src/main/org/apache/tools/ant/AntClassLoader.java
index 9f22011..fcf923f 100644
--- a/src/main/org/apache/tools/ant/AntClassLoader.java
+++ b/src/main/org/apache/tools/ant/AntClassLoader.java
@@ -20,12 +20,12 @@
 import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Constructor;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.nio.file.Files;
 import java.security.CodeSource;
 import java.security.ProtectionDomain;
 import java.security.cert.Certificate;
@@ -74,6 +74,10 @@
 
     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
 
+    static {
+        registerAsParallelCapable();
+    }
+
     /**
      * An enumeration of all resources of a given name found within the
      * classpath of this class loader. This enumeration is used by the
@@ -174,7 +178,7 @@
      * The components of the classpath that the classloader searches
      * for classes.
      */
-    private final Vector<File> pathComponents  = new VectorSet<File>();
+    private final Vector<File> pathComponents  = new VectorSet<>();
 
     /**
      * The project to which this class loader belongs.
@@ -192,14 +196,14 @@
      * loader regardless of whether the parent class loader is being searched
      * first or not.
      */
-    private final Vector<String> systemPackages = new Vector<String>();
+    private final Vector<String> systemPackages = new Vector<>();
 
     /**
      * These are the package roots that are to be loaded by this class loader
      * regardless of whether the parent class loader is being searched first
      * or not.
      */
-    private final Vector<String> loaderPackages = new Vector<String>();
+    private final Vector<String> loaderPackages = new Vector<>();
 
     /**
      * Whether or not this classloader will ignore the base
@@ -217,7 +221,7 @@
     /**
      * A hashtable of zip files opened by the classloader (File to JarFile).
      */
-    private Hashtable<File, JarFile> jarFiles = new Hashtable<File, JarFile>();
+    private Hashtable<File, JarFile> jarFiles = new Hashtable<>();
 
     /** Static map of jar file/time to manifest class-path entries */
     private static Map<String, String> pathMap =
@@ -289,8 +293,8 @@
      *                    classloader should be consulted  before trying to
      *                    load the a class through this loader.
      */
-    public AntClassLoader(
-                          final ClassLoader parent, final Project project, final Path classpath, final boolean parentFirst) {
+    public AntClassLoader(final ClassLoader parent, final Project project,
+        final Path classpath, final boolean parentFirst) {
         this(project, classpath);
         if (parent != null) {
             setParent(parent);
@@ -311,7 +315,8 @@
      *                    classloader should be consulted before trying to
      *                    load the a class through this loader.
      */
-    public AntClassLoader(final Project project, final Path classpath, final boolean parentFirst) {
+    public AntClassLoader(final Project project, final Path classpath,
+        final boolean parentFirst) {
         this(null, project, classpath, parentFirst);
     }
 
@@ -493,19 +498,13 @@
                 + pathComponent.lastModified() + "-" + pathComponent.length();
         String classpath = pathMap.get(absPathPlusTimeAndLength);
         if (classpath == null) {
-            JarFile jarFile = null;
-            try {
-                jarFile = new JarFile(pathComponent);
+            try (JarFile jarFile = new JarFile(pathComponent)) {
                 final Manifest manifest = jarFile.getManifest();
                 if (manifest == null) {
                     return;
                 }
                 classpath = manifest.getMainAttributes()
                     .getValue(Attributes.Name.CLASS_PATH);
-            } finally {
-                if (jarFile != null) {
-                    jarFile.close();
-                }
             }
             if (classpath == null) {
                 classpath = "";
@@ -789,7 +788,7 @@
             if (jarFile == null && file.isDirectory()) {
                 final File resource = new File(file, resourceName);
                 if (resource.exists()) {
-                    return new FileInputStream(resource);
+                    return Files.newInputStream(resource.toPath());
                 }
             } else {
                 if (jarFile == null) {
@@ -1411,12 +1410,7 @@
      */
     public synchronized void cleanup() {
         for (final Enumeration<JarFile> e = jarFiles.elements(); e.hasMoreElements();) {
-            final JarFile jarFile = e.nextElement();
-            try {
-                jarFile.close();
-            } catch (final IOException ioe) {
-                // ignore
-            }
+            FileUtils.close(e.nextElement());
         }
         jarFiles = new Hashtable<File, JarFile>();
         if (project != null) {
@@ -1592,8 +1586,7 @@
     }
 
     private static boolean readFully(final File f, final byte[] b) throws IOException {
-        final FileInputStream fis = new FileInputStream(f);
-        try {
+        try (InputStream fis = Files.newInputStream(f.toPath())) {
             final int len = b.length;
             int count = 0, x = 0;
             while (count != len) {
@@ -1604,8 +1597,6 @@
                 count += x;
             }
             return count == len;
-        } finally {
-            fis.close();
         }
     }
 
diff --git a/src/main/org/apache/tools/ant/ArgumentProcessorRegistry.java b/src/main/org/apache/tools/ant/ArgumentProcessorRegistry.java
index ed3331f..c378cd5 100644
--- a/src/main/org/apache/tools/ant/ArgumentProcessorRegistry.java
+++ b/src/main/org/apache/tools/ant/ArgumentProcessorRegistry.java
@@ -21,6 +21,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.ArrayList;
@@ -151,7 +152,7 @@
         try {
             try {
                 isr = new InputStreamReader(is, "UTF-8");
-            } catch (java.io.UnsupportedEncodingException e) {
+            } catch (UnsupportedEncodingException e) {
                 isr = new InputStreamReader(is);
             }
             BufferedReader rd = new BufferedReader(isr);
diff --git a/src/main/org/apache/tools/ant/BuildException.java b/src/main/org/apache/tools/ant/BuildException.java
index 34c1605..442071f 100644
--- a/src/main/org/apache/tools/ant/BuildException.java
+++ b/src/main/org/apache/tools/ant/BuildException.java
@@ -38,13 +38,26 @@
      * Constructs an exception with the given descriptive message.
      *
      * @param message A description of or information about the exception.
-     *            Should not be <code>null</code>.
+     *            Should not be {@code null}.
      */
     public BuildException(String message) {
         super(message);
     }
 
     /**
+     * Constructs an exception with the given format pattern and arguments.
+     *
+     * @param pattern A description of or information about the exception.
+     *            Should not be {@code null}.
+     * @param formatArguments ditto
+     * @see String#format(String, Object...)
+     * @since Ant 1.10.2
+     */
+    public BuildException(String pattern, Object... formatArguments) {
+        super(String.format(pattern, formatArguments));
+    }
+
+    /**
      * Constructs an exception with the given message and exception as
      * a root cause.
      *
diff --git a/src/main/org/apache/tools/ant/ComponentHelper.java b/src/main/org/apache/tools/ant/ComponentHelper.java
index 31ab880..ab8ced9 100644
--- a/src/main/org/apache/tools/ant/ComponentHelper.java
+++ b/src/main/org/apache/tools/ant/ComponentHelper.java
@@ -59,31 +59,31 @@
  */
 public class ComponentHelper  {
     /** Map of component name to lists of restricted definitions */
-    private Map<String, List<AntTypeDefinition>> restrictedDefinitions = new HashMap<String, List<AntTypeDefinition>>();
+    private Map<String, List<AntTypeDefinition>> restrictedDefinitions = new HashMap<>();
 
     /** Map from component name to anttypedefinition */
-    private final Hashtable<String, AntTypeDefinition> antTypeTable = new Hashtable<String, AntTypeDefinition>();
+    private final Hashtable<String, AntTypeDefinition> antTypeTable = new Hashtable<>();
 
     /** Map of tasks generated from antTypeTable */
-    private final Hashtable<String, Class<?>> taskClassDefinitions = new Hashtable<String, Class<?>>();
+    private final Hashtable<String, Class<?>> taskClassDefinitions = new Hashtable<>();
 
     /** flag to rebuild taskClassDefinitions */
     private boolean rebuildTaskClassDefinitions = true;
 
     /** Map of types generated from antTypeTable */
-    private final Hashtable<String, Class<?>> typeClassDefinitions = new Hashtable<String, Class<?>>();
+    private final Hashtable<String, Class<?>> typeClassDefinitions = new Hashtable<>();
 
     /** flag to rebuild typeClassDefinitions */
     private boolean rebuildTypeClassDefinitions = true;
 
     /** Set of namespaces that have been checked for antlibs */
-    private final HashSet<String> checkedNamespaces = new HashSet<String>();
+    private final HashSet<String> checkedNamespaces = new HashSet<>();
 
     /**
      * Stack of antlib contexts used to resolve definitions while
      *   processing antlib
      */
-    private Stack<String> antLibStack = new Stack<String>();
+    private Stack<String> antLibStack = new Stack<>();
 
     /** current antlib uri */
     private String antLibCurrentUri = null;
@@ -189,7 +189,6 @@
      */
     public void setProject(Project project) {
         this.project = project;
-//        antTypeTable = new Hashtable<String, AntTypeDefinition>(project);
     }
 
     /**
@@ -205,13 +204,13 @@
      * @return A deep copy of the restrictedDefinition
      */
     private Map<String, List<AntTypeDefinition>> getRestrictedDefinition() {
-        final Map<String, List<AntTypeDefinition>> result = new HashMap<String, List<AntTypeDefinition>>();
+        final Map<String, List<AntTypeDefinition>> result = new HashMap<>();
         synchronized (restrictedDefinitions) {
             for (Map.Entry<String, List<AntTypeDefinition>> entry : restrictedDefinitions.entrySet()) {
                 List<AntTypeDefinition> entryVal = entry.getValue();
                 synchronized (entryVal) {
                     //copy the entryVal
-                    entryVal = new ArrayList<AntTypeDefinition> (entryVal);
+                    entryVal = new ArrayList<>(entryVal);
                 }
                 result.put(entry.getKey(), entryVal);
             }
@@ -750,7 +749,7 @@
      */
     public void exitAntLib() {
         antLibStack.pop();
-        antLibCurrentUri = (antLibStack.size() == 0) ? null : (String) antLibStack.peek();
+        antLibCurrentUri = (antLibStack.isEmpty()) ? null : (String) antLibStack.peek();
     }
 
     /**
@@ -759,9 +758,7 @@
     private void initTasks() {
         ClassLoader classLoader = getClassLoader(null);
         Properties props = getDefaultDefinitions(false);
-        Enumeration<?> e = props.propertyNames();
-        while (e.hasMoreElements()) {
-            String name = (String) e.nextElement();
+        for (String name : props.stringPropertyNames()) {
             String className = props.getProperty(name);
             AntTypeDefinition def = new AntTypeDefinition();
             def.setName(name);
@@ -902,7 +899,7 @@
             probablyIDE = true;
             antHomeLib = "ANT_HOME" + File.separatorChar + "lib";
         }
-        StringBuffer dirListingText = new StringBuffer();
+        StringBuilder dirListingText = new StringBuilder();
         final String tab = "        -";
         dirListingText.append(tab);
         dirListingText.append(antHomeLib);
@@ -1026,14 +1023,7 @@
                 + " declarations have taken place.");
         if (uri.length() > 0) {
             final List<AntTypeDefinition> matches = findTypeMatches(uri);
-            if (matches.size() > 0) {
-                out.println();
-                out.println("The definitions in the namespace " + uri + " are:");
-                for (AntTypeDefinition def : matches) {
-                    String local = ProjectHelper.extractNameFromComponentName(def.getName());
-                    out.println("    " + local);
-                }
-            } else {
+            if (matches.isEmpty()) {
                 out.println("No types or tasks have been defined in this namespace yet");
                 if (isAntlib) {
                     out.println();
@@ -1041,6 +1031,13 @@
                     out.println("Action: Check that the implementing library exists in one of:");
                     out.println(dirListing);
                 }
+            } else {
+                out.println();
+                out.println("The definitions in the namespace " + uri + " are:");
+                for (AntTypeDefinition def : matches) {
+                    String local = ProjectHelper.extractNameFromComponentName(def.getName());
+                    out.println("    " + local);
+                }
             }
         }
     }
diff --git a/src/main/org/apache/tools/ant/DefaultDefinitions.java b/src/main/org/apache/tools/ant/DefaultDefinitions.java
index 062018d..19b4424 100644
--- a/src/main/org/apache/tools/ant/DefaultDefinitions.java
+++ b/src/main/org/apache/tools/ant/DefaultDefinitions.java
@@ -66,7 +66,6 @@
 
     private void componentDef(String ns, String name, String classname) {
         AntTypeDefinition def = new AntTypeDefinition();
-        String n = ProjectHelper.genComponentName(ns, name);
         def.setName(ProjectHelper.genComponentName(ns, name));
         def.setClassName(classname);
         def.setClassLoader(getClass().getClassLoader());
diff --git a/src/main/org/apache/tools/ant/DefaultLogger.java b/src/main/org/apache/tools/ant/DefaultLogger.java
index e0cd651..8390a64 100644
--- a/src/main/org/apache/tools/ant/DefaultLogger.java
+++ b/src/main/org/apache/tools/ant/DefaultLogger.java
@@ -24,9 +24,10 @@
 import java.io.StringReader;
 import java.text.DateFormat;
 import java.util.Date;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.util.DateUtils;
-import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.StringUtils;
 
 /**
@@ -257,48 +258,30 @@
         // Filter out messages based on priority
         if (priority <= msgOutputLevel) {
 
-            StringBuffer message = new StringBuffer();
-            if (event.getTask() != null && !emacsMode) {
+            StringBuilder message = new StringBuilder();
+            if (event.getTask() == null || emacsMode) {
+                //emacs mode or there is no task
+                message.append(event.getMessage());
+            } else {
                 // Print out the name of the task if we're in one
                 String name = event.getTask().getTaskName();
                 String label = "[" + name + "] ";
                 int size = LEFT_COLUMN_SIZE - label.length();
-                StringBuffer tmp = new StringBuffer();
-                for (int i = 0; i < size; i++) {
-                    tmp.append(" ");
-                }
-                tmp.append(label);
-                label = tmp.toString();
+                final String prefix = size > 0 ? Stream.generate(() -> " ")
+                    .limit(size).collect(Collectors.joining()) + label : label;
 
-                BufferedReader r = null;
-                try {
-                    r = new BufferedReader(
-                            new StringReader(event.getMessage()));
-                    String line = r.readLine();
-                    boolean first = true;
-                    do {
-                        if (first) {
-                            if (line == null) {
-                                message.append(label);
-                                break;
-                            }
-                        } else {
-                            message.append(StringUtils.LINE_SEP);
-                        }
-                        first = false;
-                        message.append(label).append(line);
-                        line = r.readLine();
-                    } while (line != null);
+                try (BufferedReader r =
+                    new BufferedReader(new StringReader(event.getMessage()))) {
+
+                    message.append(r.lines().map(line -> prefix + line)
+                        .collect(Collectors.joining(StringUtils.LINE_SEP)));
+                    if (message.length() == 0) {
+                        message.append(prefix);
+                    }
                 } catch (IOException e) {
                     // shouldn't be possible
                     message.append(label).append(event.getMessage());
-                } finally {
-                    FileUtils.close(r);
                 }
-
-            } else {
-                //emacs mode or there is no task
-                message.append(event.getMessage());
             }
             Throwable ex = event.getException();
             if (Project.MSG_DEBUG <= msgOutputLevel && ex != null) {
@@ -361,8 +344,7 @@
     protected String getTimestamp() {
         Date date = new Date(System.currentTimeMillis());
         DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
-        String finishTime = formatter.format(date);
-        return finishTime;
+        return formatter.format(date);
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/DemuxInputStream.java b/src/main/org/apache/tools/ant/DemuxInputStream.java
index ea263ca..e8c2164 100644
--- a/src/main/org/apache/tools/ant/DemuxInputStream.java
+++ b/src/main/org/apache/tools/ant/DemuxInputStream.java
@@ -50,6 +50,7 @@
      * @return the next byte
      * @throws IOException on error
      */
+    @Override
     public int read() throws IOException {
         byte[] buffer = new byte[1];
         if (project.demuxInput(buffer, 0, 1) == -1) {
@@ -67,6 +68,7 @@
      * @return the number of bytes read
      * @throws IOException on error
      */
+    @Override
     public int read(byte[] buffer, int offset, int length) throws IOException {
         return project.demuxInput(buffer, offset, length);
     }
diff --git a/src/main/org/apache/tools/ant/DemuxOutputStream.java b/src/main/org/apache/tools/ant/DemuxOutputStream.java
index 9645ca7..0686826 100644
--- a/src/main/org/apache/tools/ant/DemuxOutputStream.java
+++ b/src/main/org/apache/tools/ant/DemuxOutputStream.java
@@ -64,7 +64,7 @@
     private static final int LF = 0x0a;
 
     /** Mapping from thread to buffer (Thread to BufferInfo). */
-    private WeakHashMap<Thread, BufferInfo> buffers = new WeakHashMap<Thread, BufferInfo>();
+    private WeakHashMap<Thread, BufferInfo> buffers = new WeakHashMap<>();
 
     /**
      * The project to send output to.
@@ -98,14 +98,12 @@
      */
     private BufferInfo getBufferInfo() {
         Thread current = Thread.currentThread();
-        BufferInfo bufferInfo = (BufferInfo) buffers.get(current);
-        if (bufferInfo == null) {
-            bufferInfo = new BufferInfo();
+        return buffers.computeIfAbsent(current, x -> {
+            BufferInfo bufferInfo = new BufferInfo();
             bufferInfo.buffer = new ByteArrayOutputStream(INITIAL_SIZE);
             bufferInfo.crSeen = false;
-            buffers.put(current, bufferInfo);
-        }
-        return bufferInfo;
+            return bufferInfo;
+        });
     }
 
     /**
@@ -113,7 +111,7 @@
      */
     private void resetBufferInfo() {
         Thread current = Thread.currentThread();
-        BufferInfo bufferInfo = (BufferInfo) buffers.get(current);
+        BufferInfo bufferInfo = buffers.get(current);
         FileUtils.close(bufferInfo.buffer);
         bufferInfo.buffer = new ByteArrayOutputStream();
         bufferInfo.crSeen = false;
@@ -134,6 +132,7 @@
      * @param cc data to log (byte).
      * @exception IOException if the data cannot be written to the stream
      */
+    @Override
     public void write(int cc) throws IOException {
         final byte c = (byte) cc;
 
@@ -192,6 +191,7 @@
      *
      * @see #flush
      */
+    @Override
     public void close() throws IOException {
         flush();
         removeBuffer();
@@ -203,6 +203,7 @@
      *
      * @exception IOException if there is a problem flushing the stream.
      */
+    @Override
     public void flush() throws IOException {
         BufferInfo bufferInfo = getBufferInfo();
         if (bufferInfo.buffer.size() > 0) {
@@ -219,6 +220,7 @@
      *
      * @throws IOException if the data cannot be written into the stream.
      */
+    @Override
     public void write(byte[] b, int off, int len) throws IOException {
         // find the line breaks and pass other chars through in blocks
         int offset = off;
diff --git a/src/main/org/apache/tools/ant/Diagnostics.java b/src/main/org/apache/tools/ant/Diagnostics.java
index 74e1182..9f1aa0c 100644
--- a/src/main/org/apache/tools/ant/Diagnostics.java
+++ b/src/main/org/apache/tools/ant/Diagnostics.java
@@ -18,15 +18,15 @@
 package org.apache.tools.ant;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.PrintStream;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.URL;
+import java.nio.file.Files;
 import java.util.Calendar;
 import java.util.Enumeration;
 import java.util.Properties;
@@ -42,6 +42,7 @@
 import org.apache.tools.ant.util.JAXPUtils;
 import org.apache.tools.ant.util.JavaEnvUtils;
 import org.apache.tools.ant.util.ProxySetup;
+import org.apache.tools.ant.util.java15.ProxyDiagnostics;
 import org.xml.sax.XMLReader;
 
 /**
@@ -53,9 +54,6 @@
  */
 public final class Diagnostics {
 
-    /** the version number for java 1.5 returned from JavaEnvUtils */
-    private static final int JAVA_1_5_NUMBER = 15;
-
     /**
      * value for which a difference between clock and temp file time triggers
      * a warning.
@@ -112,8 +110,7 @@
         if (home == null) {
             return null;
         }
-        File libDir = new File(home, "lib");
-        return listJarFiles(libDir);
+        return listJarFiles(new File(home, "lib"));
 
     }
 
@@ -123,13 +120,8 @@
      * @return array of files (or null for no such directory)
      */
     private static File[] listJarFiles(File libDir) {
-        FilenameFilter filter = new FilenameFilter() {
-            public boolean accept(File dir, String name) {
-                return name.endsWith(".jar");
-            }
-        };
-        File[] files  = libDir.listFiles(filter);
-        return files;
+        return libDir
+            .listFiles((FilenameFilter) (dir, name) -> name.endsWith(".jar"));
     }
 
     /**
@@ -172,8 +164,7 @@
             return "Could not create an XML Parser";
         }
         // check to what is in the classname
-        String saxParserName = saxParser.getClass().getName();
-        return saxParserName;
+        return saxParser.getClass().getName();
     }
 
     /**
@@ -186,8 +177,7 @@
             return "Could not create an XSLT Processor";
         }
         // check to what is in the classname
-        String processorName = transformer.getClass().getName();
-        return processorName;
+        return transformer.getClass().getName();
     }
 
     /**
@@ -219,17 +209,15 @@
      */
     private static Transformer getXSLTProcessor() {
         TransformerFactory transformerFactory = TransformerFactory.newInstance();
-        if (transformerFactory == null) {
-            return null;
+        if (transformerFactory != null) {
+            try {
+                return transformerFactory.newTransformer();
+            } catch (Exception e) {
+                // ignore
+                ignoreThrowable(e);
+            }
         }
-        Transformer transformer = null;
-        try {
-            transformer = transformerFactory.newTransformer();
-        } catch (Exception e) {
-            // ignore
-            ignoreThrowable(e);
-        }
-        return transformer;
+        return null;
     }
 
     /**
@@ -579,12 +567,12 @@
         //create the file
         long now = System.currentTimeMillis();
         File tempFile = null;
-        FileOutputStream fileout = null;
-        FileInputStream filein = null;
+        OutputStream fileout = null;
+        InputStream filein = null;
         try {
             tempFile = File.createTempFile("diag", "txt", tempDirectory);
             //do some writing to it
-            fileout = new FileOutputStream(tempFile);
+            fileout = Files.newOutputStream(tempFile.toPath());
             byte[] buffer = new byte[KILOBYTE];
             for (int i = 0; i < TEST_FILE_SIZE; i++) {
                 fileout.write(buffer);
@@ -594,7 +582,7 @@
 
             // read to make sure the file has been written completely
             Thread.sleep(1000);
-            filein = new FileInputStream(tempFile);
+            filein = Files.newInputStream(tempFile.toPath());
             int total = 0;
             int read = 0;
             while ((read = filein.read(buffer, 0, KILOBYTE)) > 0) {
@@ -695,25 +683,10 @@
         printProperty(out, ProxySetup.SOCKS_PROXY_USERNAME);
         printProperty(out, ProxySetup.SOCKS_PROXY_PASSWORD);
 
-        if (JavaEnvUtils.getJavaVersionNumber() < JAVA_1_5_NUMBER) {
-            return;
-        }
         printProperty(out, ProxySetup.USE_SYSTEM_PROXIES);
-        final String proxyDiagClassname = "org.apache.tools.ant.util.java15.ProxyDiagnostics";
-        try {
-            Class<?> proxyDiagClass = Class.forName(proxyDiagClassname);
-            Object instance = proxyDiagClass.newInstance();
-            out.println("Java1.5+ proxy settings:");
-            out.println(instance.toString());
-        } catch (ClassNotFoundException e) {
-            //not included, do nothing
-        } catch (IllegalAccessException e) {
-            //not included, do nothing
-        } catch (InstantiationException e) {
-            //not included, do nothing
-        } catch (NoClassDefFoundError e) {
-            // not included, to nothing
-        }
+        ProxyDiagnostics proxyDiag = new ProxyDiagnostics();
+        out.println("Java1.5+ proxy settings:");
+        out.println(proxyDiag.toString());
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/DirectoryScanner.java b/src/main/org/apache/tools/ant/DirectoryScanner.java
index b739ff8..7c540f0 100644
--- a/src/main/org/apache/tools/ant/DirectoryScanner.java
+++ b/src/main/org/apache/tools/ant/DirectoryScanner.java
@@ -20,15 +20,22 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.Deque;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.Vector;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.taskdefs.condition.Os;
 import org.apache.tools.ant.types.Resource;
@@ -39,9 +46,7 @@
 import org.apache.tools.ant.types.selectors.SelectorUtils;
 import org.apache.tools.ant.types.selectors.TokenizedPath;
 import org.apache.tools.ant.types.selectors.TokenizedPattern;
-import org.apache.tools.ant.util.CollectionUtils;
 import org.apache.tools.ant.util.FileUtils;
-import org.apache.tools.ant.util.SymbolicLinkUtils;
 import org.apache.tools.ant.util.VectorSet;
 
 /**
@@ -224,16 +229,12 @@
     /** Helper. */
     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
 
-    /** Helper. */
-    private static final SymbolicLinkUtils SYMLINK_UTILS =
-        SymbolicLinkUtils.getSymbolicLinkUtils();
-
     /**
      * Patterns which should be excluded by default.
      *
      * @see #addDefaultExcludes()
      */
-    private static final Set<String> defaultExcludes = new HashSet<String>();
+    private static final Set<String> defaultExcludes = new HashSet<>();
     static {
         resetDefaultExcludes();
     }
@@ -326,7 +327,7 @@
      *
      * @since Ant 1.6
      */
-    private final Set<String> scannedDirs = new HashSet<String>();
+    private final Set<String> scannedDirs = new HashSet<>();
 
     /**
      * Map of all include patterns that are full file names and don't
@@ -343,7 +344,7 @@
      *
      * @since Ant 1.8.0
      */
-    private final Map<String, TokenizedPath> includeNonPatterns = new HashMap<String, TokenizedPath>();
+    private final Map<String, TokenizedPath> includeNonPatterns = new HashMap<>();
 
     /**
      * Map of all exclude patterns that are full file names and don't
@@ -360,7 +361,7 @@
      *
      * @since Ant 1.8.0
      */
-    private final Map<String, TokenizedPath> excludeNonPatterns = new HashMap<String, TokenizedPath>();
+    private final Map<String, TokenizedPath> excludeNonPatterns = new HashMap<>();
 
     /**
      * Array of all include patterns that contain wildcards.
@@ -439,13 +440,7 @@
      *
      * @since Ant 1.8.0
      */
-    private final Set<String> notFollowedSymlinks = new HashSet<String>();
-
-    /**
-     * Sole constructor.
-     */
-    public DirectoryScanner() {
-    }
+    private final Set<String> notFollowedSymlinks = new HashSet<>();
 
     /**
      * Test whether or not a given path matches the start of a given
@@ -621,8 +616,8 @@
     public static void resetDefaultExcludes() {
         synchronized (defaultExcludes) {
             defaultExcludes.clear();
-            for (int i = 0; i < DEFAULTEXCLUDES.length; i++) {
-                defaultExcludes.add(DEFAULTEXCLUDES[i]);
+            for (String element : DEFAULTEXCLUDES) {
+                defaultExcludes.add(element);
             }
         }
     }
@@ -635,8 +630,9 @@
      *
      * @param basedir The base directory to scan.
      */
+    @Override
     public void setBasedir(final String basedir) {
-        setBasedir(basedir == null ? (File) null
+        setBasedir(basedir == null ? null
             : new File(basedir.replace('/', File.separatorChar).replace(
             '\\', File.separatorChar)));
     }
@@ -647,6 +643,7 @@
      *
      * @param basedir The base directory for scanning.
      */
+    @Override
     public synchronized void setBasedir(final File basedir) {
         this.basedir = basedir;
     }
@@ -657,6 +654,7 @@
      *
      * @return the base directory to be scanned.
      */
+    @Override
     public synchronized File getBasedir() {
         return basedir;
     }
@@ -678,6 +676,7 @@
      * @param isCaseSensitive whether or not the file system should be
      *                        regarded as a case sensitive one.
      */
+    @Override
     public synchronized void setCaseSensitive(final boolean isCaseSensitive) {
         this.isCaseSensitive = isCaseSensitive;
     }
@@ -737,14 +736,13 @@
      *                 list is given, all elements must be
      *                 non-<code>null</code>.
      */
+    @Override
     public synchronized void setIncludes(final String[] includes) {
         if (includes == null) {
             this.includes = null;
         } else {
-            this.includes = new String[includes.length];
-            for (int i = 0; i < includes.length; i++) {
-                this.includes[i] = normalizePattern(includes[i]);
-            }
+            this.includes = Stream.of(includes)
+                .map(DirectoryScanner::normalizePattern).toArray(String[]::new);
         }
     }
 
@@ -760,14 +758,13 @@
      *                 should be excluded. If a non-<code>null</code> list is
      *                 given, all elements must be non-<code>null</code>.
      */
+    @Override
     public synchronized void setExcludes(final String[] excludes) {
         if (excludes == null) {
             this.excludes = null;
         } else {
-            this.excludes = new String[excludes.length];
-            for (int i = 0; i < excludes.length; i++) {
-                this.excludes[i] = normalizePattern(excludes[i]);
-            }
+            this.excludes = Stream.of(excludes).map(DirectoryScanner::normalizePattern)
+                    .toArray(String[]::new);
         }
     }
 
@@ -786,17 +783,12 @@
      */
     public synchronized void addExcludes(final String[] excludes) {
         if (excludes != null && excludes.length > 0) {
-            if (this.excludes != null && this.excludes.length > 0) {
-                final String[] tmp = new String[excludes.length
-                                          + this.excludes.length];
-                System.arraycopy(this.excludes, 0, tmp, 0,
-                                 this.excludes.length);
-                for (int i = 0; i < excludes.length; i++) {
-                    tmp[this.excludes.length + i] = normalizePattern(excludes[i]);
-                }
-                this.excludes = tmp;
-            } else {
+            if (this.excludes == null || this.excludes.length == 0) {
                 setExcludes(excludes);
+            } else {
+                this.excludes = Stream.concat(Stream.of(this.excludes),
+                        Stream.of(excludes).map(DirectoryScanner::normalizePattern))
+                        .toArray(String[]::new);
             }
         }
     }
@@ -824,6 +816,7 @@
      *
      * @param selectors specifies the selectors to be invoked on a scan.
      */
+    @Override
     public synchronized void setSelectors(final FileSelector[] selectors) {
         this.selectors = selectors;
     }
@@ -849,6 +842,7 @@
      * @exception IllegalStateException if the base directory was set
      *            incorrectly (i.e. if it doesn't exist or isn't a directory).
      */
+    @Override
     public void scan() throws IllegalStateException {
         synchronized (scanLock) {
             if (scanning) {
@@ -872,13 +866,13 @@
                 clearResults();
 
                 // set in/excludes to reasonable defaults if needed:
-                final boolean nullIncludes = (includes == null);
+                final boolean nullIncludes = includes == null;
                 includes = nullIncludes ? new String[] {SelectorUtils.DEEP_TREE_MATCH} : includes;
-                final boolean nullExcludes = (excludes == null);
+                final boolean nullExcludes = excludes == null;
                 excludes = nullExcludes ? new String[0] : excludes;
 
                 if (basedir != null && !followSymlinks
-                    && SYMLINK_UTILS.isSymbolicLink(basedir)) {
+                    && Files.isSymbolicLink(basedir.toPath())) {
                     notFollowedSymlinks.add(basedir.getAbsolutePath());
                     basedir = null;
                 }
@@ -901,22 +895,19 @@
                     } else if (!basedir.isDirectory()) {
                         illegal = new IllegalStateException("basedir "
                                                             + basedir
-                                                            + " is not a"
-                                                            + " directory.");
+                                                            + " is not a directory.");
                     }
                     if (illegal != null) {
                         throw illegal;
                     }
                 }
                 if (isIncluded(TokenizedPath.EMPTY_PATH)) {
-                    if (!isExcluded(TokenizedPath.EMPTY_PATH)) {
-                        if (isSelected("", basedir)) {
-                            dirsIncluded.addElement("");
-                        } else {
-                            dirsDeselected.addElement("");
-                        }
-                    } else {
+                    if (isExcluded(TokenizedPath.EMPTY_PATH)) {
                         dirsExcluded.addElement("");
+                    } else if (isSelected("", basedir)) {
+                        dirsIncluded.addElement("");
+                    } else {
+                        dirsDeselected.addElement("");
                     }
                 } else {
                     dirsNotIncluded.addElement("");
@@ -926,8 +917,6 @@
                 includes = nullIncludes ? null : includes;
                 excludes = nullExcludes ? null : excludes;
             }
-        } catch (final IOException ex) {
-            throw new BuildException(ex);
         } finally {
             basedir = savedBase;
             synchronized (scanLock) {
@@ -944,17 +933,18 @@
      */
     private void checkIncludePatterns() {
         ensureNonPatternSetsReady();
-        final Map<TokenizedPath, String> newroots = new HashMap<TokenizedPath, String>();
+        final Map<TokenizedPath, String> newroots = new HashMap<>();
 
         // put in the newroots map the include patterns without
         // wildcard tokens
-        for (int i = 0; i < includePatterns.length; i++) {
-            final String pattern = includePatterns[i].toString();
+        for (TokenizedPattern includePattern : includePatterns) {
+            final String pattern = includePattern.toString();
             if (!shouldSkipPattern(pattern)) {
-                newroots.put(includePatterns[i].rtrimWildcardTokens(), pattern);
+                newroots.put(includePattern.rtrimWildcardTokens(), pattern);
             }
         }
-        for (final Map.Entry<String, TokenizedPath> entry : includeNonPatterns.entrySet()) {
+        for (final Map.Entry<String, TokenizedPath> entry : includeNonPatterns
+            .entrySet()) {
             final String pattern = entry.getKey();
             if (!shouldSkipPattern(pattern)) {
                 newroots.put(entry.getValue(), pattern);
@@ -1056,10 +1046,9 @@
     private boolean shouldSkipPattern(final String pattern) {
         if (FileUtils.isAbsolutePath(pattern)) {
             //skip abs. paths not under basedir, if set:
-            if (basedir != null
-                && !SelectorUtils.matchPatternStart(pattern,
-                                                    basedir.getAbsolutePath(),
-                                                    isCaseSensitive())) {
+            if (!(basedir == null || SelectorUtils.matchPatternStart(pattern,
+                                                basedir.getAbsolutePath(),
+                                                isCaseSensitive()))) {
                 return true;
             }
         } else if (basedir == null) {
@@ -1073,14 +1062,14 @@
      * Clear the result caches for a scan.
      */
     protected synchronized void clearResults() {
-        filesIncluded    = new VectorSet<String>();
-        filesNotIncluded = new VectorSet<String>();
-        filesExcluded    = new VectorSet<String>();
-        filesDeselected  = new VectorSet<String>();
-        dirsIncluded     = new VectorSet<String>();
-        dirsNotIncluded  = new VectorSet<String>();
-        dirsExcluded     = new VectorSet<String>();
-        dirsDeselected   = new VectorSet<String>();
+        filesIncluded    = new VectorSet<>();
+        filesNotIncluded = new VectorSet<>();
+        filesExcluded    = new VectorSet<>();
+        filesDeselected  = new VectorSet<>();
+        dirsIncluded     = new VectorSet<>();
+        dirsNotIncluded  = new VectorSet<>();
+        dirsExcluded     = new VectorSet<>();
+        dirsDeselected   = new VectorSet<>();
         everythingIncluded = (basedir != null);
         scannedDirs.clear();
         notFollowedSymlinks.clear();
@@ -1144,10 +1133,10 @@
     }
 
     private void processSlowScan(final String[] arr) {
-        for (int i = 0; i < arr.length; i++) {
-            final TokenizedPath path  = new TokenizedPath(arr[i]);
+        for (String element : arr) {
+            final TokenizedPath path  = new TokenizedPath(element);
             if (!couldHoldIncluded(path) || contentsExcluded(path)) {
-                scandir(new File(basedir, arr[i]), path, false);
+                scandir(new File(basedir, element), path, false);
             }
         }
     }
@@ -1205,17 +1194,17 @@
             if (!dir.exists()) {
                 throw new BuildException(dir + DOES_NOT_EXIST_POSTFIX);
             } else if (!dir.isDirectory()) {
-                throw new BuildException(dir + " is not a directory.");
+                throw new BuildException("%s is not a directory.", dir);
             } else {
-                throw new BuildException("IO error scanning directory '"
-                                         + dir.getAbsolutePath() + "'");
+                throw new BuildException("IO error scanning directory '%s'",
+                    dir.getAbsolutePath());
             }
         }
         scandir(dir, path, fast, newfiles, new LinkedList<String>());
     }
 
     private void scandir(final File dir, final TokenizedPath path, final boolean fast,
-                         String[] newfiles, final LinkedList<String> directoryNamesFollowed) {
+                         String[] newfiles, final Deque<String> directoryNamesFollowed) {
         String vpath = path.toString();
         if (vpath.length() > 0 && !vpath.endsWith(File.separator)) {
             vpath += File.separator;
@@ -1226,30 +1215,28 @@
             return;
         }
         if (!followSymlinks) {
-            final ArrayList<String> noLinks = new ArrayList<String>();
-            for (int i = 0; i < newfiles.length; i++) {
-                try {
-                    if (SYMLINK_UTILS.isSymbolicLink(dir, newfiles[i])) {
-                        final String name = vpath + newfiles[i];
-                        final File file = new File(dir, newfiles[i]);
-                        if (file.isDirectory()) {
-                            dirsExcluded.addElement(name);
-                        } else if (file.isFile()) {
-                            filesExcluded.addElement(name);
-                        }
-                        accountForNotFollowedSymlink(name, file);
-                    } else {
-                        noLinks.add(newfiles[i]);
+            final ArrayList<String> noLinks = new ArrayList<>();
+            for (final String newfile : newfiles) {
+                final Path filePath;
+                if (dir == null) {
+                    filePath = Paths.get(newfile);
+                } else {
+                    filePath = Paths.get(dir.toPath().toString(), newfile);
+                }
+                if (Files.isSymbolicLink(filePath)) {
+                    final String name = vpath + newfile;
+                    final File file = new File(dir, newfile);
+                    if (file.isDirectory()) {
+                        dirsExcluded.addElement(name);
+                    } else if (file.isFile()) {
+                        filesExcluded.addElement(name);
                     }
-                } catch (final IOException ioe) {
-                    final String msg = "IOException caught while checking "
-                        + "for links, couldn't get canonical path!";
-                    // will be caught and redirected to Ant's logging system
-                    System.err.println(msg);
-                    noLinks.add(newfiles[i]);
+                    accountForNotFollowedSymlink(name, file);
+                } else {
+                    noLinks.add(newfile);
                 }
             }
-            newfiles = (noLinks.toArray(new String[noLinks.size()]));
+            newfiles = noLinks.toArray(new String[noLinks.size()]);
         } else {
             directoryNamesFollowed.addFirst(dir.getName());
         }
@@ -1329,7 +1316,7 @@
     private void accountForIncludedDir(final TokenizedPath name,
                                        final File file, final boolean fast,
                                        final String[] children,
-                                       final LinkedList<String> directoryNamesFollowed) {
+                                       final Deque<String> directoryNamesFollowed) {
         processIncluded(name, file, dirsIncluded, dirsExcluded, dirsDeselected);
         if (fast && couldHoldIncluded(name) && !contentsExcluded(name)) {
             scandir(file, name, fast, children, directoryNamesFollowed);
@@ -1348,13 +1335,12 @@
     }
 
     private void processIncluded(final TokenizedPath path,
-                                 final File file, final Vector<String> inc, final Vector<String> exc,
-                                 final Vector<String> des) {
+                                 final File file, final List<String> inc, final List<String> exc,
+                                 final List<String> des) {
         final String name = path.toString();
         if (inc.contains(name) || exc.contains(name) || des.contains(name)) {
             return;
         }
-
         boolean included = false;
         if (isExcluded(path)) {
             exc.add(name);
@@ -1390,17 +1376,12 @@
     private boolean isIncluded(final TokenizedPath path) {
         ensureNonPatternSetsReady();
 
-        if (isCaseSensitive()
-            ? includeNonPatterns.containsKey(path.toString())
-            : includeNonPatterns.containsKey(path.toString().toUpperCase())) {
-            return true;
+        String toMatch = path.toString();
+        if (!isCaseSensitive()) {
+            toMatch = toMatch.toUpperCase();
         }
-        for (int i = 0; i < includePatterns.length; i++) {
-            if (includePatterns[i].matchPath(path, isCaseSensitive())) {
-                return true;
-            }
-        }
-        return false;
+        return includeNonPatterns.containsKey(toMatch)
+            || Stream.of(includePatterns).anyMatch(p -> p.matchPath(path, isCaseSensitive()));
     }
 
     /**
@@ -1424,19 +1405,9 @@
      *         least one include pattern, or <code>false</code> otherwise.
      */
     private boolean couldHoldIncluded(final TokenizedPath tokenizedName) {
-        for (int i = 0; i < includePatterns.length; i++) {
-            if (couldHoldIncluded(tokenizedName, includePatterns[i])) {
-                return true;
-            }
-        }
-        for (final Iterator<TokenizedPath> iter = includeNonPatterns.values().iterator();
-             iter.hasNext();) {
-            if (couldHoldIncluded(tokenizedName,
-                                  iter.next().toPattern())) {
-                return true;
-            }
-        }
-        return false;
+        return Stream.concat(Stream.of(includePatterns),
+                includeNonPatterns.values().stream().map(TokenizedPath::toPattern))
+                .anyMatch(pat -> couldHoldIncluded(tokenizedName, pat));
     }
 
     /**
@@ -1485,12 +1456,8 @@
      */
     private boolean isMorePowerfulThanExcludes(final String name) {
         final String soughtexclude = name + File.separatorChar + SelectorUtils.DEEP_TREE_MATCH;
-        for (int counter = 0; counter < excludePatterns.length; counter++) {
-            if (excludePatterns[counter].toString().equals(soughtexclude))  {
-                return false;
-            }
-        }
-        return true;
+        return Stream.of(excludePatterns).map(Object::toString)
+            .noneMatch(Predicate.isEqual(soughtexclude));
     }
 
     /**
@@ -1499,14 +1466,10 @@
      * @return whether all the specified directory's contents are excluded.
      */
     /* package */ boolean contentsExcluded(final TokenizedPath path) {
-        for (int i = 0; i < excludePatterns.length; i++) {
-            if (excludePatterns[i].endsWith(SelectorUtils.DEEP_TREE_MATCH)
-                && excludePatterns[i].withoutLastToken()
-                   .matchPath(path, isCaseSensitive())) {
-                return true;
-            }
-        }
-        return false;
+        return Stream.of(excludePatterns)
+            .filter(p -> p.endsWith(SelectorUtils.DEEP_TREE_MATCH))
+            .map(TokenizedPattern::withoutLastToken)
+            .anyMatch(wlt -> wlt.matchPath(path, isCaseSensitive()));
     }
 
     /**
@@ -1532,17 +1495,12 @@
     private boolean isExcluded(final TokenizedPath name) {
         ensureNonPatternSetsReady();
 
-        if (isCaseSensitive()
-            ? excludeNonPatterns.containsKey(name.toString())
-            : excludeNonPatterns.containsKey(name.toString().toUpperCase())) {
-            return true;
+        String toMatch = name.toString();
+        if (!isCaseSensitive()) {
+            toMatch = toMatch.toUpperCase();
         }
-        for (int i = 0; i < excludePatterns.length; i++) {
-            if (excludePatterns[i].matchPath(name, isCaseSensitive())) {
-                return true;
-            }
-        }
-        return false;
+        return excludeNonPatterns.containsKey(toMatch)
+            || Stream.of(excludePatterns).anyMatch(p -> p.matchPath(name, isCaseSensitive()));
     }
 
     /**
@@ -1554,14 +1512,8 @@
      *         should not be selected, <code>true</code> otherwise.
      */
     protected boolean isSelected(final String name, final File file) {
-        if (selectors != null) {
-            for (int i = 0; i < selectors.length; i++) {
-                if (!selectors[i].isSelected(basedir, name, file)) {
-                    return false;
-                }
-            }
-        }
-        return true;
+        return selectors == null
+                || Stream.of(selectors).allMatch(sel -> sel.isSelected(basedir, name, file));
     }
 
     /**
@@ -1572,14 +1524,14 @@
      * @return the names of the files which matched at least one of the
      *         include patterns and none of the exclude patterns.
      */
+    @Override
     public String[] getIncludedFiles() {
         String[] files;
         synchronized (this) {
             if (filesIncluded == null) {
                 throw new IllegalStateException("Must call scan() first");
             }
-            files = new String[filesIncluded.size()];
-            filesIncluded.copyInto(files);
+            files = filesIncluded.toArray(new String[filesIncluded.size()]);
         }
         Arrays.sort(files);
         return files;
@@ -1607,11 +1559,10 @@
      *
      * @see #slowScan
      */
+    @Override
     public synchronized String[] getNotIncludedFiles() {
         slowScan();
-        final String[] files = new String[filesNotIncluded.size()];
-        filesNotIncluded.copyInto(files);
-        return files;
+        return filesNotIncluded.toArray(new String[filesNotIncluded.size()]);
     }
 
     /**
@@ -1625,11 +1576,10 @@
      *
      * @see #slowScan
      */
+    @Override
     public synchronized String[] getExcludedFiles() {
         slowScan();
-        final String[] files = new String[filesExcluded.size()];
-        filesExcluded.copyInto(files);
-        return files;
+        return filesExcluded.toArray(new String[filesExcluded.size()]);
     }
 
     /**
@@ -1643,11 +1593,10 @@
      *
      * @see #slowScan
      */
+    @Override
     public synchronized String[] getDeselectedFiles() {
         slowScan();
-        final String[] files = new String[filesDeselected.size()];
-        filesDeselected.copyInto(files);
-        return files;
+        return filesDeselected.toArray(new String[filesDeselected.size()]);
     }
 
     /**
@@ -1658,14 +1607,14 @@
      * @return the names of the directories which matched at least one of the
      * include patterns and none of the exclude patterns.
      */
+    @Override
     public String[] getIncludedDirectories() {
         String[] directories;
         synchronized (this) {
             if (dirsIncluded == null) {
                 throw new IllegalStateException("Must call scan() first");
             }
-            directories = new String[dirsIncluded.size()];
-            dirsIncluded.copyInto(directories);
+            directories = dirsIncluded.toArray(new String[dirsIncluded.size()]);
         }
         Arrays.sort(directories);
         return directories;
@@ -1693,11 +1642,10 @@
      *
      * @see #slowScan
      */
+    @Override
     public synchronized String[] getNotIncludedDirectories() {
         slowScan();
-        final String[] directories = new String[dirsNotIncluded.size()];
-        dirsNotIncluded.copyInto(directories);
-        return directories;
+        return dirsNotIncluded.toArray(new String[dirsNotIncluded.size()]);
     }
 
     /**
@@ -1711,11 +1659,10 @@
      *
      * @see #slowScan
      */
+    @Override
     public synchronized String[] getExcludedDirectories() {
         slowScan();
-        final String[] directories = new String[dirsExcluded.size()];
-        dirsExcluded.copyInto(directories);
-        return directories;
+        return dirsExcluded.toArray(new String[dirsExcluded.size()]);
     }
 
     /**
@@ -1729,11 +1676,10 @@
      *
      * @see #slowScan
      */
+    @Override
     public synchronized String[] getDeselectedDirectories() {
         slowScan();
-        final String[] directories = new String[dirsDeselected.size()];
-        dirsDeselected.copyInto(directories);
-        return directories;
+        return dirsDeselected.toArray(new String[dirsDeselected.size()]);
     }
 
     /**
@@ -1757,20 +1703,14 @@
     /**
      * Add default exclusions to the current exclusions set.
      */
+    @Override
     public synchronized void addDefaultExcludes() {
-        final int excludesLength = excludes == null ? 0 : excludes.length;
-        String[] newExcludes;
-        final String[] defaultExcludesTemp = getDefaultExcludes();
-        newExcludes = new String[excludesLength + defaultExcludesTemp.length];
-        if (excludesLength > 0) {
-            System.arraycopy(excludes, 0, newExcludes, 0, excludesLength);
+        Stream<String> s = Stream.of(getDefaultExcludes()).map(p -> p.replace('/',
+                File.separatorChar).replace('\\', File.separatorChar));
+        if (excludes != null) {
+            s = Stream.concat(Stream.of(excludes), s);
         }
-        for (int i = 0; i < defaultExcludesTemp.length; i++) {
-            newExcludes[i + excludesLength] =
-                defaultExcludesTemp[i].replace('/', File.separatorChar)
-                .replace('\\', File.separatorChar);
-        }
-        excludes = newExcludes;
+        excludes = s.toArray(String[]::new);
     }
 
     /**
@@ -1780,6 +1720,7 @@
      * @return the resource with the given name.
      * @since Ant 1.5.2
      */
+    @Override
     public synchronized Resource getResource(final String name) {
         return new FileResource(basedir, name);
     }
@@ -1842,13 +1783,13 @@
      */
     private TokenizedPattern[] fillNonPatternSet(final Map<String, TokenizedPath> map,
                                                  final String[] patterns) {
-        final ArrayList<TokenizedPattern> al = new ArrayList<TokenizedPattern>(patterns.length);
-        for (int i = 0; i < patterns.length; i++) {
-            if (!SelectorUtils.hasWildcards(patterns[i])) {
-                final String s = isCaseSensitive() ? patterns[i] : patterns[i].toUpperCase();
-                map.put(s, new TokenizedPath(s));
+        final List<TokenizedPattern> al = new ArrayList<>(patterns.length);
+        for (String pattern : patterns) {
+            if (SelectorUtils.hasWildcards(pattern)) {
+                al.add(new TokenizedPattern(pattern));
             } else {
-                al.add(new TokenizedPattern(patterns[i]));
+                final String s = isCaseSensitive() ? pattern : pattern.toUpperCase();
+                map.put(s, new TokenizedPath(s));
             }
         }
         return al.toArray(new TokenizedPattern[al.size()]);
@@ -1866,13 +1807,19 @@
      * @since Ant 1.8.0
      */
     private boolean causesIllegalSymlinkLoop(final String dirName, final File parent,
-                                             final LinkedList<String> directoryNamesFollowed) {
+                                             final Deque<String> directoryNamesFollowed) {
         try {
+            final Path dirPath;
+            if (parent == null) {
+                dirPath = Paths.get(dirName);
+            } else {
+                dirPath = Paths.get(parent.toPath().toString(), dirName);
+            }
             if (directoryNamesFollowed.size() >= maxLevelsOfSymlinks
-                && CollectionUtils.frequency(directoryNamesFollowed, dirName) >= maxLevelsOfSymlinks
-                && SYMLINK_UTILS.isSymbolicLink(parent, dirName)) {
+                && Collections.frequency(directoryNamesFollowed, dirName) >= maxLevelsOfSymlinks
+                && Files.isSymbolicLink(dirPath)) {
 
-                final ArrayList<String> files = new ArrayList<String>();
+                final List<String> files = new ArrayList<>();
                 File f = FILE_UTILS.resolveFile(parent, dirName);
                 final String target = f.getCanonicalPath();
                 files.add(target);
@@ -1884,17 +1831,16 @@
                         f = FILE_UTILS.resolveFile(parent, relPath + dir);
                         files.add(f.getCanonicalPath());
                         if (files.size() > maxLevelsOfSymlinks
-                            && CollectionUtils.frequency(files, target) > maxLevelsOfSymlinks) {
+                            && Collections.frequency(files, target) > maxLevelsOfSymlinks) {
                             return true;
                         }
                     }
                 }
-
             }
             return false;
         } catch (final IOException ex) {
-            throw new BuildException("Caught error while checking for"
-                                     + " symbolic links", ex);
+            throw new BuildException(
+                "Caught error while checking for symbolic links", ex);
         }
     }
 
diff --git a/src/main/org/apache/tools/ant/DynamicConfigurator.java b/src/main/org/apache/tools/ant/DynamicConfigurator.java
index e48062b..1eb321e 100644
--- a/src/main/org/apache/tools/ant/DynamicConfigurator.java
+++ b/src/main/org/apache/tools/ant/DynamicConfigurator.java
@@ -26,4 +26,3 @@
 public interface DynamicConfigurator
     extends DynamicAttribute, DynamicElement {
 }
-
diff --git a/src/main/org/apache/tools/ant/Evaluable.java b/src/main/org/apache/tools/ant/Evaluable.java
index 47f09c7..bd0ec7e 100644
--- a/src/main/org/apache/tools/ant/Evaluable.java
+++ b/src/main/org/apache/tools/ant/Evaluable.java
@@ -17,13 +17,19 @@
  */
 package org.apache.tools.ant;
 
+import java.util.function.Supplier;
+
 /**
  * Kind of task attribute that can be evaluated before being assigned
+ * @param <T> as {@link Supplier}
  *
  * @see RuntimeConfigurable
  */
-public interface Evaluable {
+public interface Evaluable<T> extends Supplier<T> {
 
-    Object eval();
+    T eval();
 
+    default T get() {
+        return eval();
+    }
 }
diff --git a/src/main/org/apache/tools/ant/IntrospectionHelper.java b/src/main/org/apache/tools/ant/IntrospectionHelper.java
index ff64e9d..8ad8111 100644
--- a/src/main/org/apache/tools/ant/IntrospectionHelper.java
+++ b/src/main/org/apache/tools/ant/IntrospectionHelper.java
@@ -63,7 +63,7 @@
     /**
      * Helper instances we've already created (Class.getName() to IntrospectionHelper).
      */
-    private static final Map<String, IntrospectionHelper> HELPERS = new Hashtable<String, IntrospectionHelper>();
+    private static final Map<String, IntrospectionHelper> HELPERS = new Hashtable<>();
 
     /**
      * Map from primitive types to wrapper classes for use in
@@ -71,7 +71,7 @@
      * and boolean are in here even though they get special treatment
      * - this way we only need to test for the wrapper class.
      */
-    private static final Map<Class<?>, Class<?>> PRIMITIVE_TYPE_MAP = new HashMap<Class<?>, Class<?>>(8);
+    private static final Map<Class<?>, Class<?>> PRIMITIVE_TYPE_MAP = new HashMap<>(8);
 
     // Set up PRIMITIVE_TYPE_MAP
     static {
@@ -91,30 +91,30 @@
      * Map from attribute names to attribute types
      * (String to Class).
      */
-    private final Hashtable<String, Class<?>> attributeTypes = new Hashtable<String, Class<?>>();
+    private final Map<String, Class<?>> attributeTypes = new Hashtable<>();
 
     /**
      * Map from attribute names to attribute setter methods
      * (String to AttributeSetter).
      */
-    private final Hashtable<String, AttributeSetter> attributeSetters = new Hashtable<String, AttributeSetter>();
+    private final Map<String, AttributeSetter> attributeSetters = new Hashtable<>();
 
     /**
      * Map from attribute names to nested types
      * (String to Class).
      */
-    private final Hashtable<String, Class<?>> nestedTypes = new Hashtable<String, Class<?>>();
+    private final Map<String, Class<?>> nestedTypes = new Hashtable<>();
 
     /**
      * Map from attribute names to methods to create nested types
      * (String to NestedCreator).
      */
-    private final Hashtable<String, NestedCreator> nestedCreators = new Hashtable<String, NestedCreator>();
+    private final Map<String, NestedCreator> nestedCreators = new Hashtable<>();
 
     /**
      * Vector of methods matching add[Configured](Class) pattern.
      */
-    private final List<Method> addTypeMethods = new ArrayList<Method>();
+    private final List<Method> addTypeMethods = new ArrayList<>();
 
     /**
      * The method to invoke to add PCDATA.
@@ -706,7 +706,7 @@
      * @return true if the given nested element is supported
      */
     public boolean supportsNestedElement(final String parentUri, final String elementName) {
-        if (isDynamic() || addTypeMethods.size() > 0) {
+        if (isDynamic() || !addTypeMethods.isEmpty()) {
             return true;
         }
         return supportsReflectElement(parentUri, elementName);
@@ -731,7 +731,7 @@
      */
     public boolean supportsNestedElement(final String parentUri, final String elementName,
                                          final Project project, final Object parent) {
-        if (addTypeMethods.size() > 0
+        if (!addTypeMethods.isEmpty()
             && createAddTypeCreator(project, parent, elementName) != null) {
             return true;
         }
@@ -944,7 +944,7 @@
      * @see #getAttributeMap
      */
     public Enumeration<String> getAttributes() {
-        return attributeSetters.keys();
+        return Collections.enumeration(attributeSetters.keySet());
     }
 
     /**
@@ -968,7 +968,7 @@
      * @see #getNestedElementMap
      */
     public Enumeration<String> getNestedElements() {
-        return nestedTypes.keys();
+        return Collections.enumeration(nestedTypes.keySet());
     }
 
     /**
@@ -1118,6 +1118,16 @@
                 }
             };
         }
+        // resolve relative nio paths through Project
+        if (java.nio.file.Path.class.equals(reflectedArg)) {
+            return new AttributeSetter(m, arg) {
+                @Override
+                public void set(final Project p, final Object parent, final String value) throws InvocationTargetException, IllegalAccessException {
+                    m.invoke(parent, new Object[] { p.resolveFile(value).toPath() });
+                }
+            };
+        }
+
         // resolve Resources/FileProviders as FileResources relative to Project:
         if (Resource.class.equals(reflectedArg) || FileProvider.class.equals(reflectedArg)) {
             return new AttributeSetter(m, arg) {
@@ -1533,7 +1543,7 @@
      */
     private NestedCreator createAddTypeCreator(
             final Project project, final Object parent, final String elementName) throws BuildException {
-        if (addTypeMethods.size() == 0) {
+        if (addTypeMethods.isEmpty()) {
             return null;
         }
         final ComponentHelper helper = ComponentHelper.getComponentHelper(project);
@@ -1602,7 +1612,7 @@
         for (int c = 0; c < size; ++c) {
             final Method current = addTypeMethods.get(c);
             if (current.getParameterTypes()[0].equals(argClass)) {
-                if (method.getName().equals("addConfigured")) {
+                if ("addConfigured".equals(method.getName())) {
                     // add configured replaces the add method
                     addTypeMethods.set(c, method);
                 }
diff --git a/src/main/org/apache/tools/ant/Location.java b/src/main/org/apache/tools/ant/Location.java
index 8e25d10..0e83760 100644
--- a/src/main/org/apache/tools/ant/Location.java
+++ b/src/main/org/apache/tools/ant/Location.java
@@ -19,6 +19,7 @@
 package org.apache.tools.ant;
 
 import java.io.Serializable;
+import java.util.Objects;
 
 import org.apache.tools.ant.util.FileUtils;
 import org.xml.sax.Locator;
@@ -131,8 +132,9 @@
      *         <code>"fileName: "</code> if only the file name is known,
      *         and the empty string for unknown locations.
      */
+    @Override
     public String toString() {
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
 
         if (fileName != null) {
             buf.append(fileName);
@@ -155,6 +157,7 @@
      *              as this object.
      * @since Ant 1.6.3
      */
+    @Override
     public boolean equals(Object other) {
         if (this == other) {
             return true;
@@ -173,7 +176,8 @@
      * @return a hash code value for this location.
      * @since Ant 1.6.3
      */
+    @Override
     public int hashCode() {
-        return toString().hashCode();
+        return Objects.hash(fileName, lineNumber);
     }
 }
diff --git a/src/main/org/apache/tools/ant/MagicNames.java b/src/main/org/apache/tools/ant/MagicNames.java
index 7c17c05..5457e62 100644
--- a/src/main/org/apache/tools/ant/MagicNames.java
+++ b/src/main/org/apache/tools/ant/MagicNames.java
@@ -56,6 +56,12 @@
     public static final String SCRIPT_REPOSITORY = "org.apache.ant.scriptrepo";
 
     /**
+     * The name of the script cache used by the script runner.
+     * Value {@value}
+     */
+    public static final String SCRIPT_CACHE = "org.apache.ant.scriptcache";
+
+    /**
      * The name of the reference to the System Class Loader.
      * Value {@value}
      **/
@@ -299,8 +305,21 @@
      * as seconds since the epoch.</p>
      *
      * Value: {@value}
-     * @since Ant 1.9.10
+     * @since Ant 1.10.2
      */
     public static final String TSTAMP_NOW = "ant.tstamp.now";
+
+    /**
+     * Magic property that can be set to contain a value for tstamp's
+     * "now" in order to make builds that use the task create
+     * reproducible results.
+     *
+     * <p>The value is expected to be in ISO time format
+     * (<i>1972-04-17T08:07</i>)</p>
+     *
+     * Value: {@value}
+     * @since Ant 1.10.2
+     */
+    public static final String TSTAMP_NOW_ISO = "ant.tstamp.now.iso";
 }
 
diff --git a/src/main/org/apache/tools/ant/Main.java b/src/main/org/apache/tools/ant/Main.java
index 33dae8c..7e0f09d 100644
--- a/src/main/org/apache/tools/ant/Main.java
+++ b/src/main/org/apache/tools/ant/Main.java
@@ -19,11 +19,11 @@
 package org.apache.tools.ant;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -87,16 +87,16 @@
     private PrintStream err = System.err;
 
     /** The build targets. */
-    private final Vector<String> targets = new Vector<String>();
+    private final Vector<String> targets = new Vector<>();
 
     /** Set of properties that can be used by tasks. */
     private final Properties definedProps = new Properties();
 
     /** Names of classes to add as listeners to project. */
-    private final Vector<String> listeners = new Vector<String>(1);
+    private final Vector<String> listeners = new Vector<>(1);
 
     /** File names of property files to load on startup. */
-    private final Vector<String> propertyFiles = new Vector<String>(1);
+    private final Vector<String> propertyFiles = new Vector<>(1);
 
     /** Indicates whether this build is to support interactive input */
     private boolean allowInput = true;
@@ -155,17 +155,9 @@
      */
     private boolean proxy = false;
 
-    private final Map<Class<?>, List<String>> extraArguments = new HashMap<Class<?>, List<String>>();
+    private final Map<Class<?>, List<String>> extraArguments = new HashMap<>();
 
-    private static final GetProperty NOPROPERTIES = new GetProperty() {
-        public Object getProperty(final String aName) {
-            // No existing property takes precedence
-            return null;
-        }
-    };
-
-
-
+    private static final GetProperty NOPROPERTIES = aName -> null;
 
     /**
      * Prints the message of the Throwable if it (the message) is not
@@ -355,10 +347,10 @@
                 try {
                     final File logFile = new File(args[i + 1]);
                     i++;
-                    // life-cycle of FileOutputStream is controlled by
+                    // life-cycle of OutputStream is controlled by
                     // logTo which becomes "out" and is closed in
                     // handleLogfile
-                    logTo = new PrintStream(new FileOutputStream(logFile)); //NOSONAR
+                    logTo = new PrintStream(Files.newOutputStream(logFile.toPath())); //NOSONAR
                     isLogFileUsed = true;
                 } catch (final IOException ioe) {
                     final String msg = "Cannot write on the specified log file. "
@@ -569,8 +561,8 @@
          */
         final String arg = args[argPos];
         String name = arg.substring(2, arg.length());
-        String value = null;
-        final int posEq = name.indexOf("=");
+        String value;
+        final int posEq = name.indexOf('=');
         if (posEq > 0) {
             value = name.substring(posEq + 1);
             name = name.substring(0, posEq);
@@ -656,9 +648,9 @@
     private void loadPropertyFiles() {
         for (final String filename : propertyFiles) {
             final Properties props = new Properties();
-            FileInputStream fis = null;
+            InputStream fis = null;
             try {
-                fis = new FileInputStream(filename);
+                fis = Files.newInputStream(Paths.get(filename));
                 props.load(fis);
             } catch (final IOException e) {
                 System.out.println("Could not load property file "
@@ -1153,7 +1145,7 @@
      * @return the filtered targets.
      */
     private static Map<String, Target> removeDuplicateTargets(final Map<String, Target> targets) {
-        final Map<Location, Target> locationMap = new HashMap<Location, Target>();
+        final Map<Location, Target> locationMap = new HashMap<>();
         for (final Entry<String, Target> entry : targets.entrySet()) {
             final String name = entry.getKey();
             final Target target = entry.getValue();
@@ -1168,7 +1160,7 @@
                     target.getLocation(), target); // Smallest name wins
             }
         }
-        final Map<String, Target> ret = new HashMap<String, Target>();
+        final Map<String, Target> ret = new HashMap<>();
         for (final Target target : locationMap.values()) {
             ret.put(target.getName(), target);
         }
@@ -1191,15 +1183,15 @@
         final Map<String, Target> ptargets = removeDuplicateTargets(project.getTargets());
         // split the targets in top-level and sub-targets depending
         // on the presence of a description
-        final Vector<String> topNames = new Vector<String>();
-        final Vector<String> topDescriptions = new Vector<String>();
-        final Vector<Enumeration<String>> topDependencies = new Vector<Enumeration<String>>();
-        final Vector<String> subNames = new Vector<String>();
-        final Vector<Enumeration<String>> subDependencies = new Vector<Enumeration<String>>();
+        final Vector<String> topNames = new Vector<>();
+        final Vector<String> topDescriptions = new Vector<>();
+        final Vector<Enumeration<String>> topDependencies = new Vector<>();
+        final Vector<String> subNames = new Vector<>();
+        final Vector<Enumeration<String>> subDependencies = new Vector<>();
 
         for (final Target currentTarget : ptargets.values()) {
             final String targetName = currentTarget.getName();
-            if (targetName.equals("")) {
+            if ("".equals(targetName)) {
                 continue;
             }
             final String targetDescription = currentTarget.getDescription();
@@ -1227,7 +1219,7 @@
                 "Main targets:", maxLength);
         //if there were no main targets, we list all subtargets
         //as it means nothing has a description
-        if (topNames.size() == 0) {
+        if (topNames.isEmpty()) {
             printSubTargets = true;
         }
         if (printSubTargets) {
diff --git a/src/main/org/apache/tools/ant/PathTokenizer.java b/src/main/org/apache/tools/ant/PathTokenizer.java
index 6e6bea6..2beb09c 100644
--- a/src/main/org/apache/tools/ant/PathTokenizer.java
+++ b/src/main/org/apache/tools/ant/PathTokenizer.java
@@ -127,7 +127,7 @@
         } else {
             // we are on NetWare, tokenizing is handled a little differently,
             // due to the fact that NetWare has multiple-character volume names.
-            if (token.equals(File.pathSeparator) || token.equals(":")) {
+            if (token.equals(File.pathSeparator) || ":".equals(token)) {
                 // ignore ";" and get the next token
                 token = tokenizer.nextToken().trim();
             }
@@ -138,7 +138,7 @@
 
                 // make sure we aren't going to get the path separator next
                 if (!nextToken.equals(File.pathSeparator)) {
-                    if (nextToken.equals(":")) {
+                    if (":".equals(nextToken)) {
                         if (!token.startsWith("/") && !token.startsWith("\\")
                             && !token.startsWith(".")
                             && !token.startsWith("..")) {
@@ -163,4 +163,3 @@
         return token;
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/Project.java b/src/main/org/apache/tools/ant/Project.java
index 461b89a..271421a 100644
--- a/src/main/org/apache/tools/ant/Project.java
+++ b/src/main/org/apache/tools/ant/Project.java
@@ -144,13 +144,13 @@
     private final Hashtable<String, Object> references = new AntRefTable();
 
     /** Map of id references - used for indicating broken build files */
-    private final HashMap<String, Object> idReferences = new HashMap<String, Object>();
+    private final HashMap<String, Object> idReferences = new HashMap<>();
 
     /** Name of the project's default target. */
     private String defaultTarget;
 
     /** Map from target names to targets (String to Target). */
-    private final Hashtable<String, Target> targets = new Hashtable<String, Target>();
+    private final Hashtable<String, Target> targets = new Hashtable<>();
 
     /** Set of global filters. */
     private final FilterSet globalFilterSet = new FilterSet();
@@ -193,11 +193,11 @@
 
     /** Records the latest task to be executed on a thread. */
     private final Map<Thread, Task> threadTasks
-            = Collections.synchronizedMap(new WeakHashMap<Thread, Task>());
+            = Collections.synchronizedMap(new WeakHashMap<>());
 
     /** Records the latest task to be executed on a thread group. */
     private final Map<ThreadGroup, Task> threadGroupTasks
-            = Collections.synchronizedMap(new WeakHashMap<ThreadGroup,Task>());
+            = Collections.synchronizedMap(new WeakHashMap<>());
 
     /**
      * Called to handle any input requests.
@@ -437,7 +437,7 @@
      */
     public Vector<BuildListener> getBuildListeners() {
         synchronized (listenersLock) {
-            final Vector<BuildListener> r = new Vector<BuildListener>(listeners.length);
+            final Vector<BuildListener> r = new Vector<>(listeners.length);
             for (int i = 0; i < listeners.length; i++) {
                 r.add(listeners[i]);
             }
@@ -930,8 +930,8 @@
         setPropertyInternal(MagicNames.ANT_JAVA_VERSION, javaVersion);
 
         // sanity check
-        if (!JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_1_5))  {
-            throw new BuildException("Ant cannot work on Java prior to 1.5");
+        if (!JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_1_8))  {
+            throw new BuildException("Ant cannot work on Java prior to 1.8");
         }
         log("Detected Java version: " + javaVersion + " in: "
             + System.getProperty("java.home"), MSG_VERBOSE);
@@ -1046,7 +1046,7 @@
      * @since Ant 1.8.1
      */
     public Map<String, Class<?>> getCopyOfTaskDefinitions() {
-        return new HashMap<String, Class<?>>(getTaskDefinitions());
+        return new HashMap<>(getTaskDefinitions());
     }
 
     /**
@@ -1088,7 +1088,7 @@
      * @since Ant 1.8.1
      */
     public Map<String, Class<?>> getCopyOfDataTypeDefinitions() {
-        return new HashMap<String, Class<?>>(getDataTypeDefinitions());
+        return new HashMap<>(getDataTypeDefinitions());
     }
 
     /**
@@ -1168,7 +1168,7 @@
      * @since Ant 1.8.1
      */
     public Map<String, Target> getCopyOfTargets() {
-        return new HashMap<String, Target>(targets);
+        return new HashMap<>(targets);
     }
 
     /**
@@ -1273,12 +1273,10 @@
         final Task task = getThreadTask(Thread.currentThread());
         if (task == null) {
             log(output, isWarning ? MSG_WARN : MSG_INFO);
+        } else if (isWarning) {
+            task.handleErrorOutput(output);
         } else {
-            if (isWarning) {
-                task.handleErrorOutput(output);
-            } else {
-                task.handleOutput(output);
-            }
+            task.handleOutput(output);
         }
     }
 
@@ -1297,12 +1295,11 @@
      */
     public int defaultInput(final byte[] buffer, final int offset, final int length)
         throws IOException {
-        if (defaultInputStream != null) {
-            System.out.flush();
-            return defaultInputStream.read(buffer, offset, length);
-        } else {
+        if (defaultInputStream == null) {
             throw new EOFException("No input provided for project");
         }
+        System.out.flush();
+        return defaultInputStream.read(buffer, offset, length);
     }
 
     /**
@@ -1322,9 +1319,8 @@
         final Task task = getThreadTask(Thread.currentThread());
         if (task == null) {
             return defaultInput(buffer, offset, length);
-        } else {
-            return task.handleInput(buffer, offset, length);
         }
+        return task.handleInput(buffer, offset, length);
     }
 
     /**
@@ -1342,12 +1338,10 @@
         final Task task = getThreadTask(Thread.currentThread());
         if (task == null) {
             fireMessageLogged(this, output, isError ? MSG_ERR : MSG_INFO);
+        } else if (isError) {
+            task.handleErrorFlush(output);
         } else {
-            if (isError) {
-                task.handleErrorFlush(output);
-            } else {
-                task.handleFlush(output);
-            }
+            task.handleFlush(output);
         }
     }
 
@@ -1383,7 +1377,7 @@
      */
     public void executeSortedTargets(final Vector<Target> sortedTargets)
         throws BuildException {
-        final Set<String> succeededTargets = new HashSet<String>();
+        final Set<String> succeededTargets = new HashSet<>();
         BuildException buildException = null; // first build exception
         for (final Target curtarget : sortedTargets) {
             boolean canExecute = true;
@@ -1749,9 +1743,9 @@
             return ((ProjectComponent) o).getProject();
         }
         try {
-            final Method m = o.getClass().getMethod("getProject", (Class[]) null);
-            if (Project.class == m.getReturnType()) {
-                return (Project) m.invoke(o, (Object[]) null);
+            final Method m = o.getClass().getMethod("getProject");
+            if (Project.class.equals(m.getReturnType())) {
+                return (Project) m.invoke(o);
             }
         } catch (final Exception e) {
             //too bad
@@ -1819,9 +1813,9 @@
      */
     public final Vector<Target> topoSort(final String[] roots, final Hashtable<String, Target> targetTable,
                                  final boolean returnAll) throws BuildException {
-        final Vector<Target> ret = new VectorSet<Target>();
-        final Hashtable<String, String> state = new Hashtable<String, String>();
-        final Stack<String> visiting = new Stack<String>();
+        final Vector<Target> ret = new VectorSet<>();
+        final Hashtable<String, String> state = new Hashtable<>();
+        final Stack<String> visiting = new Stack<>();
 
         // We first run a DFS based sort using each root as a starting node.
         // This creates the minimum sequence of Targets to the root node(s).
@@ -1832,7 +1826,7 @@
         // build Target.
 
         for (int i = 0; i < roots.length; i++) {
-            final String st = (state.get(roots[i]));
+            final String st = state.get(roots[i]);
             if (st == null) {
                 tsort(roots[i], targetTable, state, visiting, ret);
             } else if (st == VISITING) {
@@ -1840,7 +1834,7 @@
                     + roots[i]);
             }
         }
-        final StringBuffer buf = new StringBuffer("Build sequence for target(s)");
+        final StringBuilder buf = new StringBuilder("Build sequence for target(s)");
 
         for (int j = 0; j < roots.length; j++) {
             buf.append((j == 0) ? " `" : ", `").append(roots[j]).append('\'');
@@ -1848,7 +1842,7 @@
         buf.append(" is ").append(ret);
         log(buf.toString(), MSG_VERBOSE);
 
-        final Vector<Target> complete = (returnAll) ? ret : new Vector<Target>(ret);
+        final Vector<Target> complete = (returnAll) ? ret : new Vector<>(ret);
         for (final Enumeration<String> en = targetTable.keys(); en.hasMoreElements();) {
             final String curTarget = en.nextElement();
             final String st = state.get(curTarget);
@@ -2037,7 +2031,7 @@
      * @since Ant 1.8.1
      */
     public Map<String, Object> getCopyOfReferences() {
-        return new HashMap<String, Object>(references);
+        return new HashMap<>(references);
     }
 
     /**
@@ -2491,6 +2485,7 @@
      * @return the file resource.
      * @since Ant 1.7
      */
+    @Override
     public Resource getResource(final String name) {
         return new FileResource(getBaseDir(), name);
     }
diff --git a/src/main/org/apache/tools/ant/ProjectComponent.java b/src/main/org/apache/tools/ant/ProjectComponent.java
index 767d0c0..8c8feac 100644
--- a/src/main/org/apache/tools/ant/ProjectComponent.java
+++ b/src/main/org/apache/tools/ant/ProjectComponent.java
@@ -160,6 +160,7 @@
      * @throws CloneNotSupportedException does not happen,
      *                                    but is declared to allow subclasses to do so.
      */
+    @Override
     public Object clone() throws CloneNotSupportedException {
         ProjectComponent pc = (ProjectComponent) super.clone();
         pc.setLocation(getLocation());
diff --git a/src/main/org/apache/tools/ant/ProjectHelper.java b/src/main/org/apache/tools/ant/ProjectHelper.java
index 0c73b26..93f5576 100644
--- a/src/main/org/apache/tools/ant/ProjectHelper.java
+++ b/src/main/org/apache/tools/ant/ProjectHelper.java
@@ -146,16 +146,12 @@
         }
     }
 
-    /** Default constructor */
-    public ProjectHelper() {
-    }
-
     // -------------------- Common properties  --------------------
     // The following properties are required by import (and other tasks
     // that read build files using ProjectHelper).
 
-    private Vector<Object> importStack = new Vector<Object>();
-    private List<String[]> extensionStack = new LinkedList<String[]>();
+    private Vector<Object> importStack = new Vector<>();
+    private List<String[]> extensionStack = new LinkedList<>();
 
     /**
      *  Import stack.
@@ -181,7 +177,7 @@
         return extensionStack;
     }
 
-    private static final ThreadLocal<String> targetPrefix = new ThreadLocal<String>();
+    private static final ThreadLocal<String> targetPrefix = new ThreadLocal<>();
 
     /**
      * The prefix to prepend to imported target names.
@@ -297,7 +293,7 @@
      * @see org.apache.tools.ant.ProjectHelperRepository#getHelpers()
      */
     public static ProjectHelper getProjectHelper() {
-        return (ProjectHelper) ProjectHelperRepository.getInstance().getHelpers().next();
+        return ProjectHelperRepository.getInstance().getHelpers().next();
     }
 
     /**
@@ -501,7 +497,7 @@
      * @return      The stringified form of the ns name
      */
     public static String genComponentName(String uri, String name) {
-        if (uri == null || uri.equals("") || uri.equals(ANT_CORE_URI)) {
+        if (uri == null || "".equals(uri) || uri.equals(ANT_CORE_URI)) {
             return name;
         }
         return uri + ":" + name;
diff --git a/src/main/org/apache/tools/ant/ProjectHelperRepository.java b/src/main/org/apache/tools/ant/ProjectHelperRepository.java
index df5d1a0..cd2e7db 100644
--- a/src/main/org/apache/tools/ant/ProjectHelperRepository.java
+++ b/src/main/org/apache/tools/ant/ProjectHelperRepository.java
@@ -27,6 +27,7 @@
 import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.List;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.helper.ProjectHelper2;
 import org.apache.tools.ant.types.Resource;
@@ -53,7 +54,7 @@
     private static ProjectHelperRepository instance =
         new ProjectHelperRepository();
 
-    private List<Constructor<? extends ProjectHelper>> helpers = new ArrayList<Constructor<? extends ProjectHelper>>();
+    private List<Constructor<? extends ProjectHelper>> helpers = new ArrayList<>();
 
     private static Constructor<ProjectHelper2> PROJECTHELPER2_CONSTRUCTOR;
 
@@ -300,40 +301,15 @@
      * @return an iterator of {@link ProjectHelper}
      */
     public Iterator<ProjectHelper> getHelpers() {
-        return new ConstructingIterator(helpers.iterator());
-    }
-
-    private static class ConstructingIterator implements Iterator<ProjectHelper> {
-        private final Iterator<Constructor<? extends ProjectHelper>> nested;
-        private boolean empty = false;
-
-        ConstructingIterator(Iterator<Constructor<? extends ProjectHelper>> nested) {
-            this.nested = nested;
-        }
-
-        public boolean hasNext() {
-            return nested.hasNext() || !empty;
-        }
-
-        public ProjectHelper next() {
-            Constructor<? extends ProjectHelper> c;
-            if (nested.hasNext()) {
-                c = nested.next();
-            } else {
-                // last but not least, ant default project helper
-                empty = true;
-                c = PROJECTHELPER2_CONSTRUCTOR;
-            }
+        Stream.Builder<Constructor<? extends ProjectHelper>> b = Stream.builder();
+        helpers.forEach(b::add);
+        return b.add(PROJECTHELPER2_CONSTRUCTOR).build().map(c -> {
             try {
                 return c.newInstance();
             } catch (Exception e) {
                 throw new BuildException("Failed to invoke no-arg constructor"
-                                         + " on " + c.getName());
+                        + " on " + c.getName());
             }
-        }
-
-        public void remove() {
-            throw new UnsupportedOperationException("remove is not supported");
-        }
+        }).map(ProjectHelper.class::cast).iterator();
     }
 }
diff --git a/src/main/org/apache/tools/ant/PropertyHelper.java b/src/main/org/apache/tools/ant/PropertyHelper.java
index 9f94bda..4449fcb 100644
--- a/src/main/org/apache/tools/ant/PropertyHelper.java
+++ b/src/main/org/apache/tools/ant/PropertyHelper.java
@@ -17,7 +17,6 @@
  */
 package org.apache.tools.ant;
 
-import java.text.ParsePosition;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -30,7 +29,6 @@
 
 import org.apache.tools.ant.property.GetProperty;
 import org.apache.tools.ant.property.NullReturn;
-import org.apache.tools.ant.property.ParseNextProperty;
 import org.apache.tools.ant.property.ParseProperties;
 import org.apache.tools.ant.property.PropertyExpander;
 
@@ -184,52 +182,41 @@
         }
     };
 
-    private static final PropertyExpander DEFAULT_EXPANDER = new PropertyExpander() {
-        public String parsePropertyName(
-            String s, ParsePosition pos, ParseNextProperty notUsed) {
+    private static final PropertyExpander DEFAULT_EXPANDER =
+        (s, pos, notUsed) -> {
             int index = pos.getIndex();
             //directly check near, triggering characters:
-            if (s.length() - index >= 3
-                    && '$' == s.charAt(index) && '{' == s.charAt(index + 1)) {
+            if (s.length() - index >= 3 && '$' == s.charAt(index)
+                && '{' == s.charAt(index + 1)) {
                 int start = index + 2;
                 //defer to String.indexOf() for protracted check:
                 int end = s.indexOf('}', start);
                 if (end < 0) {
-                    throw new BuildException("Syntax error in property: "
-                            + s.substring(index));
+                    throw new BuildException(
+                        "Syntax error in property: " + s.substring(index));
                 }
                 pos.setIndex(end + 1);
-                return start == end ? "" :  s.substring(start, end);
+                return start == end ? "" : s.substring(start, end);
             }
             return null;
-        }
-    };
+        };
 
     /** dummy */
-    private static final PropertyExpander SKIP_DOUBLE_DOLLAR
-        = new PropertyExpander() {
-            // CheckStyle:LineLengthCheck OFF see too long
-            /**
-             * {@inheritDoc}
-             * @see org.apache.tools.ant.property.PropertyExpander#parsePropertyName(java.lang.String, java.text.ParsePosition, org.apache.tools.ant.PropertyHelper)
-             */
-            // CheckStyle:LineLengthCheck ON
-            public String parsePropertyName(
-                String s, ParsePosition pos, ParseNextProperty notUsed) {
-                int index = pos.getIndex();
-                if (s.length() - index >= 2) {
-                    /* check for $$; if found, advance by one--
-                     * this expander is at the bottom of the stack
-                     * and will thus be the last consulted,
-                     * so the next thing that ParseProperties will do
-                     * is advance the parse position beyond the second $
-                     */
-                    if ('$' == s.charAt(index) && '$' == s.charAt(++index)) {
-                        pos.setIndex(index);
-                    }
+    private static final PropertyExpander SKIP_DOUBLE_DOLLAR =
+        (s, pos, notUsed) -> {
+            int index = pos.getIndex();
+            if (s.length() - index >= 2) {
+                /* check for $$; if found, advance by one--
+                 * this expander is at the bottom of the stack
+                 * and will thus be the last consulted,
+                 * so the next thing that ParseProperties will do
+                 * is advance the parse position beyond the second $
+                 */
+                if ('$' == s.charAt(index) && '$' == s.charAt(++index)) {
+                    pos.setIndex(index);
                 }
-                return null;
             }
+            return null;
         };
 
     /**
@@ -248,24 +235,24 @@
 
     private Project project;
     private PropertyHelper next;
-    private final Hashtable<Class<? extends Delegate>, List<Delegate>> delegates = new Hashtable<Class<? extends Delegate>, List<Delegate>>();
+    private final Hashtable<Class<? extends Delegate>, List<Delegate>> delegates = new Hashtable<>();
 
     /** Project properties map (usually String to String). */
-    private Hashtable<String, Object> properties = new Hashtable<String, Object>();
+    private Hashtable<String, Object> properties = new Hashtable<>();
 
     /**
      * Map of "user" properties (as created in the Ant task, for example).
      * Note that these key/value pairs are also always put into the
      * project properties, so only the project properties need to be queried.
      */
-    private Hashtable<String, Object> userProperties = new Hashtable<String, Object>();
+    private Hashtable<String, Object> userProperties = new Hashtable<>();
 
     /**
      * Map of inherited "user" properties - that are those "user"
      * properties that have been created by tasks and not been set
      * from the command line or a GUI tool.
      */
-    private Hashtable<String, Object> inheritedProperties = new Hashtable<String, Object>();
+    private Hashtable<String, Object> inheritedProperties = new Hashtable<>();
 
     /**
      * Default constructor.
@@ -900,7 +887,7 @@
     public Hashtable<String, Object> getProperties() {
         //avoid concurrent modification:
         synchronized (properties) {
-            return new Hashtable<String, Object>(properties);
+            return new Hashtable<>(properties);
         }
         // There is a better way to save the context. This shouldn't
         // delegate to next, it's for backward compatibility only.
@@ -917,7 +904,7 @@
     public Hashtable<String, Object> getUserProperties() {
         //avoid concurrent modification:
         synchronized (userProperties) {
-            return new Hashtable<String, Object>(userProperties);
+            return new Hashtable<>(userProperties);
         }
     }
 
@@ -932,7 +919,7 @@
     public Hashtable<String, Object> getInheritedProperties() {
         //avoid concurrent modification:
         synchronized (inheritedProperties) {
-            return new Hashtable<String, Object>(inheritedProperties);
+            return new Hashtable<>(inheritedProperties);
         }
     }
 
@@ -982,7 +969,7 @@
         synchronized (inheritedProperties) {
             Enumeration<String> e = inheritedProperties.keys();
             while (e.hasMoreElements()) {
-                String arg = e.nextElement().toString();
+                String arg = e.nextElement();
                 if (other.getUserProperty(arg) != null) {
                     continue;
                 }
@@ -1036,7 +1023,7 @@
         int prev = 0;
         int pos;
         //search for the next instance of $ from the 'prev' position
-        while ((pos = value.indexOf("$", prev)) >= 0) {
+        while ((pos = value.indexOf('$', prev)) >= 0) {
 
             //if there was any text before this, add it as a fragment
             //TODO, this check could be modified to go if pos>prev;
@@ -1096,10 +1083,10 @@
             for (Class<? extends Delegate> key : getDelegateInterfaces(delegate)) {
                 List<Delegate> list = delegates.get(key);
                 if (list == null) {
-                    list = new ArrayList<Delegate>();
+                    list = new ArrayList<>();
                 } else {
                     //copy on write, top priority
-                    list = new ArrayList<Delegate>(list);
+                    list = new ArrayList<>(list);
                     list.remove(delegate);
                 }
                 list.add(0, delegate);
@@ -1130,7 +1117,7 @@
      * @since Ant 1.8.0
      */
     protected static Set<Class<? extends Delegate>> getDelegateInterfaces(Delegate d) {
-        final HashSet<Class<? extends Delegate>> result = new HashSet<Class<? extends Delegate>>();
+        final HashSet<Class<? extends Delegate>> result = new HashSet<>();
         Class<?> c = d.getClass();
         while (c != null) {
             Class<?>[] ifs = c.getInterfaces();
diff --git a/src/main/org/apache/tools/ant/RuntimeConfigurable.java b/src/main/org/apache/tools/ant/RuntimeConfigurable.java
index 6c4953f..a850b28 100644
--- a/src/main/org/apache/tools/ant/RuntimeConfigurable.java
+++ b/src/main/org/apache/tools/ant/RuntimeConfigurable.java
@@ -25,12 +25,11 @@
 import java.util.Hashtable;
 import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map.Entry;
+import java.util.Map;
 
 import org.apache.tools.ant.attribute.EnableAttribute;
 import org.apache.tools.ant.taskdefs.MacroDef.Attribute;
 import org.apache.tools.ant.taskdefs.MacroInstance;
-import org.apache.tools.ant.util.CollectionUtils;
 import org.xml.sax.AttributeList;
 import org.xml.sax.helpers.AttributeListImpl;
 
@@ -46,14 +45,14 @@
 
     /** Empty Hashtable. */
     private static final Hashtable<String, Object> EMPTY_HASHTABLE =
-            new Hashtable<String, Object>(0);
+            new Hashtable<>(0);
 
     /** Name of the element to configure. */
     private String elementTag = null;
 
     /** List of child element wrappers. */
     // picking ArrayList rather than List as arrayList is Serializable
-    private ArrayList<RuntimeConfigurable> children = null;
+    private List<RuntimeConfigurable> children = null;
 
     /** The element to configure. It is only used during
      * maybeConfigure.
@@ -304,17 +303,17 @@
             this.polyType = value == null ? null : value.toString();
         } else {
             if (attributeMap == null) {
-                attributeMap = new LinkedHashMap<String, Object>();
+                attributeMap = new LinkedHashMap<>();
             }
-            if (name.equalsIgnoreCase("refid") && !attributeMap.isEmpty()) {
-                LinkedHashMap<String, Object> newAttributeMap = new LinkedHashMap<String, Object>();
+            if ("refid".equalsIgnoreCase(name) && !attributeMap.isEmpty()) {
+                LinkedHashMap<String, Object> newAttributeMap = new LinkedHashMap<>();
                 newAttributeMap.put(name, value);
                 newAttributeMap.putAll(attributeMap);
                 attributeMap = newAttributeMap;
             } else {
                 attributeMap.put(name, value);
             }
-            if (name.equals("id")) {
+            if ("id".equals(name)) {
                 this.id = value == null ? null : value.toString();
             }
         }
@@ -336,7 +335,7 @@
      */
     public synchronized Hashtable<String, Object> getAttributeMap() {
         return (attributeMap == null)
-            ? EMPTY_HASHTABLE : new Hashtable<String, Object>(attributeMap);
+            ? EMPTY_HASHTABLE : new Hashtable<>(attributeMap);
     }
 
     /**
@@ -358,7 +357,7 @@
      *              Must not be <code>null</code>.
      */
     public synchronized void addChild(RuntimeConfigurable child) {
-        children = (children == null) ? new ArrayList<RuntimeConfigurable>() : children;
+        children = (children == null) ? new ArrayList<>() : children;
         children.add(child);
     }
 
@@ -380,7 +379,7 @@
      * @since Ant 1.6
      */
     public synchronized Enumeration<RuntimeConfigurable> getChildren() {
-        return (children == null) ? new CollectionUtils.EmptyEnumeration<RuntimeConfigurable>()
+        return (children == null) ? Collections.emptyEnumeration()
             : Collections.enumeration(children);
     }
 
@@ -500,7 +499,7 @@
             IntrospectionHelper.getHelper(p, target.getClass());
          ComponentHelper componentHelper = ComponentHelper.getComponentHelper(p);
         if (attributeMap != null) {
-            for (Entry<String, Object> entry : attributeMap.entrySet()) {
+            for (Map.Entry<String, Object> entry : attributeMap.entrySet()) {
                 String name = entry.getKey();
                 // skip restricted attributes such as if:set
                 AttributeComponentInformation attributeComponentInformation = isRestrictedAttribute(name, componentHelper);
@@ -512,8 +511,8 @@
                 // MacroInstance where properties are expanded for the
                 // nested sequential
                 Object attrValue;
-                if (value instanceof Evaluable) {
-                    attrValue = ((Evaluable) value).eval();
+                if (value instanceof Evaluable<?>) {
+                    attrValue = ((Evaluable<?>) value).eval();
                 } else {
                     attrValue = PropertyHelper.getPropertyHelper(p).parseProperties(value.toString());
                 }
@@ -531,7 +530,7 @@
                     ih.setAttribute(p, target, name, attrValue);
                 } catch (UnsupportedAttributeException be) {
                     // id attribute must be set externally
-                    if (name.equals("id")) {
+                    if ("id".equals(name)) {
                         // Do nothing
                     } else if (getElementTag() == null) {
                         throw be;
@@ -541,7 +540,7 @@
                             + be.getAttribute() + "\" attribute", be);
                     }
                 } catch (BuildException be) {
-                    if (name.equals("id")) {
+                    if ("id".equals(name)) {
                         // Assume that this is an not supported attribute type
                         // thrown for example by a dynamic attribute task
                         // Do nothing
@@ -593,7 +592,7 @@
 
         // Children (this is a shadow of UnknownElement#children)
         if (r.children != null) {
-            ArrayList<RuntimeConfigurable> newChildren = new ArrayList<RuntimeConfigurable>(r.children);
+            List<RuntimeConfigurable> newChildren = new ArrayList<>(r.children);
             if (children != null) {
                 newChildren.addAll(children);
             }
@@ -603,7 +602,7 @@
         // Text
         if (r.characters != null) {
             if (characters == null
-                || characters.toString().trim().length() == 0) {
+                || characters.toString().trim().isEmpty()) {
                 characters = new StringBuffer(r.characters.toString());
             }
         }
diff --git a/src/main/org/apache/tools/ant/Target.java b/src/main/org/apache/tools/ant/Target.java
index 33b8b72..a57d3b0 100644
--- a/src/main/org/apache/tools/ant/Target.java
+++ b/src/main/org/apache/tools/ant/Target.java
@@ -55,7 +55,7 @@
     private List<String> dependencies = null;
 
     /** Children of this target (tasks and data types). */
-    private List<Object> children = new ArrayList<Object>();
+    private List<Object> children = new ArrayList<>();
 
     /** Since Ant 1.6.2 */
     private Location location = Location.UNKNOWN_LOCATION;
@@ -145,7 +145,7 @@
     public static List<String> parseDepends(String depends,
                                                 String targetName,
                                                 String attributeName) {
-        List<String> list = new ArrayList<String>();
+        List<String> list = new ArrayList<>();
         if (depends.length() > 0) {
             StringTokenizer tok =
                 new StringTokenizer(depends, ",", true);
@@ -225,7 +225,7 @@
      * @return an array of the tasks currently within this target
      */
     public Task[] getTasks() {
-        List<Task> tasks = new ArrayList<Task>(children.size());
+        List<Task> tasks = new ArrayList<>(children.size());
         for (Object o : children) {
             if (o instanceof Task) {
                 tasks.add((Task) o);
@@ -242,7 +242,7 @@
      */
     public void addDependency(String dependency) {
         if (dependencies == null) {
-            dependencies = new ArrayList<String>(2);
+            dependencies = new ArrayList<>(2);
         }
         dependencies.add(dependency);
     }
@@ -253,8 +253,8 @@
      * @return an enumeration of the dependencies of this target (enumeration of String)
      */
     public Enumeration<String> getDependencies() {
-        return Collections
-                .enumeration(dependencies == null ? Collections.<String> emptyList() : dependencies);
+        return dependencies == null ? Collections.emptyEnumeration()
+            : Collections.enumeration(dependencies);
     }
 
     /**
@@ -284,7 +284,12 @@
      */
     public void setIf(String property) {
         ifString = property == null ? "" : property;
-        setIf(new IfStringCondition(ifString));
+        setIf(() -> {
+            PropertyHelper propertyHelper =
+                PropertyHelper.getPropertyHelper(getProject());
+            Object o = propertyHelper.parseProperties(ifString);
+            return propertyHelper.testIfCondition(o);
+        });
     }
 
     /**
@@ -332,7 +337,12 @@
      */
     public void setUnless(String property) {
         unlessString = property == null ? "" : property;
-        setUnless(new UnlessStringCondition(unlessString));
+        setUnless(() -> {
+            PropertyHelper propertyHelper =
+                PropertyHelper.getPropertyHelper(getProject());
+            Object o = propertyHelper.parseProperties(unlessString);
+            return !propertyHelper.testUnlessCondition(o);
+        });
     }
 
     /**
@@ -392,6 +402,7 @@
      * @return the name of this target, or <code>null</code> if the
      *         name has not been set yet.
      */
+    @Override
     public String toString() {
         return name;
     }
@@ -493,42 +504,4 @@
             children.set(index, o);
         }
     }
-
-    /**
-     * Condition evaluating the 'if' attribute with the PropertyHelper.
-     */
-    private class IfStringCondition implements Condition {
-
-        private String condition;
-
-        public IfStringCondition(String condition) {
-            this.condition = condition;
-        }
-
-        public boolean eval() throws BuildException {
-            PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(getProject());
-            Object o = propertyHelper.parseProperties(condition);
-            return propertyHelper.testIfCondition(o);
-        }
-
-    }
-
-    /**
-     * Condition evaluating the 'unless' attribute with the PropertyHelper.
-     */
-    private class UnlessStringCondition implements Condition {
-
-        private String condition;
-
-        public UnlessStringCondition(String condition) {
-            this.condition = condition;
-        }
-
-        public boolean eval() throws BuildException {
-            PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(getProject());
-            Object o = propertyHelper.parseProperties(condition);
-            return !propertyHelper.testUnlessCondition(o);
-        }
-
-    }
 }
diff --git a/src/main/org/apache/tools/ant/Task.java b/src/main/org/apache/tools/ant/Task.java
index 0d08eb0..bdd2337 100644
--- a/src/main/org/apache/tools/ant/Task.java
+++ b/src/main/org/apache/tools/ant/Task.java
@@ -81,10 +81,6 @@
      */
     private boolean invalid;
 
-    /** Sole constructor. */
-    public Task() {
-    }
-
     /**
      * Sets the target container of this task.
      *
@@ -197,12 +193,10 @@
      * @exception BuildException if the task cannot be configured.
      */
     public void maybeConfigure() throws BuildException {
-        if (!invalid) {
-            if (wrapper != null) {
-                wrapper.maybeConfigure(getProject());
-            }
-        } else {
+        if (invalid) {
             getReplacement();
+        } else if (wrapper != null) {
+            wrapper.maybeConfigure(getProject());
         }
     }
 
@@ -290,10 +284,10 @@
      *                 be logged.
      */
     public void log(String msg, int msgLevel) {
-        if (getProject() != null) {
-            getProject().log(this, msg, msgLevel);
-        } else {
+        if (getProject() == null) {
             super.log(msg, msgLevel);
+        } else {
+            getProject().log(this, msg, msgLevel);
         }
     }
 
@@ -323,10 +317,10 @@
      * @since 1.7
      */
     public void log(String msg, Throwable t, int msgLevel) {
-        if (getProject() != null) {
-            getProject().log(this, msg, t, msgLevel);
-        } else {
+        if (getProject() == null) {
             super.log(msg, msgLevel);
+        } else {
+            getProject().log(this, msg, t, msgLevel);
         }
     }
 
@@ -340,7 +334,11 @@
      * is still fired, but with the exception as the cause.
      */
     public final void perform() {
-        if (!invalid) {
+        if (invalid) {
+            UnknownElement ue = getReplacement();
+            Task task = ue.getTask();
+            task.perform();
+        } else {
             getProject().fireTaskStarted(this);
             Throwable reason = null;
             try {
@@ -363,10 +361,6 @@
             } finally {
                 getProject().fireTaskFinished(this, reason);
             }
-        } else {
-            UnknownElement ue = getReplacement();
-            Task task = ue.getTask();
-            task.perform();
         }
     }
 
diff --git a/src/main/org/apache/tools/ant/TaskAdapter.java b/src/main/org/apache/tools/ant/TaskAdapter.java
index d4d8c32..567bc81 100644
--- a/src/main/org/apache/tools/ant/TaskAdapter.java
+++ b/src/main/org/apache/tools/ant/TaskAdapter.java
@@ -81,7 +81,7 @@
             // don't have to check for interface, since then
             // taskClass would be abstract too.
             try {
-                final Method executeM = taskClass.getMethod("execute", (Class[]) null);
+                final Method executeM = taskClass.getMethod("execute");
                 // don't have to check for public, since
                 // getMethod finds public method only.
                 // don't have to check for abstract, since then
@@ -122,10 +122,10 @@
      */
     public void execute() throws BuildException {
         try {
-            Method setLocationM = proxy.getClass().getMethod(
-                "setLocation", new Class[] {Location.class});
+            Method setLocationM =
+                proxy.getClass().getMethod("setLocation", Location.class);
             if (setLocationM != null) {
-                setLocationM.invoke(proxy, new Object[] {getLocation()});
+                setLocationM.invoke(proxy, getLocation());
             }
         } catch (NoSuchMethodException e) {
             // ignore this if the class being used as a task does not have
@@ -137,10 +137,10 @@
         }
 
         try {
-            Method setProjectM = proxy.getClass().getMethod(
-                "setProject", new Class[] {Project.class});
+            Method setProjectM =
+                proxy.getClass().getMethod("setProject", Project.class);
             if (setProjectM != null) {
-                setProjectM.invoke(proxy, new Object[] {getProject()});
+                setProjectM.invoke(proxy, getProject());
             }
         } catch (NoSuchMethodException e) {
             // ignore this if the class being used as a task does not have
diff --git a/src/main/org/apache/tools/ant/TaskConfigurationChecker.java b/src/main/org/apache/tools/ant/TaskConfigurationChecker.java
index 9a52043..942b2dc 100644
--- a/src/main/org/apache/tools/ant/TaskConfigurationChecker.java
+++ b/src/main/org/apache/tools/ant/TaskConfigurationChecker.java
@@ -55,7 +55,7 @@
 public class TaskConfigurationChecker {
 
     /** List of all collected error messages. */
-    private List<String> errors = new ArrayList<String>();
+    private List<String> errors = new ArrayList<>();
 
     /** Task for which the configuration should be checked. */
     private final Task task;
@@ -94,8 +94,7 @@
      */
     public void checkErrors() throws BuildException {
         if (!errors.isEmpty()) {
-            StringBuffer sb = new StringBuffer();
-            sb.append("Configuration error on <");
+            StringBuilder sb = new StringBuilder("Configuration error on <");
             sb.append(task.getTaskName());
             sb.append(">:");
             sb.append(System.getProperty("line.separator"));
diff --git a/src/main/org/apache/tools/ant/UnknownElement.java b/src/main/org/apache/tools/ant/UnknownElement.java
index f0a274e..8a73847 100644
--- a/src/main/org/apache/tools/ant/UnknownElement.java
+++ b/src/main/org/apache/tools/ant/UnknownElement.java
@@ -24,6 +24,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 import org.apache.tools.ant.taskdefs.PreSetDef;
 
@@ -234,10 +235,8 @@
         throws IOException {
         if (realThing instanceof Task) {
             return ((Task) realThing).handleInput(buffer, offset, length);
-        } else {
-            return super.handleInput(buffer, offset, length);
         }
-
+        return super.handleInput(buffer, offset, length);
     }
 
     /**
@@ -311,7 +310,7 @@
      */
     public void addChild(UnknownElement child) {
         if (children == null) {
-            children = new ArrayList<UnknownElement>();
+            children = new ArrayList<>();
         }
         children.add(child);
     }
@@ -341,7 +340,6 @@
         Class<?> parentClass = parent.getClass();
         IntrospectionHelper ih = IntrospectionHelper.getHelper(getProject(), parentClass);
 
-
         if (children != null) {
             Iterator<UnknownElement> it = children.iterator();
             for (int i = 0; it.hasNext(); i++) {
@@ -400,7 +398,7 @@
         // Do the runtime
         getWrapper().applyPreSet(u.getWrapper());
         if (u.children != null) {
-            List<UnknownElement> newChildren = new ArrayList<UnknownElement>(u.children);
+            List<UnknownElement> newChildren = new ArrayList<>(u.children);
             if (children != null) {
                 newChildren.addAll(children);
             }
@@ -505,7 +503,6 @@
      * @return the name to use in logging messages.
      */
     public String getTaskName() {
-        //return elementName;
         return realThing == null
             || !(realThing instanceof Task) ? super.getTaskName()
                                             : ((Task) realThing).getTaskName();
@@ -611,7 +608,7 @@
         }
         UnknownElement other = (UnknownElement) obj;
         // Are the names the same ?
-        if (!equalsString(elementName, other.elementName)) {
+        if (!Objects.equals(elementName, other.elementName)) {
             return false;
         }
         if (!namespace.equals(other.namespace)) {
@@ -636,7 +633,7 @@
         // Are the sub elements the same ?
         final int childrenSize = children == null ? 0 : children.size();
         if (childrenSize == 0) {
-            return other.children == null || other.children.size() == 0;
+            return other.children == null || other.children.isEmpty();
         }
         if (other.children == null) {
             return false;
@@ -654,10 +651,6 @@
         return true;
     }
 
-    private static boolean equalsString(String a, String b) {
-        return (a == null) ? (b == null) : a.equals(b);
-    }
-
     /**
      * Make a copy of the unknown element and set it in the new project.
      * @param newProject the project to create the UE in.
diff --git a/src/main/org/apache/tools/ant/XmlLogger.java b/src/main/org/apache/tools/ant/XmlLogger.java
index 51d4776..75af5f5 100644
--- a/src/main/org/apache/tools/ant/XmlLogger.java
+++ b/src/main/org/apache/tools/ant/XmlLogger.java
@@ -17,12 +17,13 @@
  */
 package org.apache.tools.ant;
 
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintStream;
 import java.io.Writer;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.Stack;
@@ -31,7 +32,6 @@
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.tools.ant.util.DOMElementWriter;
-import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.StringUtils;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -108,16 +108,16 @@
     private Document doc = builder.newDocument();
 
     /** Mapping for when tasks started (Task to TimedElement). */
-    private Hashtable<Task, TimedElement> tasks = new Hashtable<Task, TimedElement>();
+    private Hashtable<Task, TimedElement> tasks = new Hashtable<>();
 
     /** Mapping for when targets started (Target to TimedElement). */
-    private Hashtable<Target, TimedElement> targets = new Hashtable<Target, XmlLogger.TimedElement>();
+    private Hashtable<Target, TimedElement> targets = new Hashtable<>();
 
     /**
      * Mapping of threads to stacks of elements
      * (Thread to Stack of TimedElement).
      */
-    private Hashtable<Thread, Stack<TimedElement>> threadStacks = new Hashtable<Thread, Stack<TimedElement>>();
+    private Hashtable<Thread, Stack<TimedElement>> threadStacks = new Hashtable<>();
 
     /**
      * When the build started.
@@ -133,23 +133,20 @@
         private long startTime;
         /** Element created at the start time. */
         private Element element;
+
+        @Override
         public String toString() {
             return element.getTagName() + ":" + element.getAttribute("name");
         }
     }
 
     /**
-     *  Constructs a new BuildListener that logs build events to an XML file.
-     */
-    public XmlLogger() {
-    }
-
-    /**
      * Fired when the build starts, this builds the top-level element for the
      * document and remembers the time of the start of the build.
      *
      * @param event Ignored.
      */
+    @Override
     public void buildStarted(BuildEvent event) {
         buildElement = new TimedElement();
         buildElement.startTime = System.currentTimeMillis();
@@ -163,6 +160,7 @@
      * @param event An event with any relevant extra information.
      *              Will not be <code>null</code>.
      */
+    @Override
     public void buildFinished(BuildEvent event) {
         long totalTime = System.currentTimeMillis() - buildElement.startTime;
         buildElement.element.setAttribute(TIME_ATTR, DefaultLogger.formatTime(totalTime));
@@ -179,25 +177,19 @@
         }
         String outFilename = getProperty(event, "XmlLogger.file", "log.xml");
         String xslUri = getProperty(event, "ant.XmlLogger.stylesheet.uri", "log.xsl");
-        Writer out = null;
-        try {
-            // specify output in UTF8 otherwise accented characters will blow
-            // up everything
-            OutputStream stream = outStream;
-            if (stream == null) {
-                stream = new FileOutputStream(outFilename);
-            }
-            out = new OutputStreamWriter(stream, "UTF8");
+
+        try (OutputStream stream =
+            outStream == null ? Files.newOutputStream(Paths.get(outFilename)) : outStream;
+                Writer out = new OutputStreamWriter(stream, "UTF8")) {
             out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
             if (xslUri.length() > 0) {
-                out.write("<?xml-stylesheet type=\"text/xsl\" href=\"" + xslUri + "\"?>\n\n");
+                out.write("<?xml-stylesheet type=\"text/xsl\" href=\"" + xslUri
+                    + "\"?>\n\n");
             }
             new DOMElementWriter().write(buildElement.element, out, 0, "\t");
             out.flush();
         } catch (IOException exc) {
             throw new BuildException("Unable to write log file", exc);
-        } finally {
-            FileUtils.close(out);
         }
         buildElement = null;
     }
@@ -217,7 +209,7 @@
     private Stack<TimedElement> getStack() {
         Stack<TimedElement> threadStack = threadStacks.get(Thread.currentThread());
         if (threadStack == null) {
-            threadStack = new Stack<TimedElement>();
+            threadStack = new Stack<>();
             threadStacks.put(Thread.currentThread(), threadStack);
         }
         /* For debugging purposes uncomment:
@@ -235,6 +227,7 @@
      * @param event An event with any relevant extra information.
      *              Will not be <code>null</code>.
      */
+    @Override
     public void targetStarted(BuildEvent event) {
         Target target = event.getTarget();
         TimedElement targetElement = new TimedElement();
@@ -252,6 +245,7 @@
      * @param event An event with any relevant extra information.
      *              Will not be <code>null</code>.
      */
+    @Override
     public void targetFinished(BuildEvent event) {
         Target target = event.getTarget();
         TimedElement targetElement = targets.get(target);
@@ -289,6 +283,7 @@
      * @param event An event with any relevant extra information.
      *              Will not be <code>null</code>.
      */
+    @Override
     public void taskStarted(BuildEvent event) {
         TimedElement taskElement = new TimedElement();
         taskElement.startTime = System.currentTimeMillis();
@@ -312,6 +307,7 @@
      * @param event An event with any relevant extra information.
      *              Will not be <code>null</code>.
      */
+    @Override
     public void taskFinished(BuildEvent event) {
         Task task = event.getTask();
         TimedElement taskElement = tasks.get(task);
@@ -354,10 +350,9 @@
         }
         for (Enumeration<Task> e = tasks.keys(); e.hasMoreElements();) {
             Task key = e.nextElement();
-            if (key instanceof UnknownElement) {
-                if (((UnknownElement) key).getTask() == task) {
-                    return tasks.get(key);
-                }
+            if (key instanceof UnknownElement
+                && ((UnknownElement) key).getTask() == task) {
+                return tasks.get(key);
             }
         }
         return null;
@@ -371,6 +366,7 @@
      * @param event An event with any relevant extra information.
      *              Will not be <code>null</code>.
      */
+    @Override
     public void messageLogged(BuildEvent event) {
         int priority = event.getPriority();
         if (priority > msgOutputLevel) {
@@ -378,7 +374,7 @@
         }
         Element messageElement = doc.createElement(MESSAGE_TAG);
 
-        String name = "debug";
+        String name;
         switch (priority) {
             case Project.MSG_ERR:
                 name = "error";
@@ -432,6 +428,7 @@
      *        see {@link org.apache.tools.ant.Project#MSG_ERR Project}
      *        class for level definitions
      */
+    @Override
     public void setMessageOutputLevel(int level) {
         msgOutputLevel = level;
     }
@@ -442,6 +439,7 @@
      *
      * @param output the output PrintStream.
      */
+    @Override
     public void setOutputPrintStream(PrintStream output) {
         this.outStream = new PrintStream(output, true);
     }
@@ -452,6 +450,7 @@
      * @param emacsMode true if logger should produce emacs compatible
      *        output
      */
+    @Override
     public void setEmacsMode(boolean emacsMode) {
     }
 
@@ -462,6 +461,7 @@
      *
      * @param err the stream we are going to ignore.
      */
+    @Override
     public void setErrorPrintStream(PrintStream err) {
     }
 
diff --git a/src/main/org/apache/tools/ant/attribute/BaseIfAttribute.java b/src/main/org/apache/tools/ant/attribute/BaseIfAttribute.java
index c2ec08a..f0b03d9 100644
--- a/src/main/org/apache/tools/ant/attribute/BaseIfAttribute.java
+++ b/src/main/org/apache/tools/ant/attribute/BaseIfAttribute.java
@@ -19,6 +19,7 @@
 package org.apache.tools.ant.attribute;
 
 import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.Map;
 
@@ -67,18 +68,19 @@
      * @param el the element this attribute is in.
      * @return a map of attributes.
      */
-    protected Map getParams(UnknownElement el) {
-        Map ret = new HashMap();
+    protected Map<String, String> getParams(UnknownElement el) {
+        Map<String, String> ret = new HashMap<>();
         RuntimeConfigurable rc = el.getWrapper();
-        Map attributes = rc.getAttributeMap(); // This does a copy!
-        for (Iterator i = attributes.entrySet().iterator(); i.hasNext();) {
-            Map.Entry entry = (Map.Entry) i.next();
-            String key = (String) entry.getKey();
+        Hashtable<String, Object> attributes = rc.getAttributeMap(); // This does a copy!
+        for (Iterator<Map.Entry<String, Object>> i =
+            attributes.entrySet().iterator(); i.hasNext();) {
+            Map.Entry<String, Object> entry = i.next();
+            String key = entry.getKey();
             String value = (String) entry.getValue();
             if (key.startsWith("ant-attribute:param")) {
                 int pos = key.lastIndexOf(':');
                 ret.put(key.substring(pos + 1),
-                        el.getProject().replaceProperties(value));
+                    el.getProject().replaceProperties(value));
             }
         }
         return ret;
diff --git a/src/main/org/apache/tools/ant/dispatch/DispatchTask.java b/src/main/org/apache/tools/ant/dispatch/DispatchTask.java
index b88b873..4d19c3d 100644
--- a/src/main/org/apache/tools/ant/dispatch/DispatchTask.java
+++ b/src/main/org/apache/tools/ant/dispatch/DispatchTask.java
@@ -36,6 +36,7 @@
      * Get the action parameter name.
      * @return the <code>String</code> "action" by default (can be overridden).
      */
+    @Override
     public String getActionParameterName() {
         return "action";
     }
diff --git a/src/main/org/apache/tools/ant/dispatch/DispatchUtils.java b/src/main/org/apache/tools/ant/dispatch/DispatchUtils.java
index 62dd88f..7a840d1 100644
--- a/src/main/org/apache/tools/ant/dispatch/DispatchUtils.java
+++ b/src/main/org/apache/tools/ant/dispatch/DispatchUtils.java
@@ -98,12 +98,12 @@
                 }
             } else {
                 Method executeM = null;
-                executeM = task.getClass().getMethod(methodName, new Class[0]);
+                executeM = task.getClass().getMethod(methodName);
                 if (executeM == null) {
                     throw new BuildException("No public " + methodName + "() in "
                         + task.getClass());
                 }
-                executeM.invoke(task, (Object[]) null);
+                executeM.invoke(task);
                 if (task instanceof UnknownElement) {
                     ((UnknownElement) task).setRealThing(null);
                 }
diff --git a/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java b/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java
index 5d144c2..4e836ef 100644
--- a/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java
+++ b/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java
@@ -223,7 +223,7 @@
     /**
      * Set the regular expression as an attribute.
      * @param pattern String
-     * @since Ant 1.9.10
+     * @since Ant 1.10.2
      */
     public void setRegexp(String pattern) {
         RegularExpression regexp = new RegularExpression();
diff --git a/src/main/org/apache/tools/ant/filters/Native2AsciiFilter.java b/src/main/org/apache/tools/ant/filters/Native2AsciiFilter.java
index 2e764ae..5631534 100644
--- a/src/main/org/apache/tools/ant/filters/Native2AsciiFilter.java
+++ b/src/main/org/apache/tools/ant/filters/Native2AsciiFilter.java
@@ -39,6 +39,7 @@
         this.reverse = reverse;
     }
 
+    @Override
     public String filter(String line) {
         return reverse
             ? Native2AsciiUtils.ascii2native(line)
diff --git a/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java b/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
index f176c33..5294f36 100644
--- a/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
+++ b/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
@@ -23,9 +23,13 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
-import java.util.Iterator;
+import java.util.Collection;
 import java.util.List;
+import java.util.Optional;
 import java.util.Vector;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.AntClassLoader;
 import org.apache.tools.ant.BuildException;
@@ -34,7 +38,6 @@
 import org.apache.tools.ant.filters.ChainableReader;
 import org.apache.tools.ant.types.AntFilterReader;
 import org.apache.tools.ant.types.FilterChain;
-import org.apache.tools.ant.types.Parameter;
 import org.apache.tools.ant.types.Parameterizable;
 import org.apache.tools.ant.types.Path;
 import org.apache.tools.ant.util.FileUtils;
@@ -44,6 +47,37 @@
  *
  */
 public final class ChainReaderHelper {
+    /**
+     * Created type.
+     */
+    public class ChainReader extends FilterReader {
+
+        private List<AntClassLoader> cleanupLoaders;
+
+        private ChainReader(Reader in, List<AntClassLoader> cleanupLoaders) {
+            super(in);
+            this.cleanupLoaders = cleanupLoaders;
+        }
+
+        public String readFully() throws IOException {
+            return ChainReaderHelper.this.readFully(this);
+        }
+
+        @Override
+        public void close() throws IOException {
+            cleanUpClassLoaders(cleanupLoaders);
+            super.close();
+        }
+
+        @Override
+        protected void finalize() throws Throwable {
+            try {
+                close();
+            } finally {
+                super.finalize();
+            }
+        }
+    }
 
     // default buffer size
     private static final int DEFAULT_BUFFER_SIZE = 8192;
@@ -61,7 +95,7 @@
     /**
      * Chain of filters
      */
-    public Vector<FilterChain> filterChains = new Vector<FilterChain>();
+    public Vector<FilterChain> filterChains = new Vector<>();
 
     /** The Ant project */
     private Project project = null;
@@ -69,7 +103,25 @@
     // CheckStyle:VisibilityModifier ON
 
     /**
-     * Sets the primary reader
+     * Default constructor.
+     */
+    public ChainReaderHelper() {
+    }
+
+    /**
+     * Convenience constructor.
+     * @param project ditto
+     * @param primaryReader ditto
+     * @param filterChains ditto
+     */
+    public ChainReaderHelper(Project project, Reader primaryReader,
+        Iterable<FilterChain> filterChains) {
+        withProject(project).withPrimaryReader(primaryReader)
+            .withFilterChains(filterChains);
+    }
+
+    /**
+     * Sets the primary {@link Reader}
      * @param rdr the reader object
      */
     public void setPrimaryReader(Reader rdr) {
@@ -77,6 +129,16 @@
     }
 
     /**
+     * Fluent primary {@link Reader} mutator.
+     * @param rdr Reader
+     * @return {@code this}
+     */
+    public ChainReaderHelper withPrimaryReader(Reader rdr) {
+        setPrimaryReader(rdr);
+        return this;
+    }
+
+    /**
      * Set the project to work with
      * @param project the current project
      */
@@ -85,6 +147,16 @@
     }
 
     /**
+     * Fluent {@link Project} mutator.
+     * @param project ditto
+     * @return {@code this}
+     */
+    public ChainReaderHelper withProject(Project project) {
+        setProject(project);
+        return this;
+    }
+
+    /**
      * Get the project
      *
      * @return the current project
@@ -103,6 +175,16 @@
     }
 
     /**
+     * Fluent buffer size mutator.
+     * @param size ditto
+     * @return {@code this}
+     */
+    public ChainReaderHelper withBufferSize(int size) {
+        setBufferSize(size);
+        return this;
+    }
+
+    /**
      * Sets the collection of filter reader sets
      *
      * @param fchain the filter chains collection
@@ -112,42 +194,56 @@
     }
 
     /**
+     * Fluent {@code filterChains} mutator.
+     * @param filterChains ditto
+     * @return {@code this}
+     */
+    public ChainReaderHelper withFilterChains(Iterable<FilterChain> filterChains) {
+        final Vector<FilterChain> fcs;
+        if (filterChains instanceof Vector<?>) {
+            fcs = (Vector<FilterChain>) filterChains;
+        } else {
+            fcs = new Vector<>();
+            filterChains.forEach(fcs::add);
+        }
+        setFilterChains(fcs);
+        return this;
+    }
+
+    /**
+     * Fluent mechanism to apply some {@link Consumer}.
+     * @param consumer ditto
+     * @return {@code this}
+     */
+    public ChainReaderHelper with(Consumer<ChainReaderHelper> consumer) {
+        consumer.accept(this);
+        return this;
+    }
+
+    /**
      * Assemble the reader
      * @return the assembled reader
      * @exception BuildException if an error occurs
      */
-    public Reader getAssembledReader() throws BuildException {
+    public ChainReader getAssembledReader() throws BuildException {
         if (primaryReader == null) {
             throw new BuildException("primaryReader must not be null.");
         }
 
         Reader instream = primaryReader;
-        final int filterReadersCount = filterChains.size();
-        final Vector<Object> finalFilters = new Vector<Object>();
-        final ArrayList<AntClassLoader> classLoadersToCleanUp =
-            new ArrayList<AntClassLoader>();
+        final List<AntClassLoader> classLoadersToCleanUp = new ArrayList<>();
 
-        for (int i = 0; i < filterReadersCount; i++) {
-            final FilterChain filterchain =
-                filterChains.elementAt(i);
-            final Vector<Object> filterReaders = filterchain.getFilterReaders();
-            final int readerCount = filterReaders.size();
-            for (int j = 0; j < readerCount; j++) {
-                finalFilters.addElement(filterReaders.elementAt(j));
-            }
-        }
+        final List<Object> finalFilters =
+            filterChains.stream().map(FilterChain::getFilterReaders)
+                .flatMap(Collection::stream).collect(Collectors.toList());
 
-        final int filtersCount = finalFilters.size();
-
-        if (filtersCount > 0) {
+        if (!finalFilters.isEmpty()) {
             boolean success = false;
             try {
-                for (int i = 0; i < filtersCount; i++) {
-                    Object o = finalFilters.elementAt(i);
-
+                for (Object o : finalFilters) {
                     if (o instanceof AntFilterReader) {
                         instream =
-                            expandReader((AntFilterReader) finalFilters.elementAt(i),
+                            expandReader((AntFilterReader) o,
                                          instream, classLoadersToCleanUp);
                     } else if (o instanceof ChainableReader) {
                         setProjectOnObject(o);
@@ -157,26 +253,12 @@
                 }
                 success = true;
             } finally {
-                if (!success && classLoadersToCleanUp.size() > 0) {
+                if (!(success || classLoadersToCleanUp.isEmpty())) {
                     cleanUpClassLoaders(classLoadersToCleanUp);
                 }
             }
         }
-        final Reader finalReader = instream;
-        return classLoadersToCleanUp.size() == 0 ? finalReader
-            : new FilterReader(finalReader) {
-                    public void close() throws IOException {
-                        FileUtils.close(in);
-                        cleanUpClassLoaders(classLoadersToCleanUp);
-                    }
-                    protected void finalize() throws Throwable {
-                        try {
-                            close();
-                        } finally {
-                            super.finalize();
-                        }
-                    }
-                };
+        return new ChainReader(instream, classLoadersToCleanUp);
     }
 
     /**
@@ -199,9 +281,7 @@
      * Deregisters Classloaders from the project so GC can remove them later.
      */
     private static void cleanUpClassLoaders(List<AntClassLoader> loaders) {
-        for (Iterator<AntClassLoader> it = loaders.iterator(); it.hasNext();) {
-            it.next().cleanup();
-        }
+        loaders.forEach(AntClassLoader::cleanup);
     }
 
     /**
@@ -211,8 +291,7 @@
      * @return the contents of the file as a string
      * @exception IOException if an error occurs
      */
-    public String readFully(Reader rdr)
-        throws IOException {
+    public String readFully(Reader rdr) throws IOException {
         return FileUtils.readFully(rdr, bufferSize);
     }
 
@@ -227,57 +306,45 @@
                                 final List<AntClassLoader> classLoadersToCleanUp) {
         final String className = filter.getClassName();
         final Path classpath = filter.getClasspath();
-        final Project pro = filter.getProject();
         if (className != null) {
             try {
-                Class<?> clazz = null;
-                if (classpath == null) {
-                    clazz = Class.forName(className);
-                } else {
-                    AntClassLoader al = pro.createClassLoader(classpath);
-                    classLoadersToCleanUp.add(al);
-                    clazz = Class.forName(className, true, al);
+                Class<? extends FilterReader> clazz;
+                try {
+                    if (classpath == null) {
+                        clazz = Class.forName(className)
+                            .asSubclass(FilterReader.class);
+                    } else {
+                        AntClassLoader al =
+                            filter.getProject().createClassLoader(classpath);
+                        classLoadersToCleanUp.add(al);
+                        clazz = Class.forName(className, true, al)
+                            .asSubclass(FilterReader.class);
+                    }
+                } catch (ClassCastException ex) {
+                    throw new BuildException("%s does not extend %s", className,
+                        FilterReader.class.getName());
                 }
-                if (clazz != null) {
-                    if (!FilterReader.class.isAssignableFrom(clazz)) {
-                        throw new BuildException(className + " does not extend"
-                                                 + " java.io.FilterReader");
-                    }
-                    final Constructor<?>[] constructors = clazz.getConstructors();
-                    int j = 0;
-                    boolean consPresent = false;
-                    for (; j < constructors.length; j++) {
-                        Class<?>[] types = constructors[j].getParameterTypes();
-                        if (types.length == 1
-                            && types[0].isAssignableFrom(Reader.class)) {
-                            consPresent = true;
-                            break;
-                        }
-                    }
-                    if (!consPresent) {
-                        throw new BuildException(className + " does not define"
-                                                 + " a public constructor"
-                                                 + " that takes in a Reader"
-                                                 + " as its single argument.");
-                    }
-                    final Reader[] rdr = {ancestor};
-                    Reader instream =
-                        (Reader) constructors[j].newInstance((Object[]) rdr);
-                    setProjectOnObject(instream);
-                    if (Parameterizable.class.isAssignableFrom(clazz)) {
-                        final Parameter[] params = filter.getParams();
-                        ((Parameterizable) instream).setParameters(params);
-                    }
-                    return instream;
+                Optional<Constructor<?>> ctor =
+                    Stream.of(clazz.getConstructors())
+                        .filter(c -> c.getParameterCount() == 1
+                            && c.getParameterTypes()[0]
+                                .isAssignableFrom(Reader.class))
+                        .findFirst();
+
+                Object instream = ctor
+                    .orElseThrow(() -> new BuildException(
+                        "%s does not define a public constructor that takes in a %s as its single argument.",
+                        className, Reader.class.getSimpleName()))
+                    .newInstance(ancestor);
+
+                setProjectOnObject(instream);
+                if (Parameterizable.class.isAssignableFrom(clazz)) {
+                    ((Parameterizable) instream).setParameters(filter.getParams());
                 }
-            } catch (final ClassNotFoundException cnfe) {
-                throw new BuildException(cnfe);
-            } catch (final InstantiationException ie) {
-                throw new BuildException(ie);
-            } catch (final IllegalAccessException iae) {
-                throw new BuildException(iae);
-            } catch (final InvocationTargetException ite) {
-                throw new BuildException(ite);
+                return (Reader) instream;
+            } catch (ClassNotFoundException | InstantiationException
+                    | IllegalAccessException | InvocationTargetException ex) {
+                throw new BuildException(ex);
             }
         }
         // Ant 1.7.1 and earlier ignore <filterreader> without a
diff --git a/src/main/org/apache/tools/ant/helper/AntXMLContext.java b/src/main/org/apache/tools/ant/helper/AntXMLContext.java
index 393ad5c..a6b1ed1 100644
--- a/src/main/org/apache/tools/ant/helper/AntXMLContext.java
+++ b/src/main/org/apache/tools/ant/helper/AntXMLContext.java
@@ -91,7 +91,7 @@
     /** The stack of RuntimeConfigurable2 wrapping the
         objects.
     */
-    private Vector<RuntimeConfigurable> wStack = new Vector<RuntimeConfigurable>();
+    private Vector<RuntimeConfigurable> wStack = new Vector<>();
 
     /**
      * Indicates whether the project tag attributes are to be ignored
diff --git a/src/main/org/apache/tools/ant/helper/ProjectHelper2.java b/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
index 34dfde3..61a696c 100644
--- a/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
+++ b/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
@@ -18,13 +18,13 @@
 package org.apache.tools.ant.helper;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.URL;
 import java.net.URLConnection;
+import java.nio.file.Files;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Map;
@@ -88,6 +88,7 @@
      *
      * @since Ant 1.8.0
      */
+    @Override
     public boolean canParseAntlibDescriptor(Resource resource) {
         return true;
     }
@@ -102,6 +103,7 @@
      *
      * @since Ant 1.8.0
      */
+    @Override
     public UnknownElement parseAntlibDescriptor(Project containingProject,
                                                 Resource resource) {
         URLProvider up = resource.as(URLProvider.class);
@@ -143,6 +145,7 @@
      * @param source  the xml source
      * @exception BuildException if an error occurs
      */
+    @Override
     public void parse(Project project, Object source) throws BuildException {
         getImportStack().addElement(source);
         AntXMLContext context = null;
@@ -247,7 +250,7 @@
             String uri = null;
             if (buildFile != null) {
                 uri = FILE_UTILS.toURI(buildFile.getAbsolutePath());
-                inputStream = new FileInputStream(buildFile);
+                inputStream = Files.newInputStream(buildFile.toPath());
             } else {
                 uri = url.toString();
                 int pling = -1;
@@ -521,6 +524,7 @@
          *                 document. Will not be <code>null</code>.
          * @return an inputsource for this identifier
          */
+        @Override
         public InputSource resolveEntity(String publicId, String systemId) {
 
             context.getProject().log("resolving systemId: " + systemId, Project.MSG_VERBOSE);
@@ -538,10 +542,10 @@
                 }
                 context.getProject().log("file=" + file, Project.MSG_DEBUG);
                 try {
-                    InputSource inputSource = new InputSource(new FileInputStream(file));
+                    InputSource inputSource = new InputSource(Files.newInputStream(file.toPath()));
                     inputSource.setSystemId(FILE_UTILS.toURI(file.getAbsolutePath()));
                     return inputSource;
-                } catch (FileNotFoundException fne) {
+                } catch (IOException fne) {
                     context.getProject().log(file.getAbsolutePath() + " could not be found",
                                              Project.MSG_WARN);
                 }
@@ -566,6 +570,7 @@
          * @exception org.xml.sax.SAXParseException if the tag given is not
          *                              <code>"project"</code>
          */
+        @Override
         public void startElement(String uri, String tag, String qname, Attributes attrs)
             throws SAXParseException {
             AntHandler next = currentHandler.onStartChild(uri, tag, qname, attrs, context);
@@ -580,6 +585,7 @@
          * @param locator The locator used by the parser.
          *                Will not be <code>null</code>.
          */
+        @Override
         public void setDocumentLocator(Locator locator) {
             context.setLocator(locator);
         }
@@ -595,9 +601,10 @@
          *
          * @exception SAXException in case of error (not thrown in this implementation)
          */
+        @Override
         public void endElement(String uri, String name, String qName) throws SAXException {
             currentHandler.onEndElement(uri, name, context);
-            AntHandler prev = (AntHandler) antHandlers.pop();
+            AntHandler prev = antHandlers.pop();
             currentHandler = prev;
             if (currentHandler != null) {
                 currentHandler.onEndChild(uri, name, qName, context);
@@ -612,6 +619,7 @@
          * @param count The number of characters to read.
          * @exception SAXParseException if an error occurs
          */
+        @Override
         public void characters(char[] buf, int start, int count) throws SAXParseException {
             currentHandler.characters(buf, start, count, context);
         }
@@ -622,6 +630,7 @@
          * @param prefix the namespace prefix
          * @param uri the namespace uri
          */
+        @Override
         public void startPrefixMapping(String prefix, String uri) {
             context.startPrefixMapping(prefix, uri);
         }
@@ -631,6 +640,7 @@
          *
          * @param prefix the prefix that is not mapped anymore
          */
+        @Override
         public void endPrefixMapping(String prefix) {
             context.endPrefixMapping(prefix);
         }
@@ -654,10 +664,11 @@
          * @return The project handler that handles subelements of project
          * @exception SAXParseException if the qualified name is not "project".
          */
+        @Override
         public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
                                        AntXMLContext context) throws SAXParseException {
             if ("project".equals(name)
-                && (uri.equals("") || uri.equals(ANT_CORE_URI))) {
+                && (uri.isEmpty() || uri.equals(ANT_CORE_URI))) {
                 return ProjectHelper2.projectHandler;
             }
             if (name.equals(qname)) {
@@ -693,6 +704,7 @@
          *            encountered or if the <code>"default"</code> attribute
          *            is missing.
          */
+        @Override
         public void onStartElement(String uri, String tag, String qname, Attributes attrs,
                                    AntXMLContext context) throws SAXParseException {
             String baseDir = null;
@@ -715,14 +727,14 @@
 
             for (int i = 0; i < attrs.getLength(); i++) {
                 String attrUri = attrs.getURI(i);
-                if (attrUri != null && !attrUri.equals("") && !attrUri.equals(uri)) {
+                if (attrUri != null && !attrUri.isEmpty() && !attrUri.equals(uri)) {
                     continue; // Ignore attributes from unknown uris
                 }
                 String key = attrs.getLocalName(i);
                 String value = attrs.getValue(i);
 
                 if ("default".equals(key)) {
-                    if (value != null && !value.equals("")) {
+                    if (value != null && !value.isEmpty()) {
                         if (!context.isIgnoringProjectTag()) {
                             project.setDefault(value);
                         }
@@ -849,10 +861,11 @@
          *            <code>"extension-point"</code>
          *            or a data type definition
          */
+        @Override
         public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
                                        AntXMLContext context) throws SAXParseException {
-            return (name.equals("target") || name.equals("extension-point"))
-                && (uri.equals("") || uri.equals(ANT_CORE_URI))
+            return ("target".equals(name) || "extension-point".equals(name))
+                && (uri.isEmpty() || uri.equals(ANT_CORE_URI))
                 ? ProjectHelper2.targetHandler : ProjectHelper2.elementHandler;
         }
     }
@@ -882,6 +895,7 @@
          * @exception SAXParseException if an unexpected attribute is encountered
          *            or if the <code>"name"</code> attribute is missing.
          */
+        @Override
         public void onStartElement(String uri, String tag, String qname, Attributes attrs,
                                    AntXMLContext context) throws SAXParseException {
             String name = null;
@@ -898,7 +912,7 @@
 
             for (int i = 0; i < attrs.getLength(); i++) {
                 String attrUri = attrs.getURI(i);
-                if (attrUri != null && !attrUri.equals("") && !attrUri.equals(uri)) {
+                if (attrUri != null && !attrUri.isEmpty() && !attrUri.equals(uri)) {
                     continue; // Ignore attributes from unknown uris
                 }
                 String key = attrs.getLocalName(i);
@@ -906,7 +920,7 @@
 
                 if ("name".equals(key)) {
                     name = value;
-                    if ("".equals(name)) {
+                    if (name.isEmpty()) {
                         throw new BuildException("name attribute must " + "not be empty");
                     }
                 } else if ("depends".equals(key)) {
@@ -916,7 +930,7 @@
                 } else if ("unless".equals(key)) {
                     target.setUnless(value);
                 } else if ("id".equals(key)) {
-                    if (value != null && !value.equals("")) {
+                    if (value != null && !value.isEmpty()) {
                         context.getProject().addReference(value, target);
                     }
                 } else if ("description".equals(key)) {
@@ -1062,6 +1076,7 @@
          * @exception SAXParseException if an error occurs when initialising
          *                              the appropriate child handler
          */
+        @Override
         public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
                                        AntXMLContext context) throws SAXParseException {
             return ProjectHelper2.elementHandler;
@@ -1075,6 +1090,7 @@
          * @param tag The name of the element.
          * @param context The current context.
          */
+        @Override
         public void onEndElement(String uri, String tag, AntXMLContext context) {
             context.setCurrentTarget(context.getImplicitTarget());
         }
@@ -1109,6 +1125,7 @@
          * @exception SAXParseException in case of error (not thrown in
          *                              this implementation)
          */
+        @Override
         public void onStartElement(String uri, String tag, String qname, Attributes attrs,
                                    AntXMLContext context) throws SAXParseException {
             RuntimeConfigurable parentWrapper = context.currentWrapper();
@@ -1150,7 +1167,7 @@
             for (int i = 0; i < attrs.getLength(); i++) {
                 String name = attrs.getLocalName(i);
                 String attrUri = attrs.getURI(i);
-                if (attrUri != null && !attrUri.equals("") && !attrUri.equals(uri)) {
+                if (attrUri != null && !attrUri.isEmpty() && !attrUri.equals(uri)) {
                     name = attrUri + ":" + attrs.getQName(i);
                 }
                 String value = attrs.getValue(i);
@@ -1195,6 +1212,7 @@
          *
          * @see ProjectHelper#addText(Project,java.lang.Object,char[],int,int)
          */
+        @Override
         public void characters(char[] buf, int start, int count,
                                AntXMLContext context) throws SAXParseException {
             RuntimeConfigurable wrapper = context.currentWrapper();
@@ -1218,6 +1236,7 @@
          * @exception SAXParseException if an error occurs when initialising
          *                              the appropriate child handler
          */
+        @Override
         public AntHandler onStartChild(String uri, String tag, String qname, Attributes attrs,
                                        AntXMLContext context) throws SAXParseException {
             return ProjectHelper2.elementHandler;
@@ -1231,6 +1250,7 @@
          * @param tag The name of the element.
          * @param context The current context.
          */
+        @Override
         public void onEndElement(String uri, String tag, AntXMLContext context) {
             context.popWrapper();
         }
diff --git a/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java b/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java
index 4b159f3..4b824ba 100644
--- a/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java
+++ b/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java
@@ -18,10 +18,11 @@
 package org.apache.tools.ant.helper;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
+import java.nio.file.Files;
 import java.util.Locale;
 
 import org.apache.tools.ant.BuildException;
@@ -110,7 +111,7 @@
                 + "default plugin");
         }
         File bFile = (File) source;
-        FileInputStream inputStream = null;
+        InputStream inputStream = null;
         InputSource inputSource = null;
 
         this.project = project;
@@ -124,7 +125,7 @@
                 parser = new XMLReaderAdapter(JAXPUtils.getXMLReader());
             }
             String uri = FILE_UTILS.toURI(bFile.getAbsolutePath());
-            inputStream = new FileInputStream(bFile);
+            inputStream = Files.newInputStream(bFile.toPath());
             inputSource = new InputSource(inputStream);
             inputSource.setSystemId(uri);
             project.log("parsing buildfile " + bFile + " with URI = " + uri, Project.MSG_VERBOSE);
@@ -302,10 +303,10 @@
                             + "' for compliance with other XML tools", Project.MSG_WARN);
                 }
                 try {
-                    InputSource inputSource = new InputSource(new FileInputStream(file));
+                    InputSource inputSource = new InputSource(Files.newInputStream(file.toPath()));
                     inputSource.setSystemId(FILE_UTILS.toURI(file.getAbsolutePath()));
                     return inputSource;
-                } catch (FileNotFoundException fne) {
+                } catch (IOException fne) {
                     helperImpl.project.log(file.getAbsolutePath() + " could not be found",
                             Project.MSG_WARN);
                 }
@@ -403,7 +404,7 @@
                 }
             }
 
-            if (def != null && !def.equals("")) {
+            if (def != null && !def.isEmpty()) {
                 helperImpl.project.setDefault(def);
             } else {
                 throw new BuildException("The default attribute is required");
@@ -526,7 +527,7 @@
 
                 if ("name".equals(key)) {
                     name = value;
-                    if (name.equals("")) {
+                    if (name.isEmpty()) {
                         throw new BuildException("name attribute must not" + " be empty",
                                 new Location(helperImpl.locator));
                     }
@@ -562,7 +563,7 @@
             target.setDescription(description);
             helperImpl.project.addTarget(name, target);
 
-            if (id != null && !id.equals("")) {
+            if (id != null && !id.isEmpty()) {
                 helperImpl.project.addReference(id, target);
             }
 
diff --git a/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java b/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java
index 4baab8f..8f3b086 100644
--- a/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java
+++ b/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java
@@ -18,6 +18,7 @@
 
 package org.apache.tools.ant.input;
 
+import java.util.Collection;
 import java.util.LinkedHashSet;
 import java.util.Vector;
 
@@ -33,26 +34,39 @@
      * @param prompt The prompt to show to the user.  Must not be null.
      * @param choices holds all input values that are allowed.
      *                Must not be null.
+     * @deprecated Use {@link #MultipleChoiceInputRequest(String,Collection)} instead
      */
+    @Deprecated
     public MultipleChoiceInputRequest(String prompt, Vector<String> choices) {
+        this(prompt, (Collection<String>) choices);
+    }
+
+    /**
+     * @param prompt The prompt to show to the user.  Must not be null.
+     * @param choices holds all input values that are allowed.
+     *                Must not be null.
+     */
+    public MultipleChoiceInputRequest(String prompt, Collection<String> choices) {
         super(prompt);
         if (choices == null) {
             throw new IllegalArgumentException("choices must not be null");
         }
-        this.choices = new LinkedHashSet<String>(choices);
+        this.choices = new LinkedHashSet<>(choices);
     }
 
     /**
      * @return The possible values.
      */
     public Vector<String> getChoices() {
-        return new Vector<String>(choices);
+        return new Vector<>(choices);
     }
 
     /**
      * @return true if the input is one of the allowed values.
      */
+    @Override
     public boolean isInputValid() {
-        return choices.contains(getInput()) || ("".equals(getInput()) && getDefaultValue() != null);
+        return choices.contains(getInput())
+            || ("".equals(getInput()) && getDefaultValue() != null);
     }
 }
diff --git a/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java b/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java
index e1e3cf1..22a99d3 100644
--- a/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java
+++ b/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java
@@ -18,8 +18,9 @@
 
 package org.apache.tools.ant.input;
 
-import java.io.FileInputStream;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.Properties;
 
 import org.apache.tools.ant.BuildException;
@@ -82,7 +83,7 @@
             props = new Properties();
 
             try {
-                props.load(new FileInputStream(propsFile));
+                props.load(Files.newInputStream(Paths.get(propsFile)));
             } catch (IOException e) {
                 throw new BuildException("Couldn't load " + propsFile, e);
             }
diff --git a/src/main/org/apache/tools/ant/launch/Launcher.java b/src/main/org/apache/tools/ant/launch/Launcher.java
index 10ca77c..e93c94c 100644
--- a/src/main/org/apache/tools/ant/launch/Launcher.java
+++ b/src/main/org/apache/tools/ant/launch/Launcher.java
@@ -25,9 +25,6 @@
 import java.util.List;
 import java.util.StringTokenizer;
 
-
-
-
 /**
  * This is a launcher for Ant.
  *
@@ -35,9 +32,6 @@
  */
 public class Launcher {
 
-    private Launcher() {
-    }
-
     /**
      * The Ant Home (installation) Directory property.
      * {@value}
@@ -63,11 +57,6 @@
     public static final String ANT_PRIVATELIB = "lib";
 
     /**
-     * launch diagnostics flag; for debugging trouble at launch time.
-     */
-    public boolean launchDiag = false;
-
-    /**
      * The location of a per-user library directory.
      * <p>It's value is the concatenation of {@link #ANT_PRIVATEDIR}
      * with {@link #ANT_PRIVATELIB}, with an appropriate file separator
@@ -126,6 +115,13 @@
         }
     }
 
+    /**
+     * launch diagnostics flag; for debugging trouble at launch time.
+     */
+    public boolean launchDiag = false;
+
+    private Launcher() {
+    }
 
     /**
      * Add a CLASSPATH or -lib to lib path urls.
@@ -155,7 +151,7 @@
                 }
             }
 
-            final URL url = Locator.fileToURL(element);
+            final URL url = new URL(element.toURI().toASCIIString());
             if (launchDiag) {
                 System.out.println("adding library URL: " + url);
             }
@@ -192,44 +188,45 @@
         }
 
         if (!antHome.exists()) {
-            throw new LaunchException("Ant home is set incorrectly or "
-                + "ant could not be located (estimated value="+antHome.getAbsolutePath()+")");
+            throw new LaunchException(
+                "Ant home is set incorrectly or ant could not be located (estimated value="
+                    + antHome.getAbsolutePath() + ")");
         }
 
-        final List<String> libPaths = new ArrayList<String>();
+        final List<String> libPaths = new ArrayList<>();
         String cpString = null;
-        final List<String> argList = new ArrayList<String>();
+        final List<String> argList = new ArrayList<>();
         String[] newArgs;
         boolean  noUserLib = false;
         boolean  noClassPath = false;
 
         for (int i = 0; i < args.length; ++i) {
-            if (args[i].equals("-lib")) {
+            if ("-lib".equals(args[i])) {
                 if (i == args.length - 1) {
-                    throw new LaunchException("The -lib argument must "
-                        + "be followed by a library location");
+                    throw new LaunchException(
+                        "The -lib argument must be followed by a library location");
                 }
                 libPaths.add(args[++i]);
-            } else if (args[i].equals("-cp")) {
+            } else if ("-cp".equals(args[i])) {
                 if (i == args.length - 1) {
-                    throw new LaunchException("The -cp argument must "
-                        + "be followed by a classpath expression");
+                    throw new LaunchException(
+                        "The -cp argument must be followed by a classpath expression");
                 }
                 if (cpString != null) {
-                    throw new LaunchException("The -cp argument must "
-                        + "not be repeated");
+                    throw new LaunchException(
+                        "The -cp argument must not be repeated");
                 }
                 cpString = args[++i];
-            } else if (args[i].equals("--nouserlib") || args[i].equals("-nouserlib")) {
+            } else if ("--nouserlib".equals(args[i]) || "-nouserlib".equals(args[i])) {
                 noUserLib = true;
-            } else if (args[i].equals("--launchdiag")) {
+            } else if ("--launchdiag".equals(args[i])) {
                 launchDiag = true;
-            } else if (args[i].equals("--noclasspath") || args[i].equals("-noclasspath")) {
+            } else if ("--noclasspath".equals(args[i]) || "-noclasspath".equals(args[i])) {
                 noClassPath = true;
-            } else if (args[i].equals("-main")) {
+            } else if ("-main".equals(args[i])) {
                 if (i == args.length - 1) {
-                    throw new LaunchException("The -main argument must "
-                            + "be followed by a library location");
+                    throw new LaunchException(
+                        "The -main argument must be followed by a library location");
                 }
                 mainClassname = args[++i];
             } else {
@@ -261,8 +258,8 @@
             libURLs, userURLs, systemURLs, toolsJAR);
 
         // now update the class.path property
-        final StringBuffer baseClassPath
-            = new StringBuffer(System.getProperty(JAVA_CLASS_PATH));
+        final StringBuilder baseClassPath
+            = new StringBuilder(System.getProperty(JAVA_CLASS_PATH));
         if (baseClassPath.charAt(baseClassPath.length() - 1)
                 == File.pathSeparatorChar) {
             baseClassPath.setLength(baseClassPath.length() - 1);
@@ -277,12 +274,12 @@
 
         final URLClassLoader loader = new URLClassLoader(jars, Launcher.class.getClassLoader());
         Thread.currentThread().setContextClassLoader(loader);
-        Class<?> mainClass = null;
+        Class<? extends AntMain> mainClass = null;
         int exitCode = 0;
         Throwable thrown = null;
         try {
-            mainClass = loader.loadClass(mainClassname);
-            final AntMain main = (AntMain) mainClass.newInstance();
+            mainClass = loader.loadClass(mainClassname).asSubclass(AntMain.class);
+            final AntMain main = mainClass.newInstance();
             main.startAnt(newArgs, null, null);
         } catch (final InstantiationException ex) {
             System.err.println(
@@ -319,7 +316,7 @@
      */
     private URL[] getLibPathURLs(final String cpString, final List<String> libPaths)
         throws MalformedURLException {
-        final List<URL> libPathURLs = new ArrayList<URL>();
+        final List<URL> libPathURLs = new ArrayList<>();
 
         if (cpString != null) {
             addPath(cpString, false, libPathURLs);
@@ -388,7 +385,7 @@
             systemJars.length);
 
         if (toolsJar != null) {
-            jars[jars.length - 1] = Locator.fileToURL(toolsJar);
+            jars[jars.length - 1] = new URL(toolsJar.toURI().toASCIIString());
         }
         return jars;
     }
@@ -406,8 +403,8 @@
     }
 
     private void logPath(final String name, final File path) {
-        if(launchDiag) {
-            System.out.println(name+"= \""+path+"\"");
+        if (launchDiag) {
+            System.out.println(name + "= \"" + path + "\"");
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/launch/Locator.java b/src/main/org/apache/tools/ant/launch/Locator.java
index 4f5aef4..b0c67c5 100644
--- a/src/main/org/apache/tools/ant/launch/Locator.java
+++ b/src/main/org/apache/tools/ant/launch/Locator.java
@@ -19,13 +19,14 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FilenameFilter;
 import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.nio.charset.StandardCharsets;
 import java.text.CharacterIterator;
 import java.text.StringCharacterIterator;
 import java.util.Locale;
+import java.util.stream.Stream;
 
 // CheckStyle:LineLengthCheck OFF - urls are long!
 /**
@@ -59,10 +60,6 @@
     private static final int SPACE = 0x20;
     private static final int DEL = 0x7F;
 
-    /**
-     * encoding used to represent URIs
-     */
-    public static final String URI_ENCODING = "UTF-8";
     // stolen from org.apache.xerces.impl.XMLEntityManager#getUserDir()
     // of the Xerces-J team
     // which ASCII characters need to be escaped
@@ -98,11 +95,6 @@
             gAfterEscaping2[ch] = gHexChs[ch & NIBBLE_MASK];
         }
     }
-    /**
-     * Not instantiable
-     */
-    private Locator() {
-    }
 
     /**
      * Find the directory or jar file the class has been loaded from.
@@ -133,7 +125,7 @@
         if (c == null) {
             c = Locator.class.getClassLoader();
         }
-        URL url = null;
+        URL url;
         if (c == null) {
             url = ClassLoader.getSystemResource(resource);
         } else {
@@ -144,21 +136,19 @@
             try {
                 if (u.startsWith("jar:file:")) {
                     return new File(fromJarURI(u));
-                } else if (u.startsWith("file:")) {
+                }
+                if (u.startsWith("file:")) {
                     int tail = u.indexOf(resource);
                     String dirName = u.substring(0, tail);
                     return new File(fromURI(dirName));
                 }
             } catch (IllegalArgumentException e) {
                 //unable to determine the URI for reasons unknown.
-                return null;
             }
         }
         return null;
     }
 
-
-
     /**
      * Constructs a file path from a <code>file:</code> URI.
      *
@@ -237,7 +227,7 @@
         if (url == null || !("file".equals(url.getProtocol()))) {
             throw new IllegalArgumentException(ERROR_NOT_FILE_URI + uri);
         }
-        StringBuffer buf = new StringBuffer(url.getHost());
+        StringBuilder buf = new StringBuilder(url.getHost());
         if (buf.length() > 0) {
             buf.insert(0, File.separatorChar).insert(0, File.separatorChar);
         }
@@ -315,11 +305,11 @@
             } else if (c >= 0x0000 && c < 0x0080) {
                 sb.write(c);
             } else { // #50543
-                byte[] bytes = String.valueOf(c).getBytes(URI_ENCODING);
+                byte[] bytes = String.valueOf(c).getBytes(StandardCharsets.UTF_8);
                 sb.write(bytes, 0, bytes.length);
             }
         }
-        return sb.toString(URI_ENCODING);
+        return sb.toString(StandardCharsets.UTF_8.name());
     }
 
     /**
@@ -327,14 +317,13 @@
      * The URI is escaped
      * @param path String to encode.
      * @return The encoded string, according to URI norms
-     * @throws UnsupportedEncodingException if UTF-8 is not available
      * @since Ant 1.7
      */
-    public static String encodeURI(String path) throws UnsupportedEncodingException {
+    public static String encodeURI(String path) {
         int i = 0;
         int len = path.length();
         int ch = 0;
-        StringBuffer sb = null;
+        StringBuilder sb = null;
         for (; i < len; i++) {
             ch = path.charAt(i);
             // if it's not an ASCII character, break here, and use UTF-8 encoding
@@ -343,7 +332,7 @@
             }
             if (gNeedEscaping[ch]) {
                 if (sb == null) {
-                    sb = new StringBuffer(path.substring(0, i));
+                    sb = new StringBuilder(path.substring(0, i));
                 }
                 sb.append('%');
                 sb.append(gAfterEscaping1[ch]);
@@ -357,17 +346,15 @@
         // we saw some non-ascii character
         if (i < len) {
             if (sb == null) {
-                sb = new StringBuffer(path.substring(0, i));
+                sb = new StringBuilder(path.substring(0, i));
             }
             // get UTF-8 bytes for the remaining sub-string
-            byte[] bytes = null;
-            byte b;
-            bytes = path.substring(i).getBytes(URI_ENCODING);
+            byte[] bytes = path.substring(i).getBytes(StandardCharsets.UTF_8);
             len = bytes.length;
 
             // for each byte
             for (i = 0; i < len; i++) {
-                b = bytes[i];
+                byte b = bytes[i];
                 // for non-ascii character: make it positive, then escape
                 if (b < 0) {
                     ch = b + BYTE_SIZE;
@@ -469,7 +456,7 @@
      */
     public static URL[] getLocationURLs(File location)
          throws MalformedURLException {
-        return getLocationURLs(location, new String[]{".jar"});
+        return getLocationURLs(location, ".jar");
     }
 
     /**
@@ -487,7 +474,7 @@
      *            formed.
      */
     public static URL[] getLocationURLs(File location,
-                                        final String[] extensions)
+                                        final String... extensions)
          throws MalformedURLException {
         URL[] urls = new URL[0];
 
@@ -506,22 +493,21 @@
             }
             return urls;
         }
-        File[] matches = location.listFiles(
-            new FilenameFilter() {
-                public boolean accept(File dir, String name) {
-                    String littleName = name.toLowerCase(Locale.ENGLISH);
-                    for (int i = 0; i < extensions.length; ++i) {
-                        if (littleName.endsWith(extensions[i])) {
-                            return true;
-                        }
-                    }
-                    return false;
-                }
-            });
+        File[] matches = location.listFiles((dir, name) -> {
+            String littleName = name.toLowerCase(Locale.ENGLISH);
+            return Stream.of(extensions).anyMatch(x -> littleName.endsWith(x));
+        });
         urls = new URL[matches.length];
         for (int i = 0; i < matches.length; ++i) {
             urls[i] = fileToURL(matches[i]);
         }
         return urls;
     }
+
+    /**
+     * Not instantiable
+     */
+    private Locator() {
+    }
+
 }
diff --git a/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java b/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java
index fb22f75..f99ca3b 100644
--- a/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java
+++ b/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java
@@ -17,10 +17,11 @@
  */
 package org.apache.tools.ant.listener;
 
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.Properties;
 
 import org.apache.tools.ant.DefaultLogger;
@@ -162,7 +163,7 @@
             Properties prop = new Properties();
 
             if (userColorFile != null) {
-                in = new FileInputStream(userColorFile);
+                in = Files.newInputStream(Paths.get(userColorFile));
             } else {
                 in = getClass().getResourceAsStream(systemColorFile);
             }
@@ -212,7 +213,7 @@
                 colorsSet = true;
             }
 
-            final StringBuffer msg = new StringBuffer(message);
+            final StringBuilder msg = new StringBuilder(message);
             switch (priority) {
                 case Project.MSG_ERR:
                     msg.insert(0, errColor);
diff --git a/src/main/org/apache/tools/ant/listener/CommonsLoggingListener.java b/src/main/org/apache/tools/ant/listener/CommonsLoggingListener.java
index cb4baa1..7c4ed60 100644
--- a/src/main/org/apache/tools/ant/listener/CommonsLoggingListener.java
+++ b/src/main/org/apache/tools/ant/listener/CommonsLoggingListener.java
@@ -102,6 +102,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void buildStarted(final BuildEvent event) {
         final Log log = getLog(PROJECT_LOG, null);
 
@@ -111,6 +112,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void buildFinished(final BuildEvent event) {
         if (initialized) {
             final Log log = getLog(PROJECT_LOG, event.getProject().getName());
@@ -128,6 +130,7 @@
      * @see BuildListener#targetStarted
      * {@inheritDoc}.
      */
+    @Override
     public void targetStarted(final BuildEvent event) {
         if (initialized) {
             final Log log = getLog(TARGET_LOG,
@@ -143,6 +146,7 @@
      * @see BuildListener#targetFinished
      * {@inheritDoc}.
      */
+    @Override
     public void targetFinished(final BuildEvent event) {
         if (initialized) {
             final String targetName = event.getTarget().getName();
@@ -162,6 +166,7 @@
      * @see BuildListener#taskStarted
      * {@inheritDoc}.
      */
+    @Override
     public void taskStarted(final BuildEvent event) {
         if (initialized) {
             final Task task = event.getTask();
@@ -184,6 +189,7 @@
      * @see BuildListener#taskFinished
      * {@inheritDoc}.
      */
+    @Override
     public void taskFinished(final BuildEvent event) {
         if (initialized) {
             final Task task = event.getTask();
@@ -213,16 +219,16 @@
      * @see BuildListener#messageLogged
      * {@inheritDoc}.
      */
+    @Override
     public void messageLogged(final BuildEvent event) {
         if (initialized) {
             Object categoryObject = event.getTask();
-            String categoryString = null;
+            String categoryString;
             String categoryDetail = null;
 
             if (categoryObject == null) {
                 categoryObject = event.getTarget();
                 if (categoryObject == null) {
-                    categoryObject = event.getProject();
                     categoryString = PROJECT_LOG;
                     categoryDetail = event.getProject().getName();
                 } else {
@@ -298,6 +304,7 @@
      * This is not used, the logger config is used instead.
      * @param level ignored
      */
+    @Override
     public void setMessageOutputLevel(final int level) {
         // Use the logger config
     }
@@ -306,6 +313,7 @@
      * Set the output print stream.
      * @param output the output stream
      */
+    @Override
     public void setOutputPrintStream(final PrintStream output) {
         this.out = output;
     }
@@ -315,6 +323,7 @@
      * This is ignored.
      * @param emacsMode ignored
      */
+    @Override
     public void setEmacsMode(final boolean emacsMode) {
         // Doesn't make sense for c-l. Use the logger config
     }
@@ -323,6 +332,7 @@
      * Set the error print stream.
      * @param err the error stream
      */
+    @Override
     public void setErrorPrintStream(final PrintStream err) {
         this.err = err;
     }
diff --git a/src/main/org/apache/tools/ant/listener/Log4jListener.java b/src/main/org/apache/tools/ant/listener/Log4jListener.java
index b691300..a116e3d 100644
--- a/src/main/org/apache/tools/ant/listener/Log4jListener.java
+++ b/src/main/org/apache/tools/ant/listener/Log4jListener.java
@@ -51,6 +51,7 @@
      * @see BuildListener#buildStarted
      * {@inheritDoc}.
      */
+    @Override
     public void buildStarted(final BuildEvent event) {
         final Logger log = Logger.getLogger(Project.class.getName());
         log.info("Build started.");
@@ -60,6 +61,7 @@
      * @see BuildListener#buildFinished
      * {@inheritDoc}.
      */
+    @Override
     public void buildFinished(final BuildEvent event) {
         final Logger log = Logger.getLogger(Project.class.getName());
         if (event.getException() == null) {
@@ -73,6 +75,7 @@
      * @see BuildListener#targetStarted
      * {@inheritDoc}.
      */
+    @Override
     public void targetStarted(final BuildEvent event) {
         final Logger log = Logger.getLogger(Target.class.getName());
         log.info("Target \"" + event.getTarget().getName() + "\" started.");
@@ -82,6 +85,7 @@
      * @see BuildListener#targetFinished
      * {@inheritDoc}.
      */
+    @Override
     public void targetFinished(final BuildEvent event) {
         final String targetName = event.getTarget().getName();
         final Logger cat = Logger.getLogger(Target.class.getName());
@@ -97,6 +101,7 @@
      * @see BuildListener#taskStarted
      * {@inheritDoc}.
      */
+    @Override
     public void taskStarted(final BuildEvent event) {
         final Task task = event.getTask();
         final Logger log = Logger.getLogger(task.getClass().getName());
@@ -107,6 +112,7 @@
      * @see BuildListener#taskFinished
      * {@inheritDoc}.
      */
+    @Override
     public void taskFinished(final BuildEvent event) {
         final Task task = event.getTask();
         final Logger log = Logger.getLogger(task.getClass().getName());
@@ -122,7 +128,7 @@
      * @see BuildListener#messageLogged
      * {@inheritDoc}.
      */
-    /** {@inheritDoc}. */
+    @Override
     public void messageLogged(final BuildEvent event) {
         Object categoryObject = event.getTask();
         if (categoryObject == null) {
diff --git a/src/main/org/apache/tools/ant/listener/MailLogger.java b/src/main/org/apache/tools/ant/listener/MailLogger.java
index 2de55bf..9462e25 100644
--- a/src/main/org/apache/tools/ant/listener/MailLogger.java
+++ b/src/main/org/apache/tools/ant/listener/MailLogger.java
@@ -18,15 +18,18 @@
 package org.apache.tools.ant.listener;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.Map;
 import java.util.Properties;
 import java.util.StringTokenizer;
 import java.util.Vector;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildEvent;
 import org.apache.tools.ant.BuildException;
@@ -96,21 +99,22 @@
  *
  */
 public class MailLogger extends DefaultLogger {
+    private static final String DEFAULT_MIME_TYPE = "text/plain";
+
     /** Buffer in which the message is constructed prior to sending */
     private StringBuffer buffer = new StringBuffer();
 
-    private static final String DEFAULT_MIME_TYPE = "text/plain";
-
     /**
      *  Sends an e-mail with the log results.
      *
      * @param event the build finished event
      */
+    @Override
     public void buildFinished(BuildEvent event) {
         super.buildFinished(event);
 
         Project project = event.getProject();
-        Hashtable<String, Object> properties = project.getProperties();
+        Map<String, Object> properties = project.getProperties();
 
         // overlay specified properties file (if any), which overrides project
         // settings
@@ -119,7 +123,7 @@
         if (filename != null) {
             InputStream is = null;
             try {
-                is = new FileInputStream(filename);
+                is = Files.newInputStream(Paths.get(filename));
                 fileProperties.load(is);
             } catch (IOException ioe) {
                 // ignore because properties file is not required
@@ -167,8 +171,8 @@
                 .subject(getValue(
                              properties, prefix + ".subject",
                              (success) ? "Build Success" : "Build Failure"));
-            if (values.user().equals("")
-                && values.password().equals("")
+            if (values.user().isEmpty()
+                && values.password().isEmpty()
                 && !values.ssl() && !values.starttls()) {
                 sendMail(values, buffer.substring(0));
             } else {
@@ -309,6 +313,7 @@
      *
      * @param message the message being logger
      */
+    @Override
     protected void log(String message) {
         buffer.append(message).append(StringUtils.LINE_SEP);
     }
@@ -324,7 +329,7 @@
      *      Set to null to make required.
      * @return                The value of the property, or default value.
      */
-    private String getValue(Hashtable<String, Object> properties, String name,
+    private String getValue(Map<String, Object> properties, String name,
                             String defaultValue) {
         String propertyName = "MailLogger." + name;
         String value = (String) properties.get(propertyName);
@@ -353,7 +358,7 @@
         mailMessage.setHeader("Date", DateUtils.getDateForHeader());
 
         mailMessage.from(values.from());
-        if (!values.replytoList().equals("")) {
+        if (!values.replytoList().isEmpty()) {
             StringTokenizer t = new StringTokenizer(
                 values.replytoList(), ", ", false);
             while (t.hasMoreTokens()) {
@@ -388,7 +393,7 @@
     private void sendMimeMail(Project project, Values values, String message) {
         Mailer mailer = null;
         try {
-            mailer = (Mailer) ClasspathUtils.newInstance(
+            mailer = ClasspathUtils.newInstance(
                     "org.apache.tools.ant.taskdefs.email.MimeMailer",
                     MailLogger.class.getClassLoader(), Mailer.class);
         } catch (BuildException e) {
@@ -397,7 +402,7 @@
             return;
         }
         // convert the replyTo string into a vector of emailaddresses
-        Vector<EmailAddress> replyToList = vectorizeEmailAddresses(values.replytoList());
+        Vector<EmailAddress> replyToList = splitEmailAddresses(values.replytoList());
         mailer.setHost(values.mailhost());
         mailer.setPort(values.port());
         mailer.setUser(values.user());
@@ -414,25 +419,20 @@
         mailer.setMessage(mymessage);
         mailer.setFrom(new EmailAddress(values.from()));
         mailer.setReplyToList(replyToList);
-        Vector<EmailAddress> toList = vectorizeEmailAddresses(values.toList());
+        Vector<EmailAddress> toList = splitEmailAddresses(values.toList());
         mailer.setToList(toList);
-        Vector<EmailAddress> toCcList = vectorizeEmailAddresses(values.toCcList());
+        Vector<EmailAddress> toCcList = splitEmailAddresses(values.toCcList());
         mailer.setCcList(toCcList);
-        Vector<EmailAddress> toBccList = vectorizeEmailAddresses(values.toBccList());
+        Vector<EmailAddress> toBccList = splitEmailAddresses(values.toBccList());
         mailer.setBccList(toBccList);
         mailer.setFiles(new Vector<File>());
         mailer.setSubject(values.subject());
         mailer.setHeaders(new Vector<Header>());
         mailer.send();
     }
-    private Vector<EmailAddress> vectorizeEmailAddresses(String listString) {
-        Vector<EmailAddress> emailList = new Vector<EmailAddress>();
-        StringTokenizer tokens = new StringTokenizer(listString, ",");
-        while (tokens.hasMoreTokens()) {
-            emailList.addElement(new EmailAddress(tokens.nextToken()));
-        }
-        return emailList;
+
+    private Vector<EmailAddress> splitEmailAddresses(String listString) {
+        return Stream.of(listString.split(",")).map(EmailAddress::new)
+            .collect(Collectors.toCollection(Vector::new));
     }
 }
-
-
diff --git a/src/main/org/apache/tools/ant/listener/ProfileLogger.java b/src/main/org/apache/tools/ant/listener/ProfileLogger.java
index bbf5bb4..5dfe8ef 100644
--- a/src/main/org/apache/tools/ant/listener/ProfileLogger.java
+++ b/src/main/org/apache/tools/ant/listener/ProfileLogger.java
@@ -32,7 +32,7 @@
  */
 public class ProfileLogger extends DefaultLogger {
 
-    private Map<Object, Date> profileData = new ConcurrentHashMap<Object, Date>();
+    private Map<Object, Date> profileData = new ConcurrentHashMap<>();
 
     /**
      * Logs a message to say that the target has started.
@@ -41,6 +41,7 @@
      *            An event with any relevant extra information. Must not be
      *            <code>null</code>.
      */
+    @Override
     public void targetStarted(BuildEvent event) {
         Date now = new Date();
         String name = "Target " + event.getTarget().getName();
@@ -55,8 +56,9 @@
      *            An event with any relevant extra information. Must not be
      *            <code>null</code>.
      */
+    @Override
     public void targetFinished(BuildEvent event) {
-        Date start = (Date) profileData.remove(event.getTarget());
+        Date start = profileData.remove(event.getTarget());
         String name = "Target " + event.getTarget().getName();
         logFinish(event, start, name);
     }
@@ -68,6 +70,7 @@
      *            An event with any relevant extra information. Must not be
      *            <code>null</code>.
      */
+    @Override
     public void taskStarted(BuildEvent event) {
         String name = event.getTask().getTaskName();
         Date now = new Date();
@@ -82,15 +85,16 @@
      *            An event with any relevant extra information. Must not be
      *            <code>null</code>.
      */
+    @Override
     public void taskFinished(BuildEvent event) {
-        Date start = (Date) profileData.remove(event.getTask());
+        Date start = profileData.remove(event.getTask());
         String name = event.getTask().getTaskName();
         logFinish(event, start, name);
     }
 
     private void logFinish(BuildEvent event, Date start, String name) {
         Date now = new Date();
-        String msg = null;
+        String msg;
         if (start != null) {
             long diff = now.getTime() - start.getTime();
             msg = StringUtils.LINE_SEP + name + ": finished " + now + " ("
diff --git a/src/main/org/apache/tools/ant/listener/SimpleBigProjectLogger.java b/src/main/org/apache/tools/ant/listener/SimpleBigProjectLogger.java
index 18f8dc6..7893287 100644
--- a/src/main/org/apache/tools/ant/listener/SimpleBigProjectLogger.java
+++ b/src/main/org/apache/tools/ant/listener/SimpleBigProjectLogger.java
@@ -33,14 +33,14 @@
      * @param event the event to work on
      * @return the target name -including the owning project name (if non-null)
      */
+    @Override
     protected String extractTargetName(BuildEvent event) {
         String targetName = super.extractTargetName(event);
         String projectName = extractProjectName(event);
-        if (projectName != null && targetName != null) {
-            return projectName + '.' + targetName;
-        } else {
+        if (projectName == null || targetName == null) {
             return targetName;
         }
+        return projectName + '.' + targetName;
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/listener/TimestampedLogger.java b/src/main/org/apache/tools/ant/listener/TimestampedLogger.java
index 91296e3..70535e9 100644
--- a/src/main/org/apache/tools/ant/listener/TimestampedLogger.java
+++ b/src/main/org/apache/tools/ant/listener/TimestampedLogger.java
@@ -30,13 +30,13 @@
      */
     public static final String SPACER = " - at ";
 
-
     /**
      * This is an override point: the message that indicates whether a build failed.
      * Subclasses can change/enhance the message.
      *
      * @return The classic "BUILD FAILED" plus a timestamp
      */
+    @Override
     protected String getBuildFailedMessage() {
         return super.getBuildFailedMessage() + SPACER + getTimestamp();
     }
@@ -47,6 +47,7 @@
      *
      * @return The classic "BUILD SUCCESSFUL" plus a timestamp
      */
+    @Override
     protected String getBuildSuccessfulMessage() {
         return super.getBuildSuccessfulMessage() + SPACER + getTimestamp();
     }
diff --git a/src/main/org/apache/tools/ant/loader/AntClassLoader2.java b/src/main/org/apache/tools/ant/loader/AntClassLoader2.java
index 1a4cac6..4838b0d 100644
--- a/src/main/org/apache/tools/ant/loader/AntClassLoader2.java
+++ b/src/main/org/apache/tools/ant/loader/AntClassLoader2.java
@@ -25,6 +25,10 @@
  *             Just use {@link AntClassLoader} itself.
  */
 public class AntClassLoader2 extends AntClassLoader {
+    static {
+        registerAsParallelCapable();
+    }
+
     /** No args constructor. */
     public AntClassLoader2() {
     }
diff --git a/src/main/org/apache/tools/ant/loader/AntClassLoader5.java b/src/main/org/apache/tools/ant/loader/AntClassLoader5.java
index 15c29df..873e48a 100644
--- a/src/main/org/apache/tools/ant/loader/AntClassLoader5.java
+++ b/src/main/org/apache/tools/ant/loader/AntClassLoader5.java
@@ -27,6 +27,10 @@
  *             Just use {@link AntClassLoader} itself.
  */
 public class AntClassLoader5 extends AntClassLoader {
+    static {
+        registerAsParallelCapable();
+    }
+
     /**
      * Creates a classloader for the given project using the classpath given.
      *
diff --git a/src/main/org/apache/tools/ant/property/LocalProperties.java b/src/main/org/apache/tools/ant/property/LocalProperties.java
index c9ce3af..d5bb9b7 100644
--- a/src/main/org/apache/tools/ant/property/LocalProperties.java
+++ b/src/main/org/apache/tools/ant/property/LocalProperties.java
@@ -36,8 +36,8 @@
      * @return the localproperties.
      */
     public static synchronized LocalProperties get(Project project) {
-        LocalProperties l = (LocalProperties) project.getReference(
-            MagicNames.REFID_LOCAL_PROPERTIES);
+        LocalProperties l =
+            project.getReference(MagicNames.REFID_LOCAL_PROPERTIES);
         if (l == null) {
             l = new LocalProperties();
             project.addReference(MagicNames.REFID_LOCAL_PROPERTIES, l);
@@ -62,14 +62,11 @@
      * Get the initial value.
      * @return a new localproperties stack.
      */
+    @Override
     protected synchronized LocalPropertyStack initialValue() {
         return new LocalPropertyStack();
     }
 
-    private LocalPropertyStack current() {
-        return (LocalPropertyStack) get();
-    }
-
     // --------------------------------------------------
     //
     //  Local property adding and scoping
@@ -81,17 +78,17 @@
      * @param property the property name to add.
      */
     public void addLocal(String property) {
-        current().addLocal(property);
+        get().addLocal(property);
     }
 
     /** enter the scope */
     public void enterScope() {
-        current().enterScope();
+        get().enterScope();
     }
 
     /** exit the scope */
     public void exitScope() {
-        current().exitScope();
+        get().exitScope();
     }
 
     // --------------------------------------------------
@@ -105,7 +102,7 @@
      * To be called from the parallel thread itself.
      */
     public void copy() {
-        set(current().copy());
+        set(get().copy());
     }
 
     // --------------------------------------------------
@@ -120,8 +117,9 @@
      * @param helper the invoking PropertyHelper.
      * @return Object value.
      */
+    @Override
     public Object evaluate(String property, PropertyHelper helper) {
-        return current().evaluate(property, helper);
+        return get().evaluate(property, helper);
     }
 
     /**
@@ -131,9 +129,10 @@
      * @param propertyHelper the invoking PropertyHelper.
      * @return true if this entity 'owns' the property.
      */
+    @Override
     public boolean setNew(
         String property, Object value, PropertyHelper propertyHelper) {
-        return current().setNew(property, value, propertyHelper);
+        return get().setNew(property, value, propertyHelper);
     }
 
     /**
@@ -143,10 +142,9 @@
      * @param propertyHelper the invoking PropertyHelper.
      * @return true if this entity 'owns' the property.
      */
+    @Override
     public boolean set(
         String property, Object value, PropertyHelper propertyHelper) {
-        return current().set(property, value, propertyHelper);
+        return get().set(property, value, propertyHelper);
     }
 }
-
-
diff --git a/src/main/org/apache/tools/ant/property/LocalPropertyStack.java b/src/main/org/apache/tools/ant/property/LocalPropertyStack.java
index 482f28c..4babf29 100644
--- a/src/main/org/apache/tools/ant/property/LocalPropertyStack.java
+++ b/src/main/org/apache/tools/ant/property/LocalPropertyStack.java
@@ -17,6 +17,7 @@
  */
 package org.apache.tools.ant.property;
 
+import java.util.Deque;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -29,7 +30,7 @@
  * @since Ant 1.8.0
  */
 public class LocalPropertyStack {
-    private final LinkedList<Map<String, Object>> stack = new LinkedList<Map<String, Object>>();
+    private final Deque<Map<String, Object>> stack = new LinkedList<>();
     private final Object LOCK = new Object();
 
     // --------------------------------------------------
diff --git a/src/main/org/apache/tools/ant/property/NullReturn.java b/src/main/org/apache/tools/ant/property/NullReturn.java
index 067aa9f..9b90bf2 100644
--- a/src/main/org/apache/tools/ant/property/NullReturn.java
+++ b/src/main/org/apache/tools/ant/property/NullReturn.java
@@ -32,6 +32,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public String toString() {
         return "null";
     }
diff --git a/src/main/org/apache/tools/ant/property/ParseProperties.java b/src/main/org/apache/tools/ant/property/ParseProperties.java
index f03f966..6f08b74 100644
--- a/src/main/org/apache/tools/ant/property/ParseProperties.java
+++ b/src/main/org/apache/tools/ant/property/ParseProperties.java
@@ -19,6 +19,7 @@
 
 import java.text.ParsePosition;
 import java.util.Collection;
+import java.util.Objects;
 
 import org.apache.tools.ant.Project;
 
@@ -49,6 +50,7 @@
      * Get the project.
      * @return the current Ant project.
      */
+    @Override
     public Project getProject() {
         return project;
     }
@@ -90,7 +92,7 @@
      *         <code>null</code> if the original string is <code>null</code>.
      */
     public Object parseProperties(String value) {
-        if (value == null || "".equals(value)) {
+        if (value == null || value.isEmpty()) {
             return value;
         }
         final int len = value.length();
@@ -99,7 +101,7 @@
         if (o != null && pos.getIndex() >= len) {
             return o;
         }
-        StringBuffer sb = new StringBuffer(len * 2);
+        StringBuilder sb = new StringBuilder(len * 2);
         if (o == null) {
             sb.append(value.charAt(pos.getIndex()));
             pos.setIndex(pos.getIndex() + 1);
@@ -157,6 +159,7 @@
      * property doesn't expand to a value, the property's name is
      * returned.
      */
+    @Override
     public Object parseNextProperty(String value, ParsePosition pos) {
         final int start = pos.getIndex();
 
@@ -183,14 +186,9 @@
     }
 
     private String parsePropertyName(String value, ParsePosition pos) {
-        for (PropertyExpander propertyExpander : expanders) {
-            String propertyName = propertyExpander.parsePropertyName(value, pos, this);
-            if (propertyName == null) {
-                continue;
-            }
-            return propertyName;
-        }
-        return null;
+        return expanders.stream()
+            .map(xp -> xp.parsePropertyName(value, pos, this))
+            .filter(Objects::nonNull).findFirst().orElse(null);
     }
 
     private Object getProperty(String propertyName) {
diff --git a/src/main/org/apache/tools/ant/property/ResolvePropertyMap.java b/src/main/org/apache/tools/ant/property/ResolvePropertyMap.java
index 5bdd354..1554ec3 100644
--- a/src/main/org/apache/tools/ant/property/ResolvePropertyMap.java
+++ b/src/main/org/apache/tools/ant/property/ResolvePropertyMap.java
@@ -30,7 +30,7 @@
  * @since Ant 1.8.0
  */
 public class ResolvePropertyMap implements GetProperty {
-    private final Set<String> seen = new HashSet<String>();
+    private final Set<String> seen = new HashSet<>();
     private final ParseProperties parseProperties;
     private final GetProperty master;
     private Map<String, Object> map;
@@ -58,10 +58,11 @@
      * @param name name of the property.
      * @return the property value, or null for no match or for name being null.
      */
+    @Override
     public Object getProperty(String name) {
         if (seen.contains(name)) {
-            throw new BuildException(
-                "Property " + name + " was circularly " + "defined.");
+            throw new BuildException("Property %s was circularly defined.",
+                name);
         }
 
         try {
@@ -110,6 +111,7 @@
      * @param map the map to resolve properties in.
      * @deprecated since Ant 1.8.2, use the three-arg method instead.
      */
+    @Deprecated
     public void resolveAllProperties(Map<String, Object> map) {
         resolveAllProperties(map, null, false);
     }
@@ -121,6 +123,7 @@
      * will finally receive - may be null.
      * @deprecated since Ant 1.8.2, use the three-arg method instead.
      */
+    @Deprecated
     public void resolveAllProperties(Map<String, Object> map, String prefix) {
         resolveAllProperties(map, null, false);
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java b/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java
index 09b9b4a..c55c393 100644
--- a/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java
@@ -20,10 +20,10 @@
 
 import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintStream;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Vector;
@@ -56,10 +56,10 @@
 
     private Commandline cmd = new Commandline();
 
-    private ArrayList<Module> modules = new ArrayList<Module>();
+    private List<Module> modules = new ArrayList<>();
 
     /** list of Commandline children */
-    private Vector<Commandline> vecCommandlines = new Vector<Commandline>();
+    private List<Commandline> commandlines = new Vector<>();
 
     /**
      * the CVSROOT variable.
@@ -155,11 +155,6 @@
     private OutputStream outputStream;
     private OutputStream errorStream;
 
-    /** empty no-arg constructor*/
-    public AbstractCvsTask() {
-        super();
-    }
-
     /**
      * sets the handler
      * @param handler a handler able of processing the output and error streams from the cvs exe
@@ -207,8 +202,7 @@
                 try {
                     setOutputStream(new PrintStream(
                                         new BufferedOutputStream(
-                                            new FileOutputStream(output
-                                                                 .getPath(),
+                                            FileUtils.newOutputStream(Paths.get(output.getPath()),
                                                                  append))));
                 } catch (IOException e) {
                     throw new BuildException(e, getLocation());
@@ -247,7 +241,7 @@
                 try {
                     setErrorStream(new PrintStream(
                                        new BufferedOutputStream(
-                                           new FileOutputStream(error.getPath(),
+                                           FileUtils.newOutputStream(Paths.get(error.getPath()),
                                                                 append))));
                 } catch (IOException e) {
                     throw new BuildException(e, getLocation());
@@ -392,11 +386,12 @@
      * @throws BuildException if failonerror is set to true and the
      * cvs command fails.
      */
+    @Override
     public void execute() throws BuildException {
 
         String savedCommand = getCommand();
 
-        if (this.getCommand() == null && vecCommandlines.size() == 0) {
+        if (this.getCommand() == null && commandlines.isEmpty()) {
             // re-implement legacy behaviour:
             this.setCommand(AbstractCvsTask.DEFAULT_COMMAND);
         }
@@ -404,16 +399,13 @@
         String c = this.getCommand();
         Commandline cloned = null;
         if (c != null) {
-            cloned = (Commandline) cmd.clone();
+            cloned = cmd.clone();
             cloned.createArgument(true).setLine(c);
             this.addConfiguredCommandline(cloned, true);
         }
 
         try {
-            final int size = vecCommandlines.size();
-            for (int i = 0; i < size; i++) {
-                this.runCommand((Commandline) vecCommandlines.elementAt(i));
-            }
+            commandlines.forEach(this::runCommand);
         } finally {
             if (cloned != null) {
                 removeCommandline(cloned);
@@ -428,24 +420,24 @@
 
         String cmdLine = Commandline.describeCommand(execute
                 .getCommandline());
-        StringBuffer stringBuffer = removeCvsPassword(cmdLine);
+        StringBuilder buf = removeCvsPassword(cmdLine);
 
         String newLine = StringUtils.LINE_SEP;
         String[] variableArray = execute.getEnvironment();
 
         if (variableArray != null) {
-            stringBuffer.append(newLine);
-            stringBuffer.append(newLine);
-            stringBuffer.append("environment:");
-            stringBuffer.append(newLine);
+            buf.append(newLine);
+            buf.append(newLine);
+            buf.append("environment:");
+            buf.append(newLine);
             for (int z = 0; z < variableArray.length; z++) {
-                stringBuffer.append(newLine);
-                stringBuffer.append("\t");
-                stringBuffer.append(variableArray[z]);
+                buf.append(newLine);
+                buf.append("\t");
+                buf.append(variableArray[z]);
             }
         }
 
-        return stringBuffer.toString();
+        return buf.toString();
     }
 
     /**
@@ -456,24 +448,24 @@
      * @param cmdLine the CVS command line
      * @return a StringBuffer where the password has been removed (if available)
      */
-    private StringBuffer removeCvsPassword(String cmdLine) {
-        StringBuffer stringBuffer = new StringBuffer(cmdLine);
+    private StringBuilder removeCvsPassword(String cmdLine) {
+        StringBuilder buf = new StringBuilder(cmdLine);
 
         int start = cmdLine.indexOf("-d:");
 
         if (start >= 0) {
-            int stop = cmdLine.indexOf("@", start);
-            int startproto = cmdLine.indexOf(":", start);
-            int startuser = cmdLine.indexOf(":", startproto + 1);
-            int startpass = cmdLine.indexOf(":", startuser + 1);
-            stop = cmdLine.indexOf("@", start);
+            int stop = cmdLine.indexOf('@', start);
+            int startproto = cmdLine.indexOf(':', start);
+            int startuser = cmdLine.indexOf(':', startproto + 1);
+            int startpass = cmdLine.indexOf(':', startuser + 1);
+            stop = cmdLine.indexOf('@', start);
             if (stop >= 0 && startpass > startproto && startpass < stop) {
                 for (int i = startpass + 1; i < stop; i++) {
-                    stringBuffer.replace(i, i + 1, "*");
+                    buf.replace(i, i + 1, "*");
                 }
             }
         }
-        return stringBuffer;
+        return buf;
     }
 
     /**
@@ -485,10 +477,8 @@
     public void setCvsRoot(String root) {
 
         // Check if not real cvsroot => set it to null
-        if (root != null) {
-            if (root.trim().equals("")) {
-                root = null;
-            }
+        if (root != null && root.trim().isEmpty()) {
+            root = null;
         }
 
         this.cvsRoot = root;
@@ -509,11 +499,8 @@
      * @param rsh the CVS_RSH variable
      */
     public void setCvsRsh(String rsh) {
-        // Check if not real cvsrsh => set it to null
-        if (rsh != null) {
-            if (rsh.trim().equals("")) {
-                rsh = null;
-            }
+        if (rsh != null && rsh.trim().isEmpty()) {
+            rsh = null;
         }
 
         this.cvsRsh = rsh;
@@ -542,7 +529,6 @@
      * @return the port of CVS
      */
     public int getPort() {
-
         return this.port;
     }
 
@@ -560,7 +546,6 @@
      * @return password file
      */
     public File getPassFile() {
-
         return this.passFile;
     }
 
@@ -583,7 +568,6 @@
      * @return directory where the checked out files should be placed
      */
     public File getDest() {
-
         return this.dest;
     }
 
@@ -602,7 +586,6 @@
      * @return package/module
      */
     public String getPackage() {
-
         return this.cvsPackage;
     }
     /**
@@ -620,7 +603,7 @@
      */
     public void setTag(String p) {
         // Check if not real tag => set it to null
-        if (p != null && p.trim().length() > 0) {
+        if (!(p == null || p.trim().isEmpty())) {
             tag = p;
             addCommandArgument("-r" + p);
         }
@@ -656,7 +639,7 @@
      * can understand see man cvs
      */
     public void setDate(String p) {
-        if (p != null && p.trim().length() > 0) {
+        if (!(p == null || p.trim().isEmpty())) {
             addCommandArgument("-D");
             addCommandArgument(p);
         }
@@ -702,7 +685,6 @@
         reallyquiet = q;
     }
 
-
     /**
      * If true, report only and don't change any files.
      *
@@ -801,7 +783,7 @@
      * @param c command line which should be removed
      */
     protected void removeCommandline(Commandline c) {
-        vecCommandlines.removeElement(c);
+        commandlines.remove(c);
     }
 
     /**
@@ -825,9 +807,9 @@
         }
         this.configureCommandline(c);
         if (insertAtStart) {
-            vecCommandlines.insertElementAt(c, 0);
+            commandlines.add(0, c);
         } else {
-            vecCommandlines.addElement(c);
+            commandlines.add(c);
         }
     }
 
@@ -862,13 +844,12 @@
     }
 
     protected List<Module> getModules() {
-        @SuppressWarnings("unchecked")
-        final List<Module> clone = (List<Module>) modules.clone();
-        return clone;
+        return new ArrayList<>(modules);
     }
 
     public static final class Module {
         private String name;
+
         public void setName(String s) {
             name = s;
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/AbstractJarSignerTask.java b/src/main/org/apache/tools/ant/taskdefs/AbstractJarSignerTask.java
index b2fe8d4..2fadd12 100644
--- a/src/main/org/apache/tools/ant/taskdefs/AbstractJarSignerTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/AbstractJarSignerTask.java
@@ -37,6 +37,17 @@
  */
 
 public abstract class AbstractJarSignerTask extends Task {
+    /**
+     * error string for unit test verification: {@value}
+     */
+    public static final String ERROR_NO_SOURCE =
+        "jar must be set through jar attribute or nested filesets";
+
+    /**
+     * name of JDK program we are looking for
+     */
+    protected static final String JARSIGNER_COMMAND = "jarsigner";
+
     // CheckStyle:VisibilityModifier OFF - bc
     /**
      * The name of the jar file.
@@ -78,12 +89,7 @@
     /**
      * the filesets of the jars to sign
      */
-    protected Vector<FileSet> filesets = new Vector<FileSet>();
-    /**
-     * name of JDK program we are looking for
-     */
-    protected static final String JARSIGNER_COMMAND = "jarsigner";
-
+    protected Vector<FileSet> filesets = new Vector<>();
     // CheckStyle:VisibilityModifier ON
 
     /**
@@ -97,12 +103,6 @@
     private Environment sysProperties = new Environment();
 
     /**
-     * error string for unit test verification: {@value}
-     */
-    public static final String ERROR_NO_SOURCE = "jar must be set through jar attribute "
-            + "or nested filesets";
-
-    /**
      * Path holding all non-filesets of filesystem resources we want to sign.
      *
      * @since Ant 1.7
@@ -253,7 +253,7 @@
     private RedirectorElement createRedirector() {
         RedirectorElement result = new RedirectorElement();
         if (storepass != null) {
-            StringBuffer input = new StringBuffer(storepass).append('\n');
+            StringBuilder input = new StringBuilder(storepass).append('\n');
             if (keypass != null) {
                 input.append(keypass).append('\n');
             }
@@ -324,7 +324,6 @@
         addValue(cmd, "-J-D" + property.getContent());
     }
 
-
     /**
      * bind to a keystore if the attributes are there
      * @param cmd command to configure
@@ -373,8 +372,7 @@
      * @return a vector of FileSet instances
      */
     protected Vector<FileSet> createUnifiedSources() {
-        @SuppressWarnings("unchecked")
-        Vector<FileSet> sources = (Vector<FileSet>) filesets.clone();
+        Vector<FileSet> sources = new Vector<>(filesets);
         if (jar != null) {
             //we create a fileset with the source file.
             //this lets us combine our logic for handling output directories,
@@ -408,7 +406,7 @@
      * @since Ant 1.7
      */
     protected boolean hasResources() {
-        return path != null || filesets.size() > 0;
+        return !(path == null && filesets.isEmpty());
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/taskdefs/Ant.java b/src/main/org/apache/tools/ant/taskdefs/Ant.java
index 78d0689..1204795 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Ant.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Ant.java
@@ -19,14 +19,16 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.lang.reflect.Method;
-import java.util.Enumeration;
+import java.util.HashMap;
+import java.nio.file.Files;
 import java.util.HashSet;
-import java.util.Hashtable;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.Vector;
 
@@ -88,10 +90,10 @@
     private boolean inheritRefs = false;
 
     /** the properties to pass to the new project */
-    private Vector<Property> properties = new Vector<Property>();
+    private List<Property> properties = new Vector<>();
 
     /** the references to pass to the new project */
-    private Vector<Reference> references = new Vector<Reference>();
+    private List<Reference> references = new Vector<>();
 
     /** the temporary project created to run the build file */
     private Project newProject;
@@ -100,10 +102,10 @@
     private PrintStream out = null;
 
     /** the sets of properties to pass to the new project */
-    private Vector<PropertySet> propertySets = new Vector<PropertySet>();
+    private List<PropertySet> propertySets = new Vector<>();
 
     /** the targets to call on the new project */
-    private Vector<String> targets = new Vector<String>();
+    private List<String> targets = new Vector<>();
 
     /** whether the target attribute was specified **/
     private boolean targetAttributeSet = false;
@@ -165,6 +167,7 @@
     /**
      * Creates a Project instance for the project to call.
      */
+    @Override
     public void init() {
         newProject = getProject().createSubProject();
         newProject.setJavaVersionProperty();
@@ -196,18 +199,18 @@
 
         Iterator<BuildListener> iter = getBuildListeners();
         while (iter.hasNext()) {
-            newProject.addBuildListener((BuildListener) iter.next());
+            newProject.addBuildListener(iter.next());
         }
 
         if (output != null) {
-            File outfile = null;
+            File outfile;
             if (dir != null) {
                 outfile = FILE_UTILS.resolveFile(dir, output);
             } else {
                 outfile = getProject().resolveFile(output);
             }
             try {
-                out = new PrintStream(new FileOutputStream(outfile));
+                out = new PrintStream(Files.newOutputStream(outfile.toPath()));
                 DefaultLogger logger = new DefaultLogger();
                 logger.setMessageOutputLevel(Project.MSG_INFO);
                 logger.setOutputPrintStream(out);
@@ -247,6 +250,7 @@
      * @see Task#handleOutput(String)
      * @since Ant 1.5
      */
+    @Override
     public void handleOutput(String outputToHandle) {
         if (newProject != null) {
             newProject.demuxOutput(outputToHandle, false);
@@ -269,6 +273,7 @@
      * @see Task#handleInput(byte[], int, int)
      * @since Ant 1.6
      */
+    @Override
     public int handleInput(byte[] buffer, int offset, int length)
         throws IOException {
         if (newProject != null) {
@@ -285,6 +290,7 @@
      * @see Task#handleFlush(String)
      * @since Ant 1.5.2
      */
+    @Override
     public void handleFlush(String toFlush) {
         if (newProject != null) {
             newProject.demuxFlush(toFlush, false);
@@ -302,6 +308,7 @@
      * @see Task#handleErrorOutput(String)
      * @since Ant 1.5
      */
+    @Override
     public void handleErrorOutput(String errorOutputToHandle) {
         if (newProject != null) {
             newProject.demuxOutput(errorOutputToHandle, true);
@@ -318,6 +325,7 @@
      * @see Task#handleErrorFlush(String)
      * @since Ant 1.5.2
      */
+    @Override
     public void handleErrorFlush(String errorOutputToFlush) {
         if (newProject != null) {
             newProject.demuxFlush(errorOutputToFlush, true);
@@ -331,10 +339,11 @@
      * @throws BuildException if a target tries to call itself;
      * probably also if a BuildException is thrown by the new project.
      */
+    @Override
     public void execute() throws BuildException {
         File savedDir = dir;
         String savedAntFile = antFile;
-        Vector<String> locals = new VectorSet<String>(targets);
+        Vector<String> locals = new VectorSet<>(targets);
         try {
             getNewProject();
 
@@ -367,7 +376,7 @@
             antFile = file.getAbsolutePath();
 
             log("calling target(s) "
-                + ((locals.size() > 0) ? locals.toString() : "[default]")
+                + (!locals.isEmpty() ? locals.toString() : "[default]")
                 + " in build file " + antFile, Project.MSG_VERBOSE);
             newProject.setUserProperty(MagicNames.ANT_FILE, antFile);
 
@@ -378,14 +387,14 @@
                 && file.equals(getProject().resolveFile(thisAntFile))
                 && getOwningTarget() != null) {
 
-                if (getOwningTarget().getName().equals("")) {
-                    if (getTaskName().equals("antcall")) {
-                        throw new BuildException("antcall must not be used at"
-                                                 + " the top level.");
+                if ("".equals(getOwningTarget().getName())) {
+                    if ("antcall".equals(getTaskName())) {
+                        throw new BuildException(
+                            "antcall must not be used at the top level.");
                     }
-                    throw new BuildException(getTaskName() + " task at the"
-                                + " top level must not invoke"
-                                + " its own build file.");
+                    throw new BuildException(
+                        "%s task at the top level must not invoke its own build file.",
+                        getTaskName());
                 }
             }
 
@@ -396,7 +405,7 @@
                     ex, getLocation());
             }
 
-            if (locals.size() == 0) {
+            if (locals.isEmpty()) {
                 String defaultTarget = newProject.getDefaultTarget();
                 if (defaultTarget != null) {
                     locals.add(defaultTarget);
@@ -410,30 +419,25 @@
                 String owningTargetName = getOwningTarget().getName();
 
                 if (locals.contains(owningTargetName)) {
-                    throw new BuildException(getTaskName() + " task calling "
-                                             + "its own parent target.");
+                    throw new BuildException(
+                        "%s task calling its own parent target.",
+                        getTaskName());
                 }
-                boolean circular = false;
-                for (Iterator<String> it = locals.iterator();
-                     !circular && it.hasNext();) {
-                    Target other =
-                        getProject().getTargets().get(it.next());
-                    circular |= (other != null
-                                 && other.dependsOn(owningTargetName));
-                }
-                if (circular) {
-                    throw new BuildException(getTaskName()
-                                             + " task calling a target"
-                                             + " that depends on"
-                                             + " its parent target \'"
-                                             + owningTargetName
-                                             + "\'.");
+
+                final Map<String, Target> targetsMap = getProject().getTargets();
+
+                if (locals.stream().map(targetsMap::get)
+                    .filter(Objects::nonNull)
+                    .anyMatch(other -> other.dependsOn(owningTargetName))) {
+                    throw new BuildException(
+                        "%s task calling a target that depends on its parent target '%s'.",
+                        getTaskName(), owningTargetName);
                 }
             }
 
             addReferences();
 
-            if (locals.size() > 0 && !(locals.size() == 1
+            if (!locals.isEmpty() && !(locals.size() == 1
                                        && "".equals(locals.get(0)))) {
                 BuildException be = null;
                 try {
@@ -485,10 +489,10 @@
     private void overrideProperties() throws BuildException {
         // remove duplicate properties - last property wins
         // Needed for backward compatibility
-        Set<String> set = new HashSet<String>();
+        Set<String> set = new HashSet<>();
         for (int i = properties.size() - 1; i >= 0; --i) {
             Property p = properties.get(i);
-            if (p.getName() != null && !p.getName().equals("")) {
+            if (p.getName() != null && !"".equals(p.getName())) {
                 if (set.contains(p.getName())) {
                     properties.remove(i);
                 } else {
@@ -496,12 +500,9 @@
                 }
             }
         }
-        Enumeration<Property> e = properties.elements();
-        while (e.hasMoreElements()) {
-            Property p = e.nextElement();
-            p.setProject(newProject);
-            p.execute();
-        }
+        properties.stream().peek(p -> p.setProject(newProject))
+            .forEach(Property::execute);
+
         if (useNativeBasedir) {
             addAlmostAll(getProject().getInheritedProperties(),
                          PropertyType.INHERITED);
@@ -518,14 +519,13 @@
      * @throws BuildException if a reference does not have a refid.
      */
     private void addReferences() throws BuildException {
-        @SuppressWarnings("unchecked")
-        Hashtable<String, Object> thisReferences
-            = (Hashtable<String, Object>) getProject().getReferences().clone();
+        Map<String, Object> thisReferences =
+            new HashMap<>(getProject().getReferences());
         for (Reference ref : references) {
             String refid = ref.getRefId();
             if (refid == null) {
-                throw new BuildException("the refid attribute is required"
-                                         + " for reference elements");
+                throw new BuildException(
+                    "the refid attribute is required for reference elements");
             }
             if (!thisReferences.containsKey(refid)) {
                 log("Parent project doesn't contain any reference '"
@@ -545,7 +545,7 @@
         // Now add all references that are not defined in the
         // subproject, if inheritRefs is true
         if (inheritRefs) {
-            Hashtable<String, Object> newReferences = newProject.getReferences();
+            Map<String, Object> newReferences = newProject.getReferences();
             for (String key : thisReferences.keySet()) {
                 if (newReferences.containsKey(key)) {
                     continue;
@@ -577,32 +577,32 @@
         Class<?> c = orig.getClass();
         Object copy = orig;
         try {
-            Method cloneM = c.getMethod("clone", new Class[0]);
+            Method cloneM = c.getMethod("clone");
             if (cloneM != null) {
-                copy = cloneM.invoke(orig, new Object[0]);
+                copy = cloneM.invoke(orig);
                 log("Adding clone of reference " + oldKey, Project.MSG_DEBUG);
             }
         } catch (Exception e) {
             // not Clonable
         }
 
-
         if (copy instanceof ProjectComponent) {
             ((ProjectComponent) copy).setProject(newProject);
         } else {
             try {
                 Method setProjectM =
-                    c.getMethod("setProject", new Class[] {Project.class});
+                    c.getMethod("setProject", Project.class);
                 if (setProjectM != null) {
-                    setProjectM.invoke(copy, new Object[] {newProject});
+                    setProjectM.invoke(copy, newProject);
                 }
             } catch (NoSuchMethodException e) {
                 // ignore this if the class being referenced does not have
                 // a set project method.
             } catch (Exception e2) {
-                String msg = "Error setting new project instance for "
-                    + "reference with id " + oldKey;
-                throw new BuildException(msg, e2, getLocation());
+                throw new BuildException(
+                    "Error setting new project instance for "
+                        + "reference with id " + oldKey,
+                    e2, getLocation());
             }
         }
         newProject.addReference(newKey, copy);
@@ -618,29 +618,31 @@
      * user property or an inherited property).
      * @since Ant 1.8.0
      */
-    private void addAlmostAll(Hashtable<?, ?> props, PropertyType type) {
-        Enumeration<?> e = props.keys();
-        while (e.hasMoreElements()) {
-            String key = e.nextElement().toString();
+    private void addAlmostAll(Map<?, ?> props, PropertyType type) {
+        props.forEach((k, v) -> {
+            String key = k.toString();
             if (MagicNames.PROJECT_BASEDIR.equals(key)
-                || MagicNames.ANT_FILE.equals(key)) {
+                    || MagicNames.ANT_FILE.equals(key)) {
                 // basedir and ant.file get special treatment in execute()
-                continue;
+                return;
             }
-
-            String value = props.get(key).toString();
-            if (type == PropertyType.PLAIN) {
+            String value = v.toString();
+            switch (type) {
+            case PLAIN:
                 // don't re-set user properties, avoid the warning message
                 if (newProject.getProperty(key) == null) {
                     // no user property
                     newProject.setNewProperty(key, value);
                 }
-            } else if (type == PropertyType.USER) {
+                break;
+            case USER:
                 newProject.setUserProperty(key, value);
-            } else if (type == PropertyType.INHERITED) {
+                break;
+            case INHERITED:
                 newProject.setInheritedProperty(key, value);
+                break;
             }
-        }
+        });
     }
 
     /**
@@ -672,7 +674,7 @@
      * @param targetToAdd the name of the target to invoke.
      */
     public void setTarget(String targetToAdd) {
-        if (targetToAdd.equals("")) {
+        if ("".equals(targetToAdd)) {
             throw new BuildException("target attribute must not be empty");
         }
         targets.add(targetToAdd);
@@ -698,7 +700,7 @@
         Property p = new Property(true, getProject());
         p.setProject(getNewProject());
         p.setTaskName("property");
-        properties.addElement(p);
+        properties.add(p);
         return p;
     }
 
@@ -708,7 +710,7 @@
      * @param ref <code>Reference</code> to add.
      */
     public void addReference(Reference ref) {
-        references.addElement(ref);
+        references.add(ref);
     }
 
     /**
@@ -722,7 +724,7 @@
                 "nested target is incompatible with the target attribute");
         }
         String name = t.getName();
-        if (name.equals("")) {
+        if ("".equals(name)) {
             throw new BuildException("target name must not be empty");
         }
         targets.add(name);
@@ -735,7 +737,7 @@
      * @since Ant 1.6
      */
     public void addPropertyset(PropertySet ps) {
-        propertySets.addElement(ps);
+        propertySets.add(ps);
     }
 
     /**
@@ -761,14 +763,10 @@
      * Helper class that implements the nested &lt;reference&gt;
      * element of &lt;ant&gt; and &lt;antcall&gt;.
      */
+    @SuppressWarnings("deprecation")
     public static class Reference
         extends org.apache.tools.ant.types.Reference {
 
-        /** Creates a reference to be configured by Ant. */
-        public Reference() {
-            super();
-        }
-
         private String targetid = null;
 
         /**
@@ -824,10 +822,7 @@
         }
     }
 
-    private static final class PropertyType {
-        private PropertyType() {}
-        private static final PropertyType PLAIN = new PropertyType();
-        private static final PropertyType INHERITED = new PropertyType();
-        private static final PropertyType USER = new PropertyType();
+    private enum PropertyType {
+        PLAIN, INHERITED, USER
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/AntStructure.java b/src/main/org/apache/tools/ant/taskdefs/AntStructure.java
index 8554a2a..977921c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/AntStructure.java
+++ b/src/main/org/apache/tools/ant/taskdefs/AntStructure.java
@@ -19,15 +19,21 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.nio.file.Files;
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.Vector;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.IntrospectionHelper;
@@ -85,9 +91,9 @@
 
         PrintWriter out = null;
         try {
-            FileOutputStream fos = null;
+            OutputStream fos = null;
             try {
-                fos = new FileOutputStream(output);
+                fos = Files.newOutputStream(output.toPath());
                 out = new PrintWriter(new OutputStreamWriter(fos, "UTF8"));
             } catch (final UnsupportedEncodingException ue) {
                 FileUtils.close(fos);
@@ -121,8 +127,8 @@
             printer.printTail(out);
 
             if (out.checkError()) {
-                throw new IOException("Encountered an error writing Ant"
-                                      + " structure");
+                throw new IOException(
+                    "Encountered an error writing Ant structure");
             }
         } catch (final IOException ioe) {
             throw new BuildException("Error writing "
@@ -186,13 +192,15 @@
 
         private final Hashtable<String, String> visited = new Hashtable<String, String>();
 
+        @Override
         public void printTail(final PrintWriter out) {
             visited.clear();
         }
 
+        @Override
         public void printHead(final PrintWriter out, final Project p, final Hashtable<String, Class<?>> tasks,
                               final Hashtable<String, Class<?>> types) {
-            printHead(out, tasks.keys(), types.keys());
+            printHead(out, tasks.keySet(), types.keySet());
         }
 
 
@@ -202,36 +210,18 @@
          * <p>Basically this prints the XML declaration, defines some
          * entities and the project element.</p>
          */
-        private void printHead(final PrintWriter out, final Enumeration<String> tasks,
-                               final Enumeration<String> types) {
+        private void printHead(final PrintWriter out, final Set<String> tasks,
+                               final Set<String> types) {
             out.println("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
             out.println("<!ENTITY % boolean \"(true|false|on|off|yes|no)\">");
-            out.print("<!ENTITY % tasks \"");
-            boolean first = true;
-            while (tasks.hasMoreElements()) {
-                final String tName = tasks.nextElement();
-                if (!first) {
-                    out.print(" | ");
-                } else {
-                    first = false;
-                }
-                out.print(tName);
-            }
-            out.println("\">");
-            out.print("<!ENTITY % types \"");
-            first = true;
-            while (types.hasMoreElements()) {
-                final String typeName = types.nextElement();
-                if (!first) {
-                    out.print(" | ");
-                } else {
-                    first = false;
-                }
-                out.print(typeName);
-            }
-            out.println("\">");
 
-            out.println("");
+            out.println(tasks.stream().collect(
+                Collectors.joining(" | ", "<!ENTITY % tasks \"", "\">")));
+
+            out.println(types.stream().collect(
+                Collectors.joining(" | ", "<!ENTITY % types \"", "\">")));
+
+            out.println();
 
             out.print("<!ELEMENT project (target | extension-point | ");
             out.print(TASKS);
@@ -248,6 +238,7 @@
         /**
          * Prints the definition for the target element.
          */
+        @Override
         public void printTargetDecl(final PrintWriter out) {
             out.print("<!ELEMENT target (");
             out.print(TASKS);
@@ -281,6 +272,7 @@
         /**
          * Print the definition for a given element.
          */
+        @Override
         public void printElementDecl(final PrintWriter out, final Project p,
                                      final String name, final Class<?> element) {
 
@@ -289,7 +281,7 @@
             }
             visited.put(name, "");
 
-            IntrospectionHelper ih = null;
+            IntrospectionHelper ih;
             try {
                 ih = IntrospectionHelper.getHelper(p, element);
             } catch (final Throwable t) {
@@ -301,10 +293,10 @@
                 return;
             }
 
-            StringBuffer sb = new StringBuffer("<!ELEMENT ");
-            sb.append(name).append(" ");
+            StringBuilder sb =
+                new StringBuilder("<!ELEMENT ").append(name).append(" ");
 
-            if (org.apache.tools.ant.types.Reference.class.equals(element)) {
+            if (Reference.class.equals(element)) {
                 sb.append("EMPTY>").append(LINE_SEP);
                 sb.append("<!ATTLIST ").append(name);
                 sb.append(LINE_SEP).append("          id ID #IMPLIED");
@@ -314,40 +306,35 @@
                 return;
             }
 
-            final Vector<String> v = new Vector<String>();
+            final List<String> v = new ArrayList<>();
             if (ih.supportsCharacters()) {
-                v.addElement("#PCDATA");
+                v.add("#PCDATA");
             }
 
             if (TaskContainer.class.isAssignableFrom(element)) {
-                v.addElement(TASKS);
+                v.add(TASKS);
             }
 
             Enumeration<String> e = ih.getNestedElements();
             while (e.hasMoreElements()) {
-                v.addElement(e.nextElement());
+                v.add(e.nextElement());
             }
 
+            final Collector<CharSequence, ?, String> joinAlts =
+                Collectors.joining(" | ", "(", ")");
+
             if (v.isEmpty()) {
                 sb.append("EMPTY");
             } else {
-                sb.append("(");
-                final int count = v.size();
-                for (int i = 0; i < count; i++) {
-                    if (i != 0) {
-                        sb.append(" | ");
-                    }
-                    sb.append(v.elementAt(i));
-                }
-                sb.append(")");
-                if (count > 1 || !v.elementAt(0).equals("#PCDATA")) {
+                sb.append(v.stream().collect(joinAlts));
+                if (v.size() > 1 || !"#PCDATA".equals(v.get(0))) {
                     sb.append("*");
                 }
             }
             sb.append(">");
             out.println(sb);
 
-            sb = new StringBuffer("<!ATTLIST ");
+            sb = new StringBuilder("<!ATTLIST ");
             sb.append(name);
             sb.append(LINE_SEP).append("          id ID #IMPLIED");
 
@@ -361,29 +348,23 @@
                 sb.append(LINE_SEP).append("          ")
                     .append(attrName).append(" ");
                 final Class<?> type = ih.getAttributeType(attrName);
-                if (type.equals(java.lang.Boolean.class)
-                    || type.equals(java.lang.Boolean.TYPE)) {
+                if (type.equals(Boolean.class)
+                    || type.equals(Boolean.TYPE)) {
                     sb.append(BOOLEAN).append(" ");
                 } else if (Reference.class.isAssignableFrom(type)) {
                     sb.append("IDREF ");
                 } else if (EnumeratedAttribute.class.isAssignableFrom(type)) {
                     try {
                         final EnumeratedAttribute ea =
-                            (EnumeratedAttribute) type.newInstance();
+                            type.asSubclass(EnumeratedAttribute.class)
+                                .newInstance();
                         final String[] values = ea.getValues();
                         if (values == null
                             || values.length == 0
                             || !areNmtokens(values)) {
                             sb.append("CDATA ");
                         } else {
-                            sb.append("(");
-                            for (int i = 0; i < values.length; i++) {
-                                if (i != 0) {
-                                    sb.append(" | ");
-                                }
-                                sb.append(values[i]);
-                            }
-                            sb.append(") ");
+                            sb.append(Stream.of(values).collect(joinAlts));
                         }
                     } catch (final InstantiationException ie) {
                         sb.append("CDATA ");
@@ -392,20 +373,13 @@
                     }
                 } else if (Enum.class.isAssignableFrom(type)) {
                     try {
-                        final Object[] values = (Object[]) type.getMethod("values", (Class[])  null)
-                            .invoke(null, (Object[]) null);
+                        final Enum<?>[] values =
+                            (Enum<?>[]) type.getMethod("values").invoke(null);
                         if (values.length == 0) {
                             sb.append("CDATA ");
                         } else {
-                            sb.append('(');
-                            for (int i = 0; i < values.length; i++) {
-                                if (i != 0) {
-                                    sb.append(" | ");
-                                }
-                                sb.append(type.getMethod("name", (Class[]) null)
-                                          .invoke(values[i], (Object[]) null));
-                            }
-                            sb.append(") ");
+                            sb.append(Stream.of(values).map(Enum::name)
+                                .collect(joinAlts));
                         }
                     } catch (final Exception x) {
                         sb.append("CDATA ");
@@ -418,9 +392,7 @@
             sb.append(">").append(LINE_SEP);
             out.println(sb);
 
-            final int count = v.size();
-            for (int i = 0; i < count; i++) {
-                final String nestedName = v.elementAt(i);
+            for (String nestedName : v) {
                 if (!"#PCDATA".equals(nestedName)
                     && !TASKS.equals(nestedName)
                     && !TYPES.equals(nestedName)) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/Antlib.java b/src/main/org/apache/tools/ant/taskdefs/Antlib.java
index 8ff836a..519436e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Antlib.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Antlib.java
@@ -22,9 +22,7 @@
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
-
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.ComponentHelper;
 import org.apache.tools.ant.Project;
@@ -94,7 +92,7 @@
             UnknownElement ue =
                 parser.parseAntlibDescriptor(project, antlibResource);
             // Check name is "antlib"
-            if (!(ue.getTag().equals(TAG))) {
+            if (!(TAG.equals(ue.getTag()))) {
                 throw new BuildException(
                     "Unexpected tag " + ue.getTag() + " expecting "
                     + TAG, ue.getLocation());
@@ -116,7 +114,7 @@
     //
     private ClassLoader classLoader;
     private String uri = "";
-    private List<Object> tasks = new ArrayList<Object>();
+    private List<Task> tasks = new ArrayList<>();
 
     /**
      * Set the class loader for this antlib.
@@ -149,6 +147,7 @@
      *
      * @param nestedTask Nested task to execute in antlib
      */
+    @Override
     public void addTask(Task nestedTask) {
         tasks.add(nestedTask);
     }
@@ -157,10 +156,12 @@
      * Execute the nested tasks, setting the classloader for
      * any tasks that derive from Definer.
      */
+    @Override
     public void execute() {
         //TODO handle tasks added via #addTask()
-        for (Iterator<Object> i = tasks.iterator(); i.hasNext();) {
-            UnknownElement ue = (UnknownElement) i.next();
+
+        for (Task task : tasks) {
+            UnknownElement ue = (UnknownElement) task;
             setLocation(ue.getLocation());
             ue.maybeConfigure();
             Object configuredObject = ue.getRealThing();
@@ -169,9 +170,9 @@
             }
             if (!(configuredObject instanceof AntlibDefinition)) {
                 throw new BuildException(
-                    "Invalid task in antlib " + ue.getTag()
-                    + " " + configuredObject.getClass() + " does not "
-                    + "extend org.apache.tools.ant.taskdefs.AntlibDefinition");
+                    "Invalid task in antlib %s %s does not extend %s",
+                    ue.getTag(), configuredObject.getClass(),
+                    AntlibDefinition.class.getName());
             }
             AntlibDefinition def = (AntlibDefinition) configuredObject;
             def.setURI(uri);
diff --git a/src/main/org/apache/tools/ant/taskdefs/AntlibDefinition.java b/src/main/org/apache/tools/ant/taskdefs/AntlibDefinition.java
index eef3334..210f443 100644
--- a/src/main/org/apache/tools/ant/taskdefs/AntlibDefinition.java
+++ b/src/main/org/apache/tools/ant/taskdefs/AntlibDefinition.java
@@ -44,11 +44,11 @@
      * @throws BuildException if a reserved URI is used
      */
     public void setURI(String uri) throws BuildException {
-        if (uri.equals(ProjectHelper.ANT_CORE_URI)) {
+        if (ProjectHelper.ANT_CORE_URI.equals(uri)) {
             uri = "";
         }
         if (uri.startsWith("ant:")) {
-            throw new BuildException("Attempt to use a reserved URI " + uri);
+            throw new BuildException("Attempt to use a reserved URI %s", uri);
         }
         this.uri = uri;
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Apt.java b/src/main/org/apache/tools/ant/taskdefs/Apt.java
deleted file mode 100644
index ab527b8..0000000
--- a/src/main/org/apache/tools/ant/taskdefs/Apt.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- *  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.
- *
- */
-package org.apache.tools.ant.taskdefs;
-
-import java.io.File;
-import java.util.Vector;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.compilers.AptExternalCompilerAdapter;
-import org.apache.tools.ant.types.Path;
-import org.apache.tools.ant.types.Reference;
-import org.apache.tools.ant.util.JavaEnvUtils;
-
-/**
- * Apt Task for running the Annotation processing tool for JDK 1.5.  It derives
- * from the existing Javac task, and forces the compiler based on whether we're
- * executing internally, or externally.
- *
- * @since Ant 1.7
- */
-
-
-public class Apt
-        extends Javac {
-    private boolean compile = true;
-    private String factory;
-    private Path factoryPath;
-    private Vector<Option> options = new Vector<Option>();
-    private File preprocessDir;
-    /** The name of the apt tool. */
-    public static final String EXECUTABLE_NAME = "apt";
-    /** An warning message when ignoring compiler attribute. */
-    public static final String ERROR_IGNORING_COMPILER_OPTION
-        = "Ignoring compiler attribute for the APT task, as it is fixed";
-    /** A warning message if used with java &lt; 1.5. */
-    public static final String ERROR_WRONG_JAVA_VERSION
-        = "Apt task requires Java 1.5+";
-
-    /**
-     * exposed for debug messages
-     */
-    public static final String WARNING_IGNORING_FORK =
-        "Apt only runs in its own JVM; fork=false option ignored";
-
-    /**
-     * The nested option element.
-     */
-    public static final class Option {
-        private String name;
-        private String value;
-
-        /** Constructor for Option */
-        public Option() {
-            //default
-        }
-
-        /**
-         * Get the name attribute.
-         * @return the name attribute.
-         */
-        public String getName() {
-            return name;
-        }
-
-        /**
-         * Set the name attribute.
-         * @param name the name of the option.
-         */
-        public void setName(String name) {
-            this.name = name;
-        }
-
-        /**
-         * Get the value attribute.
-         * @return the value attribute.
-         */
-        public String getValue() {
-            return value;
-        }
-
-        /**
-         * Set the value attribute.
-         * @param value the value of the option.
-         */
-        public void setValue(String value) {
-            this.value = value;
-        }
-    }
-
-    /**
-     * Constructor for Apt task.
-     * This sets the apt compiler adapter as the compiler in the super class.
-     */
-    public Apt() {
-        super();
-        super.setCompiler(AptExternalCompilerAdapter.class.getName());
-        super.setFork(true);
-    }
-
-    /**
-     * Get the name of the apt executable.
-     *
-     * @return the name of the executable.
-     */
-    public String getAptExecutable() {
-        String exe = getExecutable();
-        return exe != null ? exe :
-            JavaEnvUtils.getJdkExecutable(EXECUTABLE_NAME);
-    }
-
-    /**
-     * Set the compiler.
-     * This is not allowed and a warning log message is made.
-     * @param compiler not used.
-     */
-    public void setCompiler(String compiler) {
-        log(ERROR_IGNORING_COMPILER_OPTION, Project.MSG_WARN);
-    }
-
-    /**
-     * Set the fork attribute.
-     * Non-forking APT is highly classpath dependent and appears to be too
-     * brittle to work. The sole reason this attribute is retained
-     * is the superclass does it
-     * @param fork if false; warn the option is ignored.
-     */
-    public void setFork(boolean fork) {
-        if (!fork) {
-            log(WARNING_IGNORING_FORK, Project.MSG_WARN);
-        }
-    }
-
-    /**
-     * Get the compiler class name.
-     * @return the compiler class name.
-     */
-    public String getCompiler() {
-        return super.getCompiler();
-    }
-
-    /**
-     * Get the compile option for the apt compiler.
-     * If this is false the "-nocompile" argument will be used.
-     * @return the value of the compile option.
-     */
-    public boolean isCompile() {
-        return compile;
-    }
-
-    /**
-     * Set the compile option for the apt compiler.
-     * Default value is true.
-     * @param compile if true set the compile option.
-     */
-    public void setCompile(boolean compile) {
-        this.compile = compile;
-    }
-
-    /**
-     * Get the factory option for the apt compiler.
-     * If this is non-null the "-factory" argument will be used.
-     * @return the value of the factory option.
-     */
-    public String getFactory() {
-        return factory;
-    }
-
-    /**
-     * Set the factory option for the apt compiler.
-     * Default value is null.
-     * @param factory the classname of the factory.
-     */
-    public void setFactory(String factory) {
-        this.factory = factory;
-    }
-
-    /**
-     * Add a reference to a path to the factoryPath attribute.
-     * @param ref a reference to a path.
-     */
-    public void setFactoryPathRef(Reference ref) {
-        createFactoryPath().setRefid(ref);
-    }
-
-    /**
-     * Add a path to the factoryPath attribute.
-     * @return a path to be configured.
-     */
-    public Path createFactoryPath() {
-        if (factoryPath == null) {
-            factoryPath = new Path(getProject());
-        }
-        return factoryPath.createPath();
-    }
-
-    /**
-     * Get the factory path attribute.
-     * If this is not null, the "-factorypath" argument will be used.
-     * The default value is null.
-     * @return the factory path attribute.
-     */
-    public Path getFactoryPath() {
-        return factoryPath;
-    }
-
-    /**
-     * Create a nested option.
-     * @return an option to be configured.
-     */
-    public Option createOption() {
-        Option opt = new Option();
-        options.add(opt);
-        return opt;
-    }
-
-    /**
-     * Get the options to the compiler.
-     * Each option will use '"-E" name ["=" value]' argument.
-     * @return the options.
-     */
-    public Vector<Option> getOptions() {
-        return options;
-    }
-
-    /**
-     * Get the preprocessdir attribute.
-     * This corresponds to the "-s" argument.
-     * The default value is null.
-     * @return the preprocessdir attribute.
-     */
-    public File getPreprocessDir() {
-        return preprocessDir;
-    }
-
-    /**
-     * Set the preprocessdir attribute.
-     * @param preprocessDir where to place processor generated source files.
-     */
-    public void setPreprocessDir(File preprocessDir) {
-        this.preprocessDir = preprocessDir;
-    }
-
-    /**
-     * Do the compilation.
-     * @throws BuildException on error.
-     */
-    public void execute()
-            throws BuildException {
-        if (JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_1_8)) {
-           throw new BuildException("apt does not exist under Java 1.8 and higher");
-        }
-        super.execute();
-    }
-}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Available.java b/src/main/org/apache/tools/ant/taskdefs/Available.java
index d8eb82f..23496a0 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Available.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Available.java
@@ -193,9 +193,9 @@
      *             the type in its own class.
      * @param type the type of resource
      */
+    @Deprecated
     public void setType(String type) {
-        log("DEPRECATED - The setType(String) method has been deprecated."
-            + " Use setType(Available.FileDir) instead.",
+        log("DEPRECATED - The setType(String) method has been deprecated. Use setType(Available.FileDir) instead.",
             Project.MSG_WARN);
         this.type = new FileDir();
         this.type.setValue(type);
@@ -227,6 +227,7 @@
      *
      * @exception BuildException if the task is not configured correctly.
      */
+    @Override
     public void execute() throws BuildException {
         if (property == null) {
             throw new BuildException("property attribute is required",
@@ -261,17 +262,19 @@
      * @return boolean is the resource is available.
      * @exception BuildException if the condition is not configured correctly
      */
+    @Override
     public boolean eval() throws BuildException {
         try {
             if (classname == null && file == null && resource == null) {
-                throw new BuildException("At least one of (classname|file|"
-                                         + "resource) is required", getLocation());
+                throw new BuildException(
+                    "At least one of (classname|file|resource) is required",
+                    getLocation());
             }
             if (type != null) {
                 if (file == null) {
-                    throw new BuildException("The type attribute is only valid "
-                                             + "when specifying the file "
-                                             + "attribute.", getLocation());
+                    throw new BuildException(
+                        "The type attribute is only valid when specifying the file attribute.",
+                        getLocation());
                 }
             }
             if (classpath != null) {
@@ -284,13 +287,13 @@
             } else {
                 setTaskName("available");
             }
-            if ((classname != null) && !checkClass(classname)) {
+            if (!(classname == null || checkClass(classname))) {
                 log("Unable to load class " + classname + appendix,
                     Project.MSG_VERBOSE);
                 return false;
             }
             if ((file != null) && !checkFile()) {
-                StringBuffer buf = new StringBuffer("Unable to find ");
+                StringBuilder buf = new StringBuilder("Unable to find ");
                 if (type != null) {
                     buf.append(type).append(' ');
                 }
@@ -334,62 +337,64 @@
     private boolean checkFile() {
         if (filepath == null) {
             return checkFile(file, filename);
-        } else {
-            String[] paths = filepath.list();
-            for (int i = 0; i < paths.length; ++i) {
-                log("Searching " + paths[i], Project.MSG_VERBOSE);
-                File path = new File(paths[i]);
+        }
+        String[] paths = filepath.list();
+        for (String p : paths) {
+            log("Searching " + p, Project.MSG_VERBOSE);
+            File path = new File(p);
 
-                // **   full-pathname specified == path in list
-                // **   simple name specified   == path in list
-                if (path.exists()
-                    && (filename.equals(paths[i])
-                        || filename.equals(path.getName()))) {
-                    if (type == null) {
-                        log("Found: " + path, Project.MSG_VERBOSE);
-                        return true;
-                    } else if (type.isDir()
-                               && path.isDirectory()) {
-                        log("Found directory: " + path, Project.MSG_VERBOSE);
-                        return true;
-                    } else if (type.isFile()
-                               && path.isFile()) {
-                        log("Found file: " + path, Project.MSG_VERBOSE);
-                        return true;
-                    }
-                    // not the requested type
-                    return false;
+            // **   full-pathname specified == path in list
+            // **   simple name specified   == path in list
+            if (path.exists()
+                && (filename.equals(p)
+                    || filename.equals(path.getName()))) {
+                if (type == null) {
+                    log("Found: " + path, Project.MSG_VERBOSE);
+                    return true;
                 }
-                File parent = path.getParentFile();
-                // **   full-pathname specified == parent dir of path in list
-                if (parent != null && parent.exists()
-                    && filename.equals(parent.getAbsolutePath())) {
-                    if (type == null) {
-                        log("Found: " + parent, Project.MSG_VERBOSE);
-                        return true;
-                    } else if (type.isDir()) {
-                        log("Found directory: " + parent, Project.MSG_VERBOSE);
-                        return true;
-                    }
-                    // not the requested type
-                    return false;
+                if (type.isDir()
+                           && path.isDirectory()) {
+                    log("Found directory: " + path, Project.MSG_VERBOSE);
+                    return true;
                 }
-                // **   simple name specified   == path in list + name
-                if (path.exists() && path.isDirectory()) {
-                    if (checkFile(new File(path, filename),
-                                  filename + " in " + path)) {
-                        return true;
-                    }
+                if (type.isFile()
+                           && path.isFile()) {
+                    log("Found file: " + path, Project.MSG_VERBOSE);
+                    return true;
                 }
+                // not the requested type
+                return false;
+            }
+            File parent = path.getParentFile();
+            // **   full-pathname specified == parent dir of path in list
+            if (parent != null && parent.exists()
+                && filename.equals(parent.getAbsolutePath())) {
+                if (type == null) {
+                    log("Found: " + parent, Project.MSG_VERBOSE);
+                    return true;
+                }
+                if (type.isDir()) {
+                    log("Found directory: " + parent, Project.MSG_VERBOSE);
+                    return true;
+                }
+                // not the requested type
+                return false;
+            }
+            // **   simple name specified   == path in list + name
+            if (path.exists() && path.isDirectory()) {
+                if (checkFile(new File(path, filename),
+                              filename + " in " + path)) {
+                    return true;
+                }
+            }
 
-                // **   simple name specified   == parent dir + name
-                while (searchParents && parent != null && parent.exists()) {
-                    if (checkFile(new File(parent, filename),
-                                  filename + " in " + parent)) {
-                        return true;
-                    }
-                    parent = parent.getParentFile();
+            // **   simple name specified   == parent dir + name
+            while (searchParents && parent != null && parent.exists()) {
+                if (checkFile(new File(parent, filename),
+                              filename + " in " + parent)) {
+                    return true;
                 }
+                parent = parent.getParentFile();
             }
         }
         return false;
@@ -405,7 +410,8 @@
                     log("Found directory: " + text, Project.MSG_VERBOSE);
                 }
                 return f.isDirectory();
-            } else if (type.isFile()) {
+            }
+            if (type.isFile()) {
                 if (f.isFile()) {
                     log("Found file: " + text, Project.MSG_VERBOSE);
                 }
@@ -494,6 +500,7 @@
          * @see EnumeratedAttribute#getValues
          * {@inheritDoc}.
          */
+        @Override
         public String[] getValues() {
             return VALUES;
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/BUnzip2.java b/src/main/org/apache/tools/ant/taskdefs/BUnzip2.java
index e4a7995..0122e95 100644
--- a/src/main/org/apache/tools/ant/taskdefs/BUnzip2.java
+++ b/src/main/org/apache/tools/ant/taskdefs/BUnzip2.java
@@ -20,9 +20,10 @@
 
 
 import java.io.BufferedInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.util.FileUtils;
@@ -60,12 +61,12 @@
             log("Expanding " + srcResource.getName() + " to "
                 + dest.getAbsolutePath());
 
-            FileOutputStream out = null;
+            OutputStream out = null;
             CBZip2InputStream zIn = null;
             InputStream fis = null;
             BufferedInputStream bis = null;
             try {
-                out = new FileOutputStream(dest);
+                out = Files.newOutputStream(dest.toPath());
                 fis = srcResource.getInputStream();
                 bis = new BufferedInputStream(fis);
                 int b = bis.read();
diff --git a/src/main/org/apache/tools/ant/taskdefs/BZip2.java b/src/main/org/apache/tools/ant/taskdefs/BZip2.java
index f5944df..be03772 100644
--- a/src/main/org/apache/tools/ant/taskdefs/BZip2.java
+++ b/src/main/org/apache/tools/ant/taskdefs/BZip2.java
@@ -20,8 +20,8 @@
 
 
 import java.io.BufferedOutputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
+import java.nio.file.Files;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.util.FileUtils;
@@ -44,7 +44,7 @@
         CBZip2OutputStream zOut = null;
         try {
             BufferedOutputStream bos =
-                new BufferedOutputStream(new FileOutputStream(zipFile));
+                new BufferedOutputStream(Files.newOutputStream(zipFile.toPath()));
             bos.write('B');
             bos.write('Z');
             zOut = new CBZip2OutputStream(bos);
diff --git a/src/main/org/apache/tools/ant/taskdefs/Basename.java b/src/main/org/apache/tools/ant/taskdefs/Basename.java
index 0415af7..a02822c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Basename.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Basename.java
@@ -85,6 +85,7 @@
      * @throws BuildException if required attributes are not supplied
      * property and attribute are required attributes
      */
+    @Override
     public void execute() throws BuildException {
         if (property == null) {
             throw new BuildException("property attribute required", getLocation());
@@ -92,19 +93,21 @@
         if (file == null) {
             throw new BuildException("file attribute required", getLocation());
         }
-        String value = file.getName();
-        if (suffix != null && value.endsWith(suffix)) {
-            // if the suffix does not starts with a '.' and the
-            // char preceding the suffix is a '.', we assume the user
-            // wants to remove the '.' as well (see docs)
-            int pos = value.length() - suffix.length();
-            if (pos > 0 && suffix.charAt(0) != '.'
-                && value.charAt(pos - 1) == '.') {
-                pos--;
-            }
-            value = value.substring(0, pos);
+        getProject().setNewProperty(property,
+            removeExtension(file.getName(), suffix));
+    }
+
+    private String removeExtension(String s, String ext) {
+        if (ext == null || !s.endsWith(ext)) {
+            return s;
         }
-        getProject().setNewProperty(property, value);
+        int clipFrom = s.length() - ext.length();
+        // if the suffix does not starts with a '.' and the
+        // char preceding the suffix is a '.', we assume the user
+        // wants to remove the '.' as well (see docs)
+        if (ext.charAt(0) != '.' && clipFrom > 0 && s.charAt(clipFrom - 1) == '.') {
+            clipFrom -= 1;
+        }
+        return s.substring(0, clipFrom);
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/BindTargets.java b/src/main/org/apache/tools/ant/taskdefs/BindTargets.java
index 3c07e28..432a379 100644
--- a/src/main/org/apache/tools/ant/taskdefs/BindTargets.java
+++ b/src/main/org/apache/tools/ant/taskdefs/BindTargets.java
@@ -18,8 +18,8 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.ProjectHelper;
@@ -54,13 +54,8 @@
     }
 
     public void setTargets(final String target) {
-        final String[] inputs = target.split(",");
-        for (int i = 0; i < inputs.length; i++) {
-            final String input = inputs[i].trim();
-            if (input.length() > 0) {
-                targets.add(input);
-            }
-        }
+        Stream.of(target.split(",")).map(String::trim).filter(s -> !s.isEmpty())
+            .forEach(targets::add);
     }
 
     @Override
@@ -81,10 +76,9 @@
         final ProjectHelper helper = (ProjectHelper) getProject().getReference(
                 ProjectHelper.PROJECTHELPER_REFERENCE);
 
-        for (final Iterator<String> itTarget = targets.iterator(); itTarget.hasNext();) {
+        for (String target : targets) {
             helper.getExtensionStack().add(new String[] {extensionPoint,
-                    itTarget.next(), onMissingExtensionPoint.name()});
+                target, onMissingExtensionPoint.name()});
         }
-
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/BuildNumber.java b/src/main/org/apache/tools/ant/taskdefs/BuildNumber.java
index 7a66125..7799930 100644
--- a/src/main/org/apache/tools/ant/taskdefs/BuildNumber.java
+++ b/src/main/org/apache/tools/ant/taskdefs/BuildNumber.java
@@ -18,13 +18,13 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
 import java.util.Properties;
 
 import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
 import org.apache.tools.ant.util.FileUtils;
 
@@ -39,8 +39,7 @@
  * @since Ant 1.5
  * @ant.task name="buildnumber"
  */
-public class BuildNumber
-     extends Task {
+public class BuildNumber extends Task {
     /**
      * The name of the property in which the build number is stored.
      */
@@ -54,7 +53,6 @@
     /** The File in which the build number is stored.  */
     private File myFile;
 
-
     /**
      * The file in which the build number is stored. Defaults to
      * "build.number" if not specified.
@@ -65,14 +63,13 @@
         myFile = file;
     }
 
-
     /**
      * Run task.
      *
      * @exception BuildException if an error occurs
      */
-    public void execute()
-         throws BuildException {
+    @Override
+    public void execute() throws BuildException {
         File savedFile = myFile; // may be altered in validate
 
         validate();
@@ -84,26 +81,12 @@
             String.valueOf(buildNumber + 1));
 
         // Write the properties file back out
-        FileOutputStream output = null;
 
-        try {
-            output = new FileOutputStream(myFile);
-
-            final String header = "Build Number for ANT. Do not edit!";
-
-            properties.store(output, header);
+        try (OutputStream output = Files.newOutputStream(myFile.toPath())) {
+            properties.store(output, "Build Number for ANT. Do not edit!");
         } catch (final IOException ioe) {
-            final String message = "Error while writing " + myFile;
-
-            throw new BuildException(message, ioe);
+            throw new BuildException("Error while writing " + myFile, ioe);
         } finally {
-            if (null != output) {
-                try {
-                    output.close();
-                } catch (final IOException ioe) {
-                    log("error closing output stream " + ioe, Project.MSG_ERR);
-                }
-            }
             myFile = savedFile;
         }
 
@@ -112,7 +95,6 @@
             String.valueOf(buildNumber));
     }
 
-
     /**
      * Utility method to retrieve build number from properties object.
      *
@@ -129,43 +111,28 @@
         try {
             return Integer.parseInt(buildNumber);
         } catch (final NumberFormatException nfe) {
-            final String message =
-                myFile + " contains a non integer build number: " + buildNumber;
-            throw new BuildException(message, nfe);
+            throw new BuildException(
+                myFile + " contains a non integer build number: " + buildNumber,
+                nfe);
         }
     }
 
-
     /**
      * Utility method to load properties from file.
      *
      * @return the loaded properties
      * @throws BuildException if something goes wrong
      */
-    private Properties loadProperties()
-         throws BuildException {
-        FileInputStream input = null;
-
-        try {
+    private Properties loadProperties() throws BuildException {
+        try (InputStream input = Files.newInputStream(myFile.toPath())) {
             final Properties properties = new Properties();
-
-            input = new FileInputStream(myFile);
             properties.load(input);
             return properties;
         } catch (final IOException ioe) {
             throw new BuildException(ioe);
-        } finally {
-            if (null != input) {
-                try {
-                    input.close();
-                } catch (final IOException ioe) {
-                    log("error closing input stream " + ioe, Project.MSG_ERR);
-                }
-            }
         }
     }
 
-
     /**
      * Validate that the task parameters are valid.
      *
@@ -181,21 +148,18 @@
             try {
                 FILE_UTILS.createNewFile(myFile);
             } catch (final IOException ioe) {
-                final String message =
-                    myFile + " doesn't exist and new file can't be created.";
-                throw new BuildException(message, ioe);
+                throw new BuildException(
+                    myFile + " doesn't exist and new file can't be created.",
+                    ioe);
             }
         }
 
         if (!myFile.canRead()) {
-            final String message = "Unable to read from " + myFile + ".";
-            throw new BuildException(message);
+            throw new BuildException("Unable to read from " + myFile + ".");
         }
 
         if (!myFile.canWrite()) {
-            final String message = "Unable to write to " + myFile + ".";
-            throw new BuildException(message);
+            throw new BuildException("Unable to write to " + myFile + ".");
         }
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/CVSPass.java b/src/main/org/apache/tools/ant/taskdefs/CVSPass.java
index e39adef..19a6a41 100644
--- a/src/main/org/apache/tools/ant/taskdefs/CVSPass.java
+++ b/src/main/org/apache/tools/ant/taskdefs/CVSPass.java
@@ -82,6 +82,7 @@
      *
      * @exception BuildException if something goes wrong with the build
      */
+    @Override
     public final void execute() throws BuildException {
         if (cvsRoot == null) {
             throw new BuildException("cvsroot is required");
@@ -97,7 +98,7 @@
         BufferedReader reader = null;
         BufferedWriter writer = null;
         try {
-            StringBuffer buf = new StringBuffer();
+            StringBuilder buf = new StringBuilder();
 
             if (passFile.exists()) {
                 reader = new BufferedReader(new FileReader(passFile));
@@ -129,7 +130,7 @@
     }
 
     private final String mangle(String password) {
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         for (int i = 0; i < password.length(); i++) {
             buf.append(shifts[password.charAt(i)]);
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Checksum.java b/src/main/org/apache/tools/ant/taskdefs/Checksum.java
index bd95e93..887081d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Checksum.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Checksum.java
@@ -19,10 +19,11 @@
 
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
 import java.security.DigestInputStream;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -70,6 +71,7 @@
             super.add(u);
             super.add(Type.FILE);
         }
+        @Override
         public void add(ResourceCollection rc) {
             u.add(rc);
         }
@@ -109,14 +111,14 @@
      * Key:   java.util.File (source file)
      * Value: java.lang.String (digest)
      */
-    private Map<File, byte[]> allDigests = new HashMap<File, byte[]>();
+    private Map<File, byte[]> allDigests = new HashMap<>();
     /**
      * Holds relative file names for all files (always with a forward slash).
      * This is used to calculate the total hash.
      * Key:   java.util.File (source file)
      * Value: java.lang.String (relative file name)
      */
-    private Map<File, String> relativeFilePaths = new HashMap<File, String>();
+    private Map<File, String> relativeFilePaths = new HashMap<>();
     /**
      * Property where totalChecksum gets set.
      */
@@ -137,7 +139,7 @@
     /**
      * Stores SourceFile, DestFile pairs and SourceFile, Property String pairs.
      */
-    private Hashtable<File, Object> includeFileMap = new Hashtable<File, Object>();
+    private Hashtable<File, Object> includeFileMap = new Hashtable<>();
     /**
      * Message Digest instance
      */
@@ -293,13 +295,13 @@
      * Calculate the checksum(s).
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         isCondition = false;
         boolean value = validateAndExecute();
         if (verifyProperty != null) {
-            getProject().setNewProperty(
-                verifyProperty,
-                (value ? Boolean.TRUE.toString() : Boolean.FALSE.toString()));
+            getProject().setNewProperty(verifyProperty,
+                Boolean.toString(value));
         }
     }
 
@@ -310,6 +312,7 @@
      * false otherwise.
      * @throws BuildException on error
      */
+    @Override
     public boolean eval() throws BuildException {
         isCondition = true;
         return validateAndExecute();
@@ -385,7 +388,7 @@
         }
         if (fileext == null) {
             fileext = "." + algorithm;
-        } else if (fileext.trim().length() == 0) {
+        } else if (fileext.trim().isEmpty()) {
             throw new BuildException("File extension when specified must not be an empty string");
         }
         try {
@@ -462,8 +465,7 @@
             // This directory will exist
             directory = file.getParentFile();
         }
-        File checksumFile = new File(directory, file.getName() + fileext);
-        return checksumFile;
+        return new File(directory, file.getName() + fileext);
     }
 
     /**
@@ -471,8 +473,8 @@
      */
     private boolean generateChecksums() throws BuildException {
         boolean checksumMatches = true;
-        FileInputStream fis = null;
-        FileOutputStream fos = null;
+        InputStream fis = null;
+        OutputStream fos = null;
         byte[] buf = new byte[readBufferSize];
         try {
             for (Map.Entry<File, Object> e : includeFileMap.entrySet()) {
@@ -481,7 +483,7 @@
                 if (!isCondition) {
                     log("Calculating " + algorithm + " checksum for " + src, Project.MSG_VERBOSE);
                 }
-                fis = new FileInputStream(src);
+                fis = Files.newInputStream(src.toPath());
                 DigestInputStream dis = new DigestInputStream(fis,
                                                               messageDigest);
                 while (dis.read(buf, 0, readBufferSize) != -1) {
@@ -497,7 +499,7 @@
                 String checksum = createDigestString(fileDigest);
                 //can either be a property name string or a file
                 Object destination = e.getValue();
-                if (destination instanceof java.lang.String) {
+                if (destination instanceof String) {
                     String prop = (String) destination;
                     if (isCondition) {
                         checksumMatches
@@ -505,7 +507,7 @@
                     } else {
                         getProject().setNewProperty(prop, checksum);
                     }
-                } else if (destination instanceof java.io.File) {
+                } else if (destination instanceof File) {
                     if (isCondition) {
                         File existingFile = (File) destination;
                         if (existingFile.exists()) {
@@ -523,7 +525,7 @@
                         }
                     } else {
                         File dest = (File) destination;
-                        fos = new FileOutputStream(dest);
+                        fos = Files.newOutputStream(dest.toPath());
                         fos.write(format.format(new Object[] {
                                                     checksum,
                                                     src.getName(),
@@ -549,14 +551,9 @@
                 File[] keyArray = allDigests.keySet().toArray(new File[allDigests.size()]);
                 // File is Comparable, but sort-order is platform
                 // dependent (case-insensitive on Windows)
-                Arrays.sort(keyArray, new Comparator<File>() {
-                        public int compare(File f1, File f2) {
-                            return f1 == null ? (f2 == null ? 0 : -1)
-                                : (f2 == null ? 1
-                                   : getRelativeFilePath(f1)
-                                   .compareTo(getRelativeFilePath(f2)));
-                        }
-                    });
+                Arrays.sort(keyArray, Comparator.nullsFirst(
+                    Comparator.comparing(this::getRelativeFilePath)));
+
                 // Loop over the checksums and generate a total hash.
                 messageDigest.reset();
                 for (File src : keyArray) {
@@ -581,11 +578,11 @@
     }
 
     private String createDigestString(byte[] fileDigest) {
-        StringBuffer checksumSb = new StringBuffer();
+        StringBuilder checksumSb = new StringBuilder();
         for (int i = 0; i < fileDigest.length; i++) {
             String hexStr = Integer.toHexString(BYTE_MASK & fileDigest[i]);
             if (hexStr.length() < 2) {
-                checksumSb.append("0");
+                checksumSb.append('0');
             }
             checksumSb.append(hexStr);
         }
@@ -629,20 +626,15 @@
      * @since 1.7
      */
     private String readChecksum(File f) {
-        BufferedReader diskChecksumReader = null;
-        try {
-            diskChecksumReader = new BufferedReader(new FileReader(f));
+        try (BufferedReader diskChecksumReader =
+            new BufferedReader(new FileReader(f))) {
             Object[] result = format.parse(diskChecksumReader.readLine());
             if (result == null || result.length == 0 || result[0] == null) {
                 throw new BuildException("failed to find a checksum");
             }
             return (String) result[0];
-        } catch (IOException e) {
+        } catch (IOException | ParseException e) {
             throw new BuildException("Couldn't read checksum file " + f, e);
-        } catch (ParseException e) {
-            throw new BuildException("Couldn't read checksum file " + f, e);
-        } finally {
-            FileUtils.close(diskChecksumReader);
         }
     }
 
@@ -650,13 +642,12 @@
      * @since Ant 1.8.2
      */
     private String getRelativeFilePath(File f) {
-        String path = (String) relativeFilePaths.get(f);
+        String path = relativeFilePaths.get(f);
         if (path == null) {
             //bug 37386. this should not occur, but it has, once.
-            throw new BuildException("Internal error: "
-                                     + "relativeFilePaths could not match file "
-                                     + f + "\n"
-                                     + "please file a bug report on this");
+            throw new BuildException(
+                "Internal error: relativeFilePaths could not match file %s\nplease file a bug report on this",
+                f);
         }
         return path;
     }
@@ -678,11 +669,6 @@
             formatMap.put(SVF, new MessageFormat("MD5 ({1}) = {0}"));
         }
 
-        /** Constructor for FormatElement */
-        public FormatElement() {
-            super();
-        }
-
         /**
          * Get the default value - CHECKSUM.
          * @return the defaul value.
@@ -698,13 +684,14 @@
          * @return a <code>MessageFormat</code> object.
          */
         public MessageFormat getFormat() {
-            return (MessageFormat) formatMap.get(getValue());
+            return formatMap.get(getValue());
         }
 
         /**
          * Get the valid values.
          * @return an array of values.
          */
+        @Override
         public String[] getValues() {
             return new String[] {CHECKSUM, MD5SUM, SVF};
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Chmod.java b/src/main/org/apache/tools/ant/taskdefs/Chmod.java
index ac0c3d8..a83dcd0 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Chmod.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Chmod.java
@@ -58,6 +58,7 @@
      * @param project the project for this task.
      * @see org.apache.tools.ant.ProjectComponent#setProject
      */
+    @Override
     public void setProject(Project project) {
         super.setProject(project);
         defaultSet.setProject(project);
@@ -77,6 +78,7 @@
      * The directory which holds the files whose permissions must be changed.
      * @param src the directory.
      */
+    @Override
     public void setDir(File src) {
         defaultSet.setDir(src);
     }
@@ -154,6 +156,7 @@
     /**
      * Check the attributes and nested elements.
      */
+    @Override
     protected void checkConfiguration() {
         if (!havePerm) {
             throw new BuildException("Required attribute perm not set in chmod",
@@ -170,6 +173,7 @@
      * Carry out the chmoding.
      * @throws BuildException on error.
      */
+    @Override
     public void execute() throws BuildException {
         /*
          * In Ant 1.1, <chmod dir="foo" /> means, change the permissions
@@ -188,7 +192,7 @@
         } else if (isValidOs()) {
             // we are chmodding the given directory
             Execute execute = prepareExec();
-            Commandline cloned = (Commandline) cmdl.clone();
+            Commandline cloned = cmdl.clone();
             cloned.createArgument().setValue(defaultSet.getDir(getProject())
                                              .getPath());
             try {
@@ -210,6 +214,7 @@
      * @throws BuildException always.
      * @ant.attribute ignore="true"
      */
+    @Override
     public void setExecutable(String e) {
         throw new BuildException(getTaskType()
             + " doesn\'t support the executable attribute", getLocation());
@@ -222,6 +227,7 @@
      * @throws BuildException always.
      * @ant.attribute ignore="true"
      */
+    @Override
     public void setCommand(Commandline cmdl) {
         throw new BuildException(getTaskType()
             + " doesn\'t support the command attribute", getLocation());
@@ -233,6 +239,7 @@
      * @throws BuildException always.
      * @ant.attribute ignore="true"
      */
+    @Override
     public void setSkipEmptyFilesets(boolean skip) {
         throw new BuildException(getTaskType()
             + " doesn\'t support the skipemptyfileset attribute", getLocation());
@@ -244,6 +251,7 @@
      * @throws BuildException always.
      * @ant.attribute ignore="true"
      */
+    @Override
     public void setAddsourcefile(boolean b) {
         throw new BuildException(getTaskType()
             + " doesn\'t support the addsourcefile attribute", getLocation());
@@ -254,6 +262,7 @@
      * Always include unix.
      * @return true if the os is valid.
      */
+    @Override
     protected boolean isValidOs() {
         return getOs() == null && getOsFamily() == null
             ? Os.isFamily(Os.FAMILY_UNIX) : super.isValidOs();
diff --git a/src/main/org/apache/tools/ant/taskdefs/Classloader.java b/src/main/org/apache/tools/ant/taskdefs/Classloader.java
index 57bbf90..5d97e79 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Classloader.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Classloader.java
@@ -70,12 +70,6 @@
     private boolean parentFirst = true;
     private String parentName = null;
 
-    /**
-     * Default constructor
-     */
-    public Classloader() {
-    }
-
     /** Name of the loader. If none, the default loader will be modified
      *
      * @param name the name of this loader
@@ -101,6 +95,7 @@
      * @param b if true reverse the normal classloader lookup.
      * @deprecated use setParentFirst with a negated argument instead
      */
+    @Deprecated
     public void setReverse(boolean b) {
         this.parentFirst = !b;
     }
@@ -156,17 +151,17 @@
         return this.classpath.createPath();
     }
 
-
     /**
      * do the classloader manipulation.
      */
+    @Override
     public void execute() {
         try {
             // Gump friendly - don't mess with the core loader if only classpath
             if ("only".equals(getProject().getProperty("build.sysclasspath"))
                 && (name == null || SYSTEM_LOADER_REF.equals(name))) {
-                log("Changing the system loader is disabled "
-                    + "by build.sysclasspath=only", Project.MSG_WARN);
+                log("Changing the system loader is disabled by build.sysclasspath=only",
+                    Project.MSG_WARN);
                 return;
             }
 
@@ -186,6 +181,7 @@
                 return;
             }
 
+            @SuppressWarnings("resource")
             AntClassLoader acl = (AntClassLoader) obj;
             boolean existingLoader = acl != null;
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/Concat.java b/src/main/org/apache/tools/ant/taskdefs/Concat.java
index 93560ce..e632ac2 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Concat.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Concat.java
@@ -19,7 +19,6 @@
 
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
@@ -27,6 +26,7 @@
 import java.io.Reader;
 import java.io.StringReader;
 import java.io.Writer;
+import java.nio.file.Files;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
@@ -130,7 +130,7 @@
         public void setFile(File file) throws BuildException {
             // non-existing files are not allowed
             if (!file.exists()) {
-                throw new BuildException("File " + file + " does not exist.");
+                throw new BuildException("File %s does not exist.", file);
             }
 
             BufferedReader reader = null;
@@ -139,7 +139,7 @@
                     reader = new BufferedReader(new FileReader(file));
                 } else {
                     reader = new BufferedReader(
-                        new InputStreamReader(new FileInputStream(file),
+                        new InputStreamReader(Files.newInputStream(file.toPath()),
                                               this.encoding));
                 }
                 value = FileUtils.safeReadFully(reader);
@@ -181,12 +181,12 @@
             if (value == null) {
                 value = "";
             }
-            if (value.trim().length() == 0) {
+            if (value.trim().isEmpty()) {
                 value = "";
             }
             if (trimLeading) {
                 char[] current = value.toCharArray();
-                StringBuffer b = new StringBuffer(current.length);
+                StringBuilder b = new StringBuilder(current.length);
                 boolean startOfLine = true;
                 int pos = 0;
                 while (pos < current.length) {
@@ -253,6 +253,7 @@
          * @exception IOException - possibly thrown by the read for a reader
          *            object.
          */
+        @Override
         public int read() throws IOException {
             if (needAddSeparator) {
                 if (lastPos >= eolString.length()) {
@@ -287,6 +288,7 @@
          * @exception IOException - possibly thrown by the reads to the
          *            reader objects.
          */
+        @Override
         public int read(char[] cbuf, int off, int len)
             throws IOException {
 
@@ -334,14 +336,14 @@
             }
             if (amountRead == 0) {
                 return -1;
-            } else {
-                return amountRead;
             }
+            return amountRead;
         }
 
         /**
          * Close the current reader
          */
+        @Override
         public void close() throws IOException {
             if (reader != null) {
                 reader.close();
@@ -383,6 +385,7 @@
         private ConcatResource(ResourceCollection c) {
             this.c = c;
         }
+        @Override
         public InputStream getInputStream() {
             if (binary) {
                 ConcatResourceInputStream result = new ConcatResourceInputStream(c);
@@ -424,6 +427,7 @@
             return outputEncoding == null ? new ReaderInputStream(rdr)
                     : new ReaderInputStream(rdr, outputEncoding);
         }
+        @Override
         public String getName() {
             return resourceName == null
                     ? "concat (" + String.valueOf(c) + ")" : resourceName;
@@ -492,6 +496,7 @@
     private String resourceName;
 
     private ReaderFactory<Resource> resourceReaderFactory = new ReaderFactory<Resource>() {
+        @Override
         public Reader getReader(Resource o) throws IOException {
             InputStream is = o.getInputStream();
             return new BufferedReader(encoding == null
@@ -501,6 +506,7 @@
     };
 
     private ReaderFactory<Reader> identityReaderFactory = new ReaderFactory<Reader>() {
+        @Override
         public Reader getReader(Reader o) {
             return o;
         }
@@ -594,6 +600,7 @@
      * @since Ant 1.6
      * @deprecated use #setOverwrite instead
      */
+    @Deprecated
     public void setForce(boolean forceOverwrite) {
         this.forceOverwrite = forceOverwrite;
     }
@@ -753,11 +760,11 @@
      */
     public void setEol(FixCRLF.CrLf crlf) {
         String s = crlf.getValue();
-        if (s.equals("cr") || s.equals("mac")) {
+        if ("cr".equals(s) || "mac".equals(s)) {
             eolString = "\r";
-        } else if (s.equals("lf") || s.equals("unix")) {
+        } else if ("lf".equals(s) || "unix".equals(s)) {
             eolString = "\n";
-        } else if (s.equals("crlf") || s.equals("dos")) {
+        } else if ("crlf".equals(s) || "dos".equals(s)) {
             eolString = "\r\n";
         }
     }
@@ -786,6 +793,7 @@
     /**
      * Execute the concat task.
      */
+    @Override
     public void execute() {
         validate();
         if (binary && dest == null) {
@@ -797,7 +805,7 @@
             log(dest + " is up-to-date.", Project.MSG_VERBOSE);
             return;
         }
-        if (c.size() == 0 && ignoreEmpty) {
+        if (c.isEmpty() && ignoreEmpty) {
             return;
         }
         try {
@@ -816,15 +824,19 @@
      * Implement ResourceCollection.
      * @return Iterator&lt;Resource&gt;.
      */
+    @Override
     public Iterator<Resource> iterator() {
         validate();
-        return Collections.<Resource>singletonList(new ConcatResource(getResources())).iterator();
+        return Collections
+            .<Resource> singletonList(new ConcatResource(getResources()))
+            .iterator();
     }
 
     /**
      * Implement ResourceCollection.
      * @return 1.
      */
+    @Override
     public int size() {
         return 1;
     }
@@ -833,6 +845,7 @@
      * Implement ResourceCollection.
      * @return false.
      */
+    @Override
     public boolean isFilesystemOnly() {
         return false;
     }
@@ -853,8 +866,7 @@
             }
             if (encoding != null || outputEncoding != null) {
                 throw new BuildException(
-                    "Setting input or output encoding is incompatible with binary"
-                    + " concatenation");
+                    "Setting input or output encoding is incompatible with binary concatenation");
             }
             if (filterChains != null) {
                 throw new BuildException(
@@ -900,8 +912,9 @@
             checkDestNotInSources.add(rc);
             checkDestNotInSources.add(dest);
             if (checkDestNotInSources.size() > 0) {
-                throw new BuildException("Destination resource " + dest
-                        + " was specified as an input resource.");
+                throw new BuildException(
+                    "Destination resource %s was specified as an input resource.",
+                    dest);
             }
         }
         Restrict noexistRc = new Restrict();
@@ -920,12 +933,8 @@
         if (dest == null || forceOverwrite) {
             return false;
         }
-        for (Resource r : c) {
-            if (SelectorUtils.isOutOfDate(r, dest, FILE_UTILS.getFileTimestampGranularity())) {
-                return false;
-            }
-        }
-        return true;
+        return c.stream().noneMatch(r -> SelectorUtils.isOutOfDate(r, dest,
+            FILE_UTILS.getFileTimestampGranularity()));
     }
 
     /**
@@ -935,7 +944,7 @@
      * for &quot;ignorable whitespace&quot; as well.</p>
      */
     private void sanitizeText() {
-        if (textBuffer != null && "".equals(textBuffer.toString().trim())) {
+        if (textBuffer != null && textBuffer.toString().trim().isEmpty()) {
             textBuffer = null;
         }
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/ConditionTask.java b/src/main/org/apache/tools/ant/taskdefs/ConditionTask.java
index 60904e0..562ed8d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ConditionTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ConditionTask.java
@@ -107,16 +107,18 @@
      */
     public void execute() throws BuildException {
         if (countConditions() > 1) {
-            throw new BuildException("You must not nest more than one condition into <"
-                    + getTaskName() + ">");
+            throw new BuildException(
+                "You must not nest more than one condition into <%s>",
+                getTaskName());
         }
         if (countConditions() < 1) {
-            throw new BuildException("You must nest a condition into <" + getTaskName() + ">");
+            throw new BuildException("You must nest a condition into <%s>",
+                getTaskName());
         }
         if (property == null) {
             throw new BuildException("The property attribute is required.");
         }
-        Condition c = (Condition) getConditions().nextElement();
+        Condition c = getConditions().nextElement();
         if (c.eval()) {
             log("Condition true; setting " + property + " to " + value, Project.MSG_DEBUG);
             PropertyHelper.getPropertyHelper(getProject()).setNewProperty(property, value);
diff --git a/src/main/org/apache/tools/ant/taskdefs/Copy.java b/src/main/org/apache/tools/ant/taskdefs/Copy.java
index 31901a6..09d81f6 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Copy.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Copy.java
@@ -26,6 +26,7 @@
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.Vector;
 
 import org.apache.tools.ant.BuildException;
@@ -75,7 +76,7 @@
     protected File file = null;     // the source file
     protected File destFile = null; // the destination file
     protected File destDir = null;  // the destination directory
-    protected Vector<ResourceCollection> rcs = new Vector<ResourceCollection>();
+    protected Vector<ResourceCollection> rcs = new Vector<>();
     // here to provide API backwards compatibility
     protected Vector<ResourceCollection> filesets = rcs;
 
@@ -88,15 +89,15 @@
     protected boolean includeEmpty = true;
     protected boolean failonerror = true;
 
-    protected Hashtable<String, String[]> fileCopyMap = new LinkedHashtable<String, String[]>();
-    protected Hashtable<String, String[]> dirCopyMap = new LinkedHashtable<String, String[]>();
-    protected Hashtable<File, File> completeDirMap = new LinkedHashtable<File, File>();
+    protected Hashtable<String, String[]> fileCopyMap = new LinkedHashtable<>();
+    protected Hashtable<String, String[]> dirCopyMap = new LinkedHashtable<>();
+    protected Hashtable<File, File> completeDirMap = new LinkedHashtable<>();
 
     protected Mapper mapperElement = null;
     protected FileUtils fileUtils;
     //CheckStyle:VisibilityModifier ON
-    private final Vector<FilterChain> filterChains = new Vector<FilterChain>();
-    private final Vector<FilterSet> filterSets = new Vector<FilterSet>();
+    private final Vector<FilterChain> filterChains = new Vector<>();
+    private final Vector<FilterSet> filterSets = new Vector<>();
     private String inputEncoding = null;
     private String outputEncoding = null;
     private long granularity = 0;
@@ -476,18 +477,17 @@
                separate lists and then each list is handled in one go.
             */
 
-            final HashMap<File, List<String>> filesByBasedir = new HashMap<File, List<String>>();
-            final HashMap<File, List<String>> dirsByBasedir = new HashMap<File, List<String>>();
-            final HashSet<File> baseDirs = new HashSet<File>();
-            final ArrayList<Resource> nonFileResources = new ArrayList<Resource>();
-            final int size = rcs.size();
-            for (int i = 0; i < size; i++) {
-                final ResourceCollection rc = rcs.elementAt(i);
+            final Map<File, List<String>> filesByBasedir = new HashMap<>();
+            final Map<File, List<String>> dirsByBasedir = new HashMap<>();
+            final Set<File> baseDirs = new HashSet<>();
+            final List<Resource> nonFileResources = new ArrayList<>();
+
+            for (ResourceCollection rc : rcs) {
 
                 // Step (1) - beware of the ZipFileSet
                 if (rc instanceof FileSet && rc.isFilesystemOnly()) {
                     final FileSet fs = (FileSet) rc;
-                    DirectoryScanner ds = null;
+                    DirectoryScanner ds;
                     try {
                         ds = fs.getDirectoryScanner(getProject());
                     } catch (final BuildException e) {
@@ -495,12 +495,11 @@
                             || !getMessage(e).endsWith(DirectoryScanner
                                                        .DOES_NOT_EXIST_POSTFIX)) {
                             throw e;
-                        } else {
-                            if (!quiet) {
-                                log("Warning: " + getMessage(e), Project.MSG_ERR);
-                            }
-                            continue;
                         }
+                        if (!quiet) {
+                            log("Warning: " + getMessage(e), Project.MSG_ERR);
+                        }
+                        continue;
                     }
                     final File fromDir = fs.getDir(getProject());
 
@@ -576,7 +575,7 @@
                 }
             }
 
-            if (nonFileResources.size() > 0 || singleResource != null) {
+            if (!nonFileResources.isEmpty() || singleResource != null) {
                 final Resource[] nonFiles =
                     nonFileResources.toArray(new Resource[nonFileResources.size()]);
                 // restrict to out-of-date resources
@@ -647,8 +646,9 @@
         }
     }
 
-    private void iterateOverBaseDirs(
-        final HashSet<File> baseDirs, final HashMap<File, List<String>> dirsByBasedir, final HashMap<File, List<String>> filesByBasedir) {
+    private void iterateOverBaseDirs(final Set<File> baseDirs,
+        final Map<File, List<String>> dirsByBasedir,
+        final Map<File, List<String>> filesByBasedir) {
 
         for (final File f : baseDirs) {
             final List<String> files = filesByBasedir.get(f);
@@ -674,7 +674,7 @@
      * @exception BuildException if an error occurs.
      */
     protected void validateAttributes() throws BuildException {
-        if (file == null && rcs.size() == 0) {
+        if (file == null && rcs.isEmpty()) {
             throw new BuildException(
                 "Specify at least one source--a file or a resource collection.");
         }
@@ -688,36 +688,36 @@
         if (file != null && file.isDirectory()) {
             throw new BuildException("Use a resource collection to copy directories.");
         }
-        if (destFile != null && rcs.size() > 0) {
+        if (destFile != null && !rcs.isEmpty()) {
             if (rcs.size() > 1) {
                 throw new BuildException(
                     "Cannot concatenate multiple files into a single file.");
-            } else {
-                final ResourceCollection rc = rcs.elementAt(0);
-                if (!rc.isFilesystemOnly() && !supportsNonFileResources()) {
-                    throw new BuildException("Only FileSystem resources are"
-                                             + " supported.");
-                }
-                if (rc.size() == 0) {
-                    throw new BuildException(MSG_WHEN_COPYING_EMPTY_RC_TO_FILE);
-                } else if (rc.size() == 1) {
-                    final Resource res = rc.iterator().next();
-                    final FileProvider r = res.as(FileProvider.class);
-                    if (file == null) {
-                        if (r != null) {
-                            file = r.getFile();
-                        } else {
-                            singleResource = res;
-                        }
-                        rcs.removeElementAt(0);
+            }
+            final ResourceCollection rc = rcs.elementAt(0);
+            if (!rc.isFilesystemOnly() && !supportsNonFileResources()) {
+                throw new BuildException(
+                    "Only FileSystem resources are supported.");
+            }
+            if (rc.isEmpty()) {
+                throw new BuildException(MSG_WHEN_COPYING_EMPTY_RC_TO_FILE);
+            }
+            if (rc.size() == 1) {
+                final Resource res = rc.iterator().next();
+                final FileProvider r = res.as(FileProvider.class);
+                if (file == null) {
+                    if (r != null) {
+                        file = r.getFile();
                     } else {
-                        throw new BuildException(
-                            "Cannot concatenate multiple files into a single file.");
+                        singleResource = res;
                     }
+                    rcs.removeElementAt(0);
                 } else {
                     throw new BuildException(
                         "Cannot concatenate multiple files into a single file.");
                 }
+            } else {
+                throw new BuildException(
+                    "Cannot concatenate multiple files into a single file.");
             }
         }
         if (destFile != null) {
@@ -813,34 +813,28 @@
      */
     protected Map<Resource, String[]> buildMap(final Resource[] fromResources, final File toDir,
                            final FileNameMapper mapper) {
-        final HashMap<Resource, String[]> map = new HashMap<Resource, String[]>();
-        Resource[] toCopy = null;
+        final Map<Resource, String[]> map = new HashMap<>();
+        Resource[] toCopy;
         if (forceOverwrite) {
-            final Vector<Resource> v = new Vector<Resource>();
+            final List<Resource> v = new ArrayList<>();
             for (int i = 0; i < fromResources.length; i++) {
                 if (mapper.mapFileName(fromResources[i].getName()) != null) {
-                    v.addElement(fromResources[i]);
+                    v.add(fromResources[i]);
                 }
             }
-            toCopy = new Resource[v.size()];
-            v.copyInto(toCopy);
+            toCopy = v.toArray(new Resource[v.size()]);
         } else {
             toCopy = ResourceUtils.selectOutOfDateSources(this, fromResources,
                                                           mapper,
-                                                          new ResourceFactory() {
-                                            public Resource getResource(final String name) {
-                                                return new FileResource(toDir, name);
-                                            }
-                                                          },
+                                                          (ResourceFactory) name -> new FileResource(toDir, name),
                                                           granularity);
         }
         for (int i = 0; i < toCopy.length; i++) {
             final String[] mappedFiles = mapper.mapFileName(toCopy[i].getName());
-            for (int j = 0; j < mappedFiles.length; j++) {
-                if (mappedFiles[j] == null) {
-                    throw new BuildException("Can't copy a resource without a"
-                                             + " name if the mapper doesn't"
-                                             + " provide one.");
+            for (String mappedFile : mappedFiles) {
+                if (mappedFile == null) {
+                    throw new BuildException(
+                        "Can't copy a resource without a name if the mapper doesn't provide one.");
                 }
             }
 
@@ -863,7 +857,7 @@
      * This is a good method for subclasses to override.
      */
     protected void doFileOperations() {
-        if (fileCopyMap.size() > 0) {
+        if (!fileCopyMap.isEmpty()) {
             log("Copying " + fileCopyMap.size()
                 + " file" + (fileCopyMap.size() == 1 ? "" : "s")
                 + " to " + destDir.getAbsolutePath());
@@ -872,9 +866,7 @@
                 final String fromFile = e.getKey();
                 final String[] toFiles = e.getValue();
 
-                for (int i = 0; i < toFiles.length; i++) {
-                    final String toFile = toFiles[i];
-
+                for (final String toFile : toFiles) {
                     if (fromFile.equals(toFile)) {
                         log("Skipping self-copy of " + fromFile, verbosity);
                         continue;
@@ -918,8 +910,8 @@
         if (includeEmpty) {
             int createCount = 0;
             for (final String[] dirs : dirCopyMap.values()) {
-                for (int i = 0; i < dirs.length; i++) {
-                    final File d = new File(dirs[i]);
+                for (String dir : dirs) {
+                    final File d = new File(dir);
                     if (!d.exists()) {
                         if (!(d.mkdirs() || d.isDirectory())) {
                             log("Unable to create directory "
@@ -949,7 +941,7 @@
      * @since Ant 1.7
      */
     protected void doResourceOperations(final Map<Resource, String[]> map) {
-        if (map.size() > 0) {
+        if (!map.isEmpty()) {
             log("Copying " + map.size()
                 + " resource" + (map.size() == 1 ? "" : "s")
                 + " to " + destDir.getAbsolutePath());
@@ -1028,7 +1020,7 @@
             baseDir = getKeyFile(baseDir);
             List<String> l = m.get(baseDir);
             if (l == null) {
-                l = new ArrayList<String>(names.length);
+                l = new ArrayList<>(names.length);
                 m.put(baseDir, l);
             }
             l.addAll(java.util.Arrays.asList(names));
@@ -1087,7 +1079,7 @@
      */
     private String getDueTo(final Exception ex) {
         final boolean baseIOException = ex.getClass() == IOException.class;
-        final StringBuffer message = new StringBuffer();
+        final StringBuilder message = new StringBuilder();
         if (!baseIOException || ex.getMessage() == null) {
             message.append(ex.getClass().getName());
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Copydir.java b/src/main/org/apache/tools/ant/taskdefs/Copydir.java
index 8b4efc3..7a099ab 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Copydir.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Copydir.java
@@ -35,6 +35,7 @@
  * @deprecated The copydir task is deprecated since Ant 1.2.  Use copy instead.
  */
 
+@Deprecated
 public class Copydir extends MatchingTask {
 
     private File srcDir;
@@ -42,7 +43,7 @@
     private boolean filtering = false;
     private boolean flatten = false;
     private boolean forceOverwrite = false;
-    private Hashtable<String, String> filecopyList = new Hashtable<String, String>();
+    private Map<String, String> filecopyList = new Hashtable<>();
 
     /**
      * The src attribute
@@ -94,6 +95,7 @@
      * Execute the task.
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         log("DEPRECATED - The copydir task is deprecated.  Use copy instead.");
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/Copyfile.java b/src/main/org/apache/tools/ant/taskdefs/Copyfile.java
index e9acb1d..55bd1f4 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Copyfile.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Copyfile.java
@@ -34,6 +34,7 @@
  * copy instead.
  */
 
+@Deprecated
 public class Copyfile extends Task {
 
     private File srcFile;
@@ -80,6 +81,7 @@
      * Execute the task.
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         log("DEPRECATED - The copyfile task is deprecated.  Use copy instead.");
 
@@ -107,9 +109,9 @@
             try {
                 getProject().copyFile(srcFile, destFile, filtering, forceOverwrite);
             } catch (IOException ioe) {
-                String msg = "Error copying file: " + srcFile.getAbsolutePath()
-                    + " due to " + ioe.getMessage();
-                throw new BuildException(msg);
+                throw new BuildException(
+                    "Error copying file: " + srcFile.getAbsolutePath()
+                        + " due to " + ioe.getMessage());
             }
         }
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/DefaultExcludes.java b/src/main/org/apache/tools/ant/taskdefs/DefaultExcludes.java
index 6b912e2..45cdfc3 100644
--- a/src/main/org/apache/tools/ant/taskdefs/DefaultExcludes.java
+++ b/src/main/org/apache/tools/ant/taskdefs/DefaultExcludes.java
@@ -45,29 +45,28 @@
      *
      * @exception BuildException if something goes wrong with the build
      */
+    @Override
     public void execute() throws BuildException {
-        if (!defaultrequested && add.equals("") && remove.equals("") && !echo) {
-            throw new BuildException("<defaultexcludes> task must set "
-                + "at least one attribute (echo=\"false\""
-                + " doesn't count since that is the default");
+        if (!defaultrequested && "".equals(add) && "".equals(remove) && !echo) {
+            throw new BuildException(
+                "<defaultexcludes> task must set at least one attribute (echo=\"false\" doesn't count since that is the default");
         }
         if (defaultrequested) {
             DirectoryScanner.resetDefaultExcludes();
         }
-        if (!add.equals("")) {
+        if (!"".equals(add)) {
             DirectoryScanner.addDefaultExclude(add);
         }
-        if (!remove.equals("")) {
+        if (!"".equals(remove)) {
             DirectoryScanner.removeDefaultExclude(remove);
         }
         if (echo) {
-            StringBuffer message
-                = new StringBuffer("Current Default Excludes:");
+            StringBuilder message
+                = new StringBuilder("Current Default Excludes:");
             message.append(StringUtils.LINE_SEP);
-            String[] excludes = DirectoryScanner.getDefaultExcludes();
-            for (int i = 0; i < excludes.length; i++) {
+            for (String exclude : DirectoryScanner.getDefaultExcludes()) {
                 message.append("  ");
-                message.append(excludes[i]);
+                message.append(exclude);
                 message.append(StringUtils.LINE_SEP);
             }
             log(message.toString(), logLevel);
@@ -111,5 +110,4 @@
         this.echo = echo;
     }
 
-
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Definer.java b/src/main/org/apache/tools/ant/taskdefs/Definer.java
index 98a22be..154974e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Definer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Definer.java
@@ -50,13 +50,14 @@
 
     /**
      * the extension of an antlib file for autoloading.
-     * {@value[
+     * {@value /antlib.xml}
      */
     private static final String ANTLIB_XML = "/antlib.xml";
 
     private static final ThreadLocal<Map<URL, Location>> RESOURCE_STACK = new ThreadLocal<Map<URL, Location>>() {
+        @Override
         protected Map<URL, Location> initialValue() {
-            return new HashMap<URL, Location>();
+            return new HashMap<>();
         }
     };
 
@@ -120,9 +121,10 @@
          * get the values
          * @return an array of the allowed values for this attribute.
          */
+        @Override
         public String[] getValues() {
             return new String[] {POLICY_FAIL, POLICY_REPORT, POLICY_IGNORE,
-                    POLICY_FAILALL};
+                POLICY_FAILALL};
         }
     }
 
@@ -139,6 +141,7 @@
          * get the values
          * @return an array of the allowed values for this attribute.
          */
+        @Override
         public String[] getValues() {
             return new String[] {"properties", "xml"};
         }
@@ -203,6 +206,7 @@
      *
      * @exception BuildException if an error occurs
      */
+    @Override
     public void execute() throws BuildException {
         ClassLoader al = createLoader();
 
@@ -224,23 +228,22 @@
                 setResource(makeResourceFromURI(uri1));
             } else {
                 throw new BuildException(
-                        "Only antlib URIs can be located from the URI alone,"
-                                + " not the URI '" + getURI() + "'");
+                    "Only antlib URIs can be located from the URI alone, not the URI '"
+                        + getURI() + "'");
             }
         }
 
         if (name != null) {
             if (classname == null) {
-                throw new BuildException(
-                    "classname attribute of " + getTaskName() + " element "
-                    + "is undefined", getLocation());
+                throw new BuildException("classname attribute of "
+                    + getTaskName() + " element is undefined", getLocation());
             }
             addDefinition(al, name, classname);
         } else {
             if (classname != null) {
-                String msg = "You must not specify classname "
-                    + "together with file or resource.";
-                throw new BuildException(msg, getLocation());
+                throw new BuildException(
+                    "You must not specify classname together with file or resource.",
+                    getLocation());
             }
             final Enumeration<URL> urls;
             if (file == null) {
@@ -264,21 +267,19 @@
                 if (fmt == Format.PROPERTIES) {
                     loadProperties(al, url);
                     break;
+                } else if (RESOURCE_STACK.get().get(url) != null) {
+                    log("Warning: Recursive loading of " + url
+                        + " ignored"
+                        + " at " + getLocation()
+                        + " originally loaded at "
+                        + RESOURCE_STACK.get().get(url),
+                        Project.MSG_WARN);
                 } else {
-                    if (RESOURCE_STACK.get().get(url) != null) {
-                        log("Warning: Recursive loading of " + url
-                            + " ignored"
-                            + " at " + getLocation()
-                            + " originally loaded at "
-                            + RESOURCE_STACK.get().get(url),
-                            Project.MSG_WARN);
-                    } else {
-                        try {
-                            RESOURCE_STACK.get().put(url, getLocation());
-                            loadAntlib(al, url);
-                        } finally {
-                            RESOURCE_STACK.get().remove(url);
-                        }
+                    try {
+                        RESOURCE_STACK.get().put(url, getLocation());
+                        loadAntlib(al, url);
+                    } finally {
+                        RESOURCE_STACK.get().remove(url);
                     }
                 }
             }
@@ -291,7 +292,6 @@
      * @param uri the xml namespace uri that to convert.
      * @return the name of a resource. It may not exist
      */
-
     public static String makeResourceFromURI(String uri) {
         String path = uri.substring(MagicNames.ANTLIB_PREFIX.length());
         String resource;
@@ -392,9 +392,7 @@
      * @param url the url to get the definitions from
      */
     protected void loadProperties(ClassLoader al, URL url) {
-        InputStream is = null;
-        try {
-            is = url.openStream();
+        try (InputStream is = url.openStream()) {
             if (is == null) {
                 log("Could not load definitions from " + url,
                     Project.MSG_WARN);
@@ -402,16 +400,13 @@
             }
             Properties props = new Properties();
             props.load(is);
-            Enumeration<?> keys = props.keys();
-            while (keys.hasMoreElements()) {
-                name = ((String) keys.nextElement());
+            for (String key : props.stringPropertyNames()) {
+                name = key;
                 classname = props.getProperty(name);
                 addDefinition(al, name, classname);
             }
         } catch (IOException ex) {
             throw new BuildException(ex, getLocation());
-        } finally {
-            FileUtils.close(is);
         }
     }
 
@@ -560,7 +555,6 @@
         this.adaptToClass = adaptToClass;
     }
 
-
     /**
      * Add a definition using the attributes of Definer
      *
@@ -602,15 +596,16 @@
                 ComponentHelper.getComponentHelper(getProject())
                         .addDataTypeDefinition(def);
             } catch (ClassNotFoundException cnfe) {
-                String msg = getTaskName() + " class " + classname
-                        + " cannot be found"
-                        + "\n using the classloader " + al;
-                throw new BuildException(msg, cnfe, getLocation());
+                throw new BuildException(
+                    getTaskName() + " class " + classname
+                        + " cannot be found\n using the classloader " + al,
+                    cnfe, getLocation());
             } catch (NoClassDefFoundError ncdfe) {
-                String msg = getTaskName() + " A class needed by class "
-                        + classname + " cannot be found: " + ncdfe.getMessage()
-                        + "\n using the classloader " + al;
-                throw new BuildException(msg, ncdfe, getLocation());
+                throw new BuildException(
+                    getTaskName() + " A class needed by class " + classname
+                        + " cannot be found: " + ncdfe.getMessage()
+                        + "\n using the classloader " + al,
+                    ncdfe, getLocation());
             }
         } catch (BuildException ex) {
             switch (onError) {
@@ -634,7 +629,7 @@
      */
     private void tooManyDefinitions() {
         throw new BuildException(
-            "Only one of the attributes name, file and resource"
-            + " can be set", getLocation());
+            "Only one of the attributes name, file and resource can be set",
+            getLocation());
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Delete.java b/src/main/org/apache/tools/ant/taskdefs/Delete.java
index b22c7cc..12be2d4 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Delete.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Delete.java
@@ -19,6 +19,9 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Iterator;
@@ -60,7 +63,6 @@
 import org.apache.tools.ant.types.selectors.SizeSelector;
 import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
 import org.apache.tools.ant.util.FileUtils;
-import org.apache.tools.ant.util.SymbolicLinkUtils;
 
 /**
  * Deletes a file or directory, or set of files defined by a fileset.
@@ -79,33 +81,41 @@
 public class Delete extends MatchingTask {
     private static final ResourceComparator REVERSE_FILESYSTEM = new Reverse(new FileSystem());
     private static final ResourceSelector EXISTS = new Exists();
+    private static FileUtils FILE_UTILS = FileUtils.getFileUtils();
 
     private static class ReverseDirs implements ResourceCollection {
-        static final Comparator<Comparable<?>> REVERSE = new Comparator<Comparable<?>>() {
-            public int compare(Comparable<?> foo, Comparable<?> bar) {
-                return ((Comparable) foo).compareTo(bar) * -1;
-            }
-        };
+
         private Project project;
         private File basedir;
         private String[] dirs;
+
         ReverseDirs(Project project, File basedir, String[] dirs) {
             this.project = project;
             this.basedir = basedir;
             this.dirs = dirs;
-            Arrays.sort(this.dirs, REVERSE);
+            Arrays.sort(this.dirs, Comparator.reverseOrder());
         }
+
+        @Override
         public Iterator<Resource> iterator() {
             return new FileResourceIterator(project, basedir, dirs);
         }
-        public boolean isFilesystemOnly() { return true; }
-        public int size() { return dirs.length; }
+
+        @Override
+        public boolean isFilesystemOnly() {
+            return true;
+        }
+
+        @Override
+        public int size() {
+            return dirs.length;
+        }
     }
 
     // CheckStyle:VisibilityModifier OFF - bc
     protected File file = null;
     protected File dir = null;
-    protected Vector<FileSet> filesets = new Vector<FileSet>();
+    protected Vector<FileSet> filesets = new Vector<>();
     protected boolean usedMatchingTask = false;
     // by default, remove matching empty dirs
     protected boolean includeEmpty = false;
@@ -117,9 +127,6 @@
     private boolean deleteOnExit = false;
     private boolean removeNotFollowedSymlinks = false;
     private Resources rcs = null;
-    private static FileUtils FILE_UTILS = FileUtils.getFileUtils();
-    private static SymbolicLinkUtils SYMLINK_UTILS =
-        SymbolicLinkUtils.getSymbolicLinkUtils();
     private boolean performGc = Os.isFamily("windows");
 
     /**
@@ -175,9 +182,9 @@
      *
      * @param failonerror true or false
      */
-     public void setFailOnError(boolean failonerror) {
-         this.failonerror = failonerror;
-     }
+    public void setFailOnError(boolean failonerror) {
+        this.failonerror = failonerror;
+    }
 
     /**
      * If true, on failure to delete, note the error and set
@@ -185,10 +192,9 @@
      *
      * @param deleteOnExit true or false
      */
-     public void setDeleteOnExit(boolean deleteOnExit) {
-         this.deleteOnExit = deleteOnExit;
-     }
-
+    public void setDeleteOnExit(boolean deleteOnExit) {
+        this.deleteOnExit = deleteOnExit;
+    }
 
     /**
      * If true, delete empty directories.
@@ -213,10 +219,10 @@
         performGc = b;
     }
 
-   /**
-    * Adds a set of files to be deleted.
-    * @param set the set of files to be deleted
-    */
+    /**
+     * Adds a set of files to be deleted.
+     * @param set the set of files to be deleted
+     */
     public void addFileset(FileSet set) {
         filesets.addElement(set);
     }
@@ -240,6 +246,7 @@
      * add a name entry on the include list
      * @return a NameEntry object to be configured
      */
+    @Override
     public PatternSet.NameEntry createInclude() {
         usedMatchingTask = true;
         return super.createInclude();
@@ -249,6 +256,7 @@
      * add a name entry on the include files list
      * @return a NameEntry object to be configured
      */
+    @Override
     public PatternSet.NameEntry createIncludesFile() {
         usedMatchingTask = true;
         return super.createIncludesFile();
@@ -258,6 +266,7 @@
      * add a name entry on the exclude list
      * @return a NameEntry object to be configured
      */
+    @Override
     public PatternSet.NameEntry createExclude() {
         usedMatchingTask = true;
         return super.createExclude();
@@ -267,6 +276,7 @@
      * add a name entry on the include files list
      * @return a NameEntry object to be configured
      */
+    @Override
     public PatternSet.NameEntry createExcludesFile() {
         usedMatchingTask = true;
         return super.createExcludesFile();
@@ -276,6 +286,7 @@
      * add a set of patterns
      * @return PatternSet object to be configured
      */
+    @Override
     public PatternSet createPatternSet() {
         usedMatchingTask = true;
         return super.createPatternSet();
@@ -287,6 +298,7 @@
      *
      * @param includes the string containing the include patterns
      */
+    @Override
     public void setIncludes(String includes) {
         usedMatchingTask = true;
         super.setIncludes(includes);
@@ -298,6 +310,7 @@
      *
      * @param excludes the string containing the exclude patterns
      */
+    @Override
     public void setExcludes(String excludes) {
         usedMatchingTask = true;
         super.setExcludes(excludes);
@@ -310,6 +323,7 @@
      *                           should be used, "false"|"off"|"no" when they
      *                           shouldn't be used.
      */
+    @Override
     public void setDefaultexcludes(boolean useDefaultExcludes) {
         usedMatchingTask = true;
         super.setDefaultexcludes(useDefaultExcludes);
@@ -321,6 +335,7 @@
      * @param includesfile A string containing the filename to fetch
      * the include patterns from.
      */
+    @Override
     public void setIncludesfile(File includesfile) {
         usedMatchingTask = true;
         super.setIncludesfile(includesfile);
@@ -332,6 +347,7 @@
      * @param excludesfile A string containing the filename to fetch
      * the include patterns from.
      */
+    @Override
     public void setExcludesfile(File excludesfile) {
         usedMatchingTask = true;
         super.setExcludesfile(excludesfile);
@@ -343,6 +359,7 @@
      * @param isCaseSensitive "true"|"on"|"yes" if file system is case
      *                           sensitive, "false"|"off"|"no" when not.
      */
+    @Override
     public void setCaseSensitive(boolean isCaseSensitive) {
         usedMatchingTask = true;
         super.setCaseSensitive(isCaseSensitive);
@@ -353,6 +370,7 @@
      *
      * @param followSymlinks whether or not symbolic links should be followed
      */
+    @Override
     public void setFollowSymlinks(boolean followSymlinks) {
         usedMatchingTask = true;
         super.setFollowSymlinks(followSymlinks);
@@ -374,6 +392,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addSelector(SelectSelector selector) {
         usedMatchingTask = true;
         super.addSelector(selector);
@@ -384,6 +403,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addAnd(AndSelector selector) {
         usedMatchingTask = true;
         super.addAnd(selector);
@@ -394,6 +414,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addOr(OrSelector selector) {
         usedMatchingTask = true;
         super.addOr(selector);
@@ -404,6 +425,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addNot(NotSelector selector) {
         usedMatchingTask = true;
         super.addNot(selector);
@@ -414,6 +436,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addNone(NoneSelector selector) {
         usedMatchingTask = true;
         super.addNone(selector);
@@ -424,6 +447,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addMajority(MajoritySelector selector) {
         usedMatchingTask = true;
         super.addMajority(selector);
@@ -434,6 +458,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addDate(DateSelector selector) {
         usedMatchingTask = true;
         super.addDate(selector);
@@ -444,6 +469,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addSize(SizeSelector selector) {
         usedMatchingTask = true;
         super.addSize(selector);
@@ -454,6 +480,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addFilename(FilenameSelector selector) {
         usedMatchingTask = true;
         super.addFilename(selector);
@@ -464,6 +491,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addCustom(ExtendSelector selector) {
         usedMatchingTask = true;
         super.addCustom(selector);
@@ -474,6 +502,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addContains(ContainsSelector selector) {
         usedMatchingTask = true;
         super.addContains(selector);
@@ -484,6 +513,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addPresent(PresentSelector selector) {
         usedMatchingTask = true;
         super.addPresent(selector);
@@ -494,6 +524,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addDepth(DepthSelector selector) {
         usedMatchingTask = true;
         super.addDepth(selector);
@@ -504,6 +535,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addDepend(DependSelector selector) {
         usedMatchingTask = true;
         super.addDepend(selector);
@@ -514,6 +546,7 @@
      *
      * @param selector the selector to be added
      */
+    @Override
     public void addContainsRegexp(ContainsRegexpSelector selector) {
         usedMatchingTask = true;
         super.addContainsRegexp(selector);
@@ -525,6 +558,7 @@
      * @param selector the selector to add
      * @since ant 1.6
      */
+    @Override
     public void addModified(ModifiedSelector selector) {
         usedMatchingTask = true;
         super.addModified(selector);
@@ -536,6 +570,7 @@
      * @param selector the selector to be added
      * @since Ant 1.6
      */
+    @Override
     public void add(FileSelector selector) {
         usedMatchingTask = true;
         super.add(selector);
@@ -546,20 +581,21 @@
      *
      * @exception BuildException if an error occurs
      */
+    @Override
     public void execute() throws BuildException {
         if (usedMatchingTask) {
-            log("DEPRECATED - Use of the implicit FileSet is deprecated.  "
-                + "Use a nested fileset element instead.", quiet ? Project.MSG_VERBOSE : verbosity);
+            log("DEPRECATED - Use of the implicit FileSet is deprecated.  Use a nested fileset element instead.",
+                quiet ? Project.MSG_VERBOSE : verbosity);
         }
 
-        if (file == null && dir == null && filesets.size() == 0 && rcs == null) {
-            throw new BuildException("At least one of the file or dir "
-                                     + "attributes, or a nested resource collection, "
-                                     + "must be set.");
+        if (file == null && dir == null && filesets.isEmpty() && rcs == null) {
+            throw new BuildException(
+                "At least one of the file or dir attributes, or a nested resource collection, must be set.");
         }
 
         if (quiet && failonerror) {
-            throw new BuildException("quiet and failonerror cannot both be set to true", getLocation());
+            throw new BuildException(
+                "quiet and failonerror cannot both be set to true", getLocation());
         }
 
         // delete the single file
@@ -567,8 +603,8 @@
             if (file.exists()) {
                 if (file.isDirectory()) {
                     log("Directory " + file.getAbsolutePath()
-                        + " cannot be removed using the file attribute.  "
-                        + "Use dir instead.", quiet ? Project.MSG_VERBOSE : verbosity);
+                        + " cannot be removed using the file attribute.  Use dir instead.",
+                        quiet ? Project.MSG_VERBOSE : verbosity);
                 } else {
                     log("Deleting: " + file.getAbsolutePath());
 
@@ -628,11 +664,11 @@
 
         final int size = filesets.size();
         for (int i = 0; i < size; i++) {
-            FileSet fs = (FileSet) filesets.get(i);
+            FileSet fs = filesets.get(i);
             if (fs.getProject() == null) {
-                log("Deleting fileset with no project specified;"
-                    + " assuming executing project", Project.MSG_VERBOSE);
-                fs = (FileSet) fs.clone();
+                log("Deleting fileset with no project specified; assuming executing project",
+                    Project.MSG_VERBOSE);
+                fs = fs.clone();
                 fs.setProject(getProject());
             }
             final File fsDir = fs.getDir();
@@ -650,19 +686,22 @@
                 // iterating, capture the results now and store them
                 final String[] files = ds.getIncludedFiles();
                 resourcesToDelete.add(new ResourceCollection() {
-                        public boolean isFilesystemOnly() {
-                            return true;
-                        }
+                    @Override
+                    public boolean isFilesystemOnly() {
+                        return true;
+                    }
 
-                        public int size() {
-                            return files.length;
-                        }
+                    @Override
+                    public int size() {
+                        return files.length;
+                    }
 
-                        public Iterator<Resource> iterator() {
-                            return new FileResourceIterator(getProject(),
-                                                            fsDir, files);
-                        }
-                    });
+                    @Override
+                    public Iterator<Resource> iterator() {
+                        return new FileResourceIterator(getProject(),
+                                fsDir, files);
+                    }
+                });
                 if (includeEmpty) {
                     filesetDirs.add(new ReverseDirs(getProject(), fsDir,
                             ds.getIncludedDirectories()));
@@ -673,14 +712,17 @@
                     if (n.length > 0) {
                         String[] links = new String[n.length];
                         System.arraycopy(n, 0, links, 0, n.length);
-                        Arrays.sort(links, ReverseDirs.REVERSE);
+                        Arrays.sort(links, Comparator.reverseOrder());
                         for (int l = 0; l < links.length; l++) {
-                            try {
-                                SYMLINK_UTILS
-                                    .deleteSymbolicLink(new File(links[l]),
-                                                        this);
-                            } catch (java.io.IOException ex) {
-                                handle(ex);
+                            final Path filePath = Paths.get(links[l]);
+                            if (!Files.isSymbolicLink(filePath)) {
+                                // it's not a symbolic link, so move on
+                                continue;
+                            }
+                            // it's a symbolic link, so delete it
+                            final boolean deleted = filePath.toFile().delete();
+                            if (!deleted) {
+                                handle("Could not delete symbolic link at " + filePath);
                             }
                         }
                     }
@@ -836,14 +878,13 @@
         }
     }
 
-    private boolean isDanglingSymlink(File f) {
-        try {
-            return SYMLINK_UTILS.isDanglingSymbolicLink(f);
-        } catch (java.io.IOException e) {
-            log("Error while trying to detect " + f.getAbsolutePath()
-                + " as broken symbolic link. " + e.getMessage(),
-                quiet ? Project.MSG_VERBOSE : verbosity);
+    private boolean isDanglingSymlink(final File f) {
+        if (!Files.isSymbolicLink(f.toPath())) {
+            // it's not a symlink, so clearly it's not a dangling one
             return false;
         }
+        // it's a symbolic link, now  check the existence of the (target) file (by "following links")
+        final boolean targetFileExists = Files.exists(f.toPath());
+        return !targetFileExists;
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/DependSet.java b/src/main/org/apache/tools/ant/taskdefs/DependSet.java
index 549e0ff..0fbdf56 100644
--- a/src/main/org/apache/tools/ant/taskdefs/DependSet.java
+++ b/src/main/org/apache/tools/ant/taskdefs/DependSet.java
@@ -102,12 +102,15 @@
         private HideMissingBasedir(FileSet fs) {
             this.fs = fs;
         }
+        @Override
         public Iterator<Resource> iterator() {
             return basedirExists() ? fs.iterator() : Resources.EMPTY_ITERATOR;
         }
+        @Override
         public int size() {
             return basedirExists() ? fs.size() : 0;
         }
+        @Override
         public boolean isFilesystemOnly() {
             return true;
         }
@@ -191,6 +194,7 @@
      * Execute the task.
      * @throws BuildException if errors occur.
      */
+    @Override
     public void execute() throws BuildException {
         if (sources == null) {
           throw new BuildException(
@@ -201,12 +205,11 @@
               "At least one set of target files must be specified");
         }
         //no sources = nothing to compare; no targets = nothing to delete:
-        if (sources.size() > 0 && targets.size() > 0 && !uptodate(sources, targets)) {
+        if (!(sources.isEmpty() || targets.isEmpty() || uptodate(sources, targets))) {
            log("Deleting all target files.", Project.MSG_VERBOSE);
            if (verbose) {
-               String[] t = targets.list();
-               for (int i = 0; i < t.length; i++) {
-                   log("Deleting " + t[i]);
+               for (String t : targets.list()) {
+                   log("Deleting " + t);
                }
            }
            Delete delete = new Delete();
@@ -245,7 +248,7 @@
             logMissing(missingSources, "source");
             return false;
         }
-        Resource newestSource = (Resource) getNewest(sources);
+        Resource newestSource = getNewest(sources);
         logWithModificationTime(newestSource, "newest source");
         return oldestTarget.getLastModified() >= newestSource.getLastModified();
     }
@@ -263,7 +266,6 @@
         Iterator<Resource> i = rc.iterator();
         if (!i.hasNext()) {
             return null;
-
         }
         Resource xest = i.next();
         while (i.hasNext()) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/Dirname.java b/src/main/org/apache/tools/ant/taskdefs/Dirname.java
index 9e085e7..2e952df 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Dirname.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Dirname.java
@@ -68,15 +68,14 @@
      * Execute this task.
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         if (property == null) {
             throw new BuildException("property attribute required", getLocation());
         }
         if (file == null) {
             throw new BuildException("file attribute required", getLocation());
-        } else {
-            String value = file.getParent();
-            getProject().setNewProperty(property, value);
         }
+        getProject().setNewProperty(property, file.getParent());
     }
 }
\ No newline at end of file
diff --git a/src/main/org/apache/tools/ant/taskdefs/Ear.java b/src/main/org/apache/tools/ant/taskdefs/Ear.java
index 6e08ecd..45ad50e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Ear.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Ear.java
@@ -55,6 +55,7 @@
      * @deprecated since 1.5.x.
      *             Use setDestFile(destfile) instead.
      */
+    @Deprecated
     public void setEarfile(File earFile) {
         setDestFile(earFile);
     }
@@ -66,9 +67,9 @@
     public void setAppxml(File descr) {
         deploymentDescriptor = descr;
         if (!deploymentDescriptor.exists()) {
-            throw new BuildException("Deployment descriptor: "
-                                     + deploymentDescriptor
-                                     + " does not exist.");
+            throw new BuildException(
+                "Deployment descriptor: %s does not exist.",
+                deploymentDescriptor);
         }
 
         // Create a ZipFileSet for this file, and pass it up.
@@ -78,7 +79,6 @@
         super.addFileset(fs);
     }
 
-
     /**
      * Adds zipfileset.
      *
@@ -91,13 +91,13 @@
         super.addFileset(fs);
     }
 
-
     /**
      * Initialize the output stream.
      * @param zOut the zip output stream.
      * @throws IOException on I/O errors
      * @throws BuildException on other errors
      */
+    @Override
     protected void initZipOutputStream(ZipOutputStream zOut)
         throws IOException, BuildException {
         // If no webxml file is specified, it's an error.
@@ -116,6 +116,7 @@
      * @param mode the Unix permissions to set.
      * @throws IOException on error
      */
+    @Override
     protected void zipFile(File file, ZipOutputStream zOut, String vPath,
                            int mode)
         throws IOException {
@@ -147,6 +148,7 @@
      * Make sure we don't think we already have a application.xml next
      * time this task gets executed.
      */
+    @Override
     protected void cleanUp() {
         descriptorAdded = false;
         super.cleanUp();
diff --git a/src/main/org/apache/tools/ant/taskdefs/EchoXML.java b/src/main/org/apache/tools/ant/taskdefs/EchoXML.java
index 5524c0d..34baf6b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/EchoXML.java
+++ b/src/main/org/apache/tools/ant/taskdefs/EchoXML.java
@@ -18,7 +18,6 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.OutputStream;
 
 import org.apache.tools.ant.BuildException;
@@ -82,7 +81,7 @@
         OutputStream os = null;
         try {
             if (file != null) {
-                os = new FileOutputStream(file.getAbsolutePath(), append);
+                os = FileUtils.newOutputStream(file.toPath(), append);
             } else {
                 os = new LogOutputStream(this, Project.MSG_INFO);
             }
@@ -114,6 +113,7 @@
         public NamespacePolicy(String s) {
             setValue(s);
         }
+
         /** {@inheritDoc}. */
         @Override
         public String[] getValues() {
@@ -124,14 +124,15 @@
             String s = getValue();
             if (IGNORE.equalsIgnoreCase(s)) {
                 return DOMElementWriter.XmlNamespacePolicy.IGNORE;
-            } else if (ELEMENTS.equalsIgnoreCase(s)) {
+            }
+            if (ELEMENTS.equalsIgnoreCase(s)) {
                 return
                     DOMElementWriter.XmlNamespacePolicy.ONLY_QUALIFY_ELEMENTS;
-            } else if (ALL.equalsIgnoreCase(s)) {
-                return DOMElementWriter.XmlNamespacePolicy.QUALIFY_ALL;
-            } else {
-                throw new BuildException("Invalid namespace policy: " + s);
             }
+            if (ALL.equalsIgnoreCase(s)) {
+                return DOMElementWriter.XmlNamespacePolicy.QUALIFY_ALL;
+            }
+            throw new BuildException("Invalid namespace policy: " + s);
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Exec.java b/src/main/org/apache/tools/ant/taskdefs/Exec.java
index cfc6b76..a1c100f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Exec.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Exec.java
@@ -44,6 +44,7 @@
  *             delegate to {@link org.apache.tools.ant.taskdefs.Execute Execute}
  *             instead.
  */
+@Deprecated
 public class Exec extends Task {
     private String os;
     private String out;
@@ -70,6 +71,7 @@
      * Execute the task.
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         run(command);
     }
@@ -160,9 +162,8 @@
             if (err != 0) {
                 if (failOnError) {
                     throw new BuildException("Exec returned: " + err, getLocation());
-                } else {
-                    log("Result: " + err, Project.MSG_ERR);
                 }
+                log("Result: " + err, Project.MSG_ERR);
             }
         } catch (IOException ioe) {
             throw new BuildException("Error exec: " + command, ioe, getLocation());
@@ -262,6 +263,7 @@
             }
         }
 
+        @Override
         public void run() {
             try {
                 try {
diff --git a/src/main/org/apache/tools/ant/taskdefs/ExecTask.java b/src/main/org/apache/tools/ant/taskdefs/ExecTask.java
index b9eb963..1a8956f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ExecTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ExecTask.java
@@ -125,7 +125,7 @@
      */
     public void setTimeout(Integer value) {
         setTimeout(
-            (Long) ((value == null) ? null : new Long(value.intValue())));
+            (value == null) ? null : Long.valueOf(value.intValue()));
     }
 
     /**
@@ -168,8 +168,7 @@
      * @ant.attribute ignore="true"
      */
     public void setCommand(Commandline cmdl) {
-        log("The command attribute is deprecated.\n"
-            + "Please use the executable attribute and nested arg elements.",
+        log("The command attribute is deprecated.\nPlease use the executable attribute and nested arg elements.",
             Project.MSG_WARN);
         this.cmdl = cmdl;
     }
@@ -192,8 +191,8 @@
      */
     public void setInput(File input) {
         if (inputString != null) {
-            throw new BuildException("The \"input\" and \"inputstring\" "
-                + "attributes cannot both be specified");
+            throw new BuildException(
+                "The \"input\" and \"inputstring\" attributes cannot both be specified");
         }
         this.input = input;
         incompatibleWithSpawn = true;
@@ -206,8 +205,8 @@
      */
     public void setInputString(String inputString) {
         if (input != null) {
-            throw new BuildException("The \"input\" and \"inputstring\" "
-                + "attributes cannot both be specified");
+            throw new BuildException(
+                "The \"input\" and \"inputstring\" attributes cannot both be specified");
         }
         this.inputString = inputString;
         incompatibleWithSpawn = true;
@@ -486,6 +485,7 @@
      * <li>this list is not exhaustive or limitative</li>
      * </ul>
      */
+    @Override
     public void execute() throws BuildException {
         // Quick fail if this is not a valid OS for the command
         if (!isValidOs()) {
@@ -635,9 +635,8 @@
                 String msg = "Timeout: killed the sub-process";
                 if (failOnError) {
                     throw new BuildException(msg);
-                } else {
-                    log(msg, Project.MSG_WARN);
                 }
+                log(msg, Project.MSG_WARN);
             }
             maybeSetResultPropertyValue(returnCode);
             redirector.complete();
@@ -645,9 +644,8 @@
                 if (failOnError) {
                     throw new BuildException(getTaskType() + " returned: "
                         + returnCode, getLocation());
-                } else {
-                    log("Result: " + returnCode, Project.MSG_ERR);
                 }
+                log("Result: " + returnCode, Project.MSG_ERR);
             }
         } else {
             exe.spawn();
@@ -674,9 +672,8 @@
             if (failIfExecFails) {
                 throw new BuildException("Execute failed: " + e.toString(), e,
                                          getLocation());
-            } else {
-                log("Execute failed: " + e.toString(), Project.MSG_ERR);
             }
+            log("Execute failed: " + e.toString(), Project.MSG_ERR);
         } finally {
             // close the output file if required
             logFlush();
diff --git a/src/main/org/apache/tools/ant/taskdefs/Execute.java b/src/main/org/apache/tools/ant/taskdefs/Execute.java
index d9923e8..8063a99 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Execute.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Execute.java
@@ -24,7 +24,7 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.StringReader;
-import java.util.ArrayList;
+import java.io.UnsupportedEncodingException;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -54,18 +54,6 @@
      */
     public static final int INVALID = Integer.MAX_VALUE;
 
-    private String[] cmdl = null;
-    private String[] env = null;
-    private int exitValue = INVALID;
-    private ExecuteStreamHandler streamHandler;
-    private final ExecuteWatchdog watchdog;
-    private File workingDirectory = null;
-    private Project project = null;
-    private boolean newEnvironment = false;
-
-    /** Controls whether the VM is used to launch commands, where possible. */
-    private boolean useVMLauncher = true;
-
     private static String antWorkingDirectory = System.getProperty("user.dir");
     private static Map<String, String> procEnvironment = null;
 
@@ -81,6 +69,18 @@
         }
     }
 
+    private String[] cmdl = null;
+    private String[] env = null;
+    private int exitValue = INVALID;
+    private ExecuteStreamHandler streamHandler;
+    private final ExecuteWatchdog watchdog;
+    private File workingDirectory = null;
+    private Project project = null;
+    private boolean newEnvironment = false;
+
+    /** Controls whether the VM is used to launch commands, where possible. */
+    private boolean useVMLauncher = true;
+
     /**
      * Set whether or not you want the process to be spawned.
      * Default is not spawned.
@@ -104,7 +104,7 @@
      * @return a map containing the environment variables.
      * @since Ant 1.8.2
      */
-    public static synchronized Map<String,String> getEnvironmentVariables() {
+    public static synchronized Map<String, String> getEnvironmentVariables() {
         if (procEnvironment != null) {
             return procEnvironment;
         }
@@ -117,7 +117,7 @@
             }
         }
 
-        procEnvironment = new LinkedHashMap<String, String>();
+        procEnvironment = new LinkedHashMap<>();
         try {
             ByteArrayOutputStream out = new ByteArrayOutputStream();
             Execute exe = new Execute(new PumpStreamHandler(out));
@@ -149,7 +149,7 @@
                 } else {
                     // New env var...append the previous one if we have it.
                     if (var != null) {
-                        int eq = var.indexOf("=");
+                        int eq = var.indexOf('=');
                         procEnvironment.put(var.substring(0, eq),
                                             var.substring(eq + 1));
                     }
@@ -158,10 +158,10 @@
             }
             // Since we "look ahead" before adding, there's one last env var.
             if (var != null) {
-                int eq = var.indexOf("=");
+                int eq = var.indexOf('=');
                 procEnvironment.put(var.substring(0, eq), var.substring(eq + 1));
             }
-        } catch (java.io.IOException exc) {
+        } catch (IOException exc) {
             exc.printStackTrace(); //NOSONAR
             // Just try to see how much we got
         }
@@ -177,7 +177,7 @@
      */
     @Deprecated
     public static synchronized Vector<String> getProcEnvironment() {
-        Vector<String> v = new Vector<String>();
+        Vector<String> v = new Vector<>();
         for (Entry<String, String> entry : getEnvironmentVariables().entrySet()) {
             v.add(entry.getKey() + "=" + entry.getValue());
         }
@@ -195,16 +195,17 @@
         if (Os.isFamily("os/2")) {
             // OS/2 - use same mechanism as Windows 2000
             return new String[] {"cmd", "/c", "set"};
-        } else if (Os.isFamily("windows")) {
+        }
+        if (Os.isFamily("windows")) {
             // Determine if we're running under XP/2000/NT or 98/95
             if (Os.isFamily("win9x")) {
                 // Windows 98/95
                 return new String[] {"command.com", "/c", "set"};
-            } else {
-                // Windows XP/2000/NT/2003
-                return new String[] {"cmd", "/c", "set"};
             }
-        } else if (Os.isFamily("z/os") || Os.isFamily("unix")) {
+            // Windows XP/2000/NT/2003
+            return new String[] {"cmd", "/c", "set"};
+        }
+        if (Os.isFamily("z/os") || Os.isFamily("unix")) {
             // On most systems one could use: /bin/sh -c env
 
             // Some systems have /bin/env, others /usr/bin/env, just try
@@ -218,16 +219,17 @@
                 cmd[0] = "env";
             }
             return cmd;
-        } else if (Os.isFamily("netware") || Os.isFamily("os/400")) {
+        }
+        if (Os.isFamily("netware") || Os.isFamily("os/400")) {
             // rely on PATH
             return new String[] {"env"};
-        } else if (Os.isFamily("openvms")) {
-            return new String[] {"show", "logical"};
-        } else {
-            // MAC OS 9 and previous
-            // TODO: I have no idea how to get it, someone must fix it
-            return null;
         }
+        if (Os.isFamily("openvms")) {
+            return new String[] {"show", "logical"};
+        }
+        // MAC OS 9 and previous
+        // TODO: I have no idea how to get it, someone must fix it
+        return null;
     }
 
     /**
@@ -244,13 +246,13 @@
         if (Os.isFamily("z/os")) {
             try {
                 return bos.toString("Cp1047");
-            } catch (java.io.UnsupportedEncodingException e) {
+            } catch (UnsupportedEncodingException e) {
                 // noop default encoding used
             }
         } else if (Os.isFamily("os/400")) {
             try {
                 return bos.toString("Cp500");
-            } catch (java.io.UnsupportedEncodingException e) {
+            } catch (UnsupportedEncodingException e) {
                 // noop default encoding used
             }
         }
@@ -417,7 +419,7 @@
                                  String[] env, File dir, boolean useVM)
         throws IOException {
         if (dir != null && !dir.exists()) {
-            throw new BuildException(dir + " doesn't exist.");
+            throw new BuildException("%s doesn't exist.", dir);
         }
 
         CommandLauncher vmLauncher = CommandLauncher.getVMLauncher(project);
@@ -435,7 +437,7 @@
      */
     public int execute() throws IOException {
         if (workingDirectory != null && !workingDirectory.exists()) {
-            throw new BuildException(workingDirectory + " doesn't exist.");
+            throw new BuildException("%s doesn't exist.", workingDirectory);
         }
         final Process process = launch(project, getCommandline(),
                                        getEnvironment(), workingDirectory,
@@ -492,7 +494,7 @@
      */
     public void spawn() throws IOException {
         if (workingDirectory != null && !workingDirectory.exists()) {
-            throw new BuildException(workingDirectory + " doesn't exist.");
+            throw new BuildException("%s doesn't exist.", workingDirectory);
         }
         final Process process = launch(project, getCommandline(),
                                        getEnvironment(), workingDirectory,
@@ -611,7 +613,7 @@
             return env;
         }
         Map<String, String> osEnv =
-            new LinkedHashMap<String, String>(getEnvironmentVariables());
+            new LinkedHashMap<>(getEnvironmentVariables());
         for (int i = 0; i < env.length; i++) {
             String keyValue = env[i];
             String key = keyValue.substring(0, keyValue.indexOf('='));
@@ -624,7 +626,7 @@
 
                 for (String osEnvItem : osEnv.keySet()) {
                     // Nb: using default locale as key is a env name
-                    if (osEnvItem.toLowerCase().equals(key.toLowerCase())) {
+                    if (osEnvItem.equalsIgnoreCase(key)) {
                         // Use the original case of the key
                         key = osEnvItem;
                         break;
@@ -636,11 +638,8 @@
             osEnv.put(key, keyValue.substring(key.length() + 1));
         }
 
-        ArrayList<String> l = new ArrayList<String>();
-        for (Entry<String, String> entry : osEnv.entrySet()) {
-            l.add(entry.getKey() + "=" + entry.getValue());
-        }
-        return l.toArray(new String[osEnv.size()]);
+        return osEnv.entrySet().stream()
+            .map(e -> e.getKey() + "=" + e.getValue()).toArray(String[]::new);
     }
 
     /**
@@ -651,7 +650,7 @@
      * @param cmdline The command to execute.
      * @throws BuildException if the command does not exit successfully.
      */
-    public static void runCommand(Task task, String[] cmdline)
+    public static void runCommand(Task task, String... cmdline)
         throws BuildException {
         try {
             task.log(Commandline.describeCommand(cmdline),
@@ -665,7 +664,7 @@
                 throw new BuildException(cmdline[0]
                     + " failed with return code " + retval, task.getLocation());
             }
-        } catch (java.io.IOException exc) {
+        } catch (IOException exc) {
             throw new BuildException("Could not launch " + cmdline[0] + ": "
                 + exc, task.getLocation());
         }
@@ -695,9 +694,9 @@
      */
     private static Map<String, String> getVMSLogicals(BufferedReader in)
         throws IOException {
-        HashMap<String, String> logicals = new HashMap<String, String>();
+        Map<String, String> logicals = new HashMap<>();
         String logName = null, logValue = null, newLogName;
-        String line = null;
+        String line;
         // CheckStyle:MagicNumber OFF
         while ((line = in.readLine()) != null) {
             // parse the VMS logicals into required format ("VAR=VAL[,VAL2]")
diff --git a/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java b/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
index 2f65308..1f38038 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
@@ -97,6 +97,7 @@
      * @deprecated since 1.4.x.
      *             manage output at the task level.
      */
+    @Deprecated
     public void setOutput(PrintStream out) {
     }
 
@@ -122,7 +123,7 @@
             if (sysProperties != null) {
                 sysProperties.setSystem();
             }
-            Class<?> target = null;
+            Class<?> target;
             try {
                 if (classpath == null) {
                     target = Class.forName(classname);
@@ -137,18 +138,18 @@
                     target = Class.forName(classname, true, loader);
                 }
             } catch (ClassNotFoundException e) {
-                throw new BuildException("Could not find " + classname + "."
-                                         + " Make sure you have it in your"
-                                         + " classpath");
+                throw new BuildException(
+                    "Could not find %s. Make sure you have it in your classpath",
+                    classname);
             }
             main = target.getMethod("main", new Class[] {String[].class});
             if (main == null) {
-                throw new BuildException("Could not find main() method in "
-                                         + classname);
+                throw new BuildException("Could not find main() method in %s",
+                    classname);
             }
             if ((main.getModifiers() & Modifier.STATIC) == 0) {
-                throw new BuildException("main() method in " + classname
-                    + " is not declared static");
+                throw new BuildException(
+                    "main() method in %s is not declared static", classname);
             }
             if (timeout == null) {
                 run(); //NOSONAR
@@ -212,6 +213,7 @@
      * Run this ExecuteJava in a Thread.
      * @since Ant 1.5
      */
+    @Override
     public void run() {
         final Object[] argument = {javaCommand.getArguments()};
         try {
@@ -242,6 +244,7 @@
      * @param w the responsible Watchdog.
      * @since Ant 1.5
      */
+    @Override
     public synchronized void timeoutOccured(Watchdog w) {
         if (thread != null) {
             timedOut = true;
diff --git a/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java b/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java
index 39cc03a..7202211 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java
@@ -20,7 +20,10 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 import java.util.Vector;
 
 import org.apache.tools.ant.BuildException;
@@ -60,8 +63,9 @@
     // switching type to "dir" when we encounter a DirSet that would
     // be more difficult to achieve otherwise.
 
-    protected Vector<AbstractFileSet> filesets = new Vector<AbstractFileSet>(); // contains AbstractFileSet
-                                              // (both DirSet and FileSet)
+    // (both DirSet and FileSet)
+    protected Vector<AbstractFileSet> filesets = new Vector<>();
+
     private Union resources = null;
     private boolean relative = false;
     private boolean parallel = false;
@@ -296,6 +300,7 @@
     /**
      * Check the configuration of this ExecuteOn instance.
      */
+    @Override
     protected void checkConfiguration() {
 //     * @TODO using taskName here is brittle, as a user could override it.
 //     *       this should probably be modified to use the classname instead.
@@ -303,7 +308,7 @@
             log("!! execon is deprecated. Use apply instead. !!");
         }
         super.checkConfiguration();
-        if (filesets.size() == 0 && resources == null) {
+        if (filesets.isEmpty() && resources == null) {
             throw new BuildException("no resources specified",
                                      getLocation());
         }
@@ -326,6 +331,7 @@
      * @return <code>ExecuteStreamHandler</code>.
      * @throws BuildException on error.
      */
+    @Override
     protected ExecuteStreamHandler createHandler() throws BuildException {
         //if we have a RedirectorElement, return a decoy
         return (redirectorElement == null) ? super.createHandler() : new PumpStreamHandler();
@@ -334,6 +340,7 @@
     /**
      * Set up the I/O Redirector.
      */
+    @Override
     protected void setupRedirector() {
         super.setupRedirector();
         redirector.setAppendProperties(true);
@@ -344,23 +351,21 @@
      * @param exe the Execute instance representing the external process.
      * @throws BuildException on error
      */
+    @Override
     protected void runExec(Execute exe) throws BuildException {
         int totalFiles = 0;
         int totalDirs = 0;
         boolean haveExecuted = false;
         try {
-            Vector<String> fileNames = new Vector<String>();
-            Vector<File> baseDirs = new Vector<File>();
-            final int size = filesets.size();
-            for (int i = 0; i < size; i++) {
+            Vector<String> fileNames = new Vector<>();
+            Vector<File> baseDirs = new Vector<>();
+            for (AbstractFileSet fs : filesets) {
                 String currentType = type;
-                AbstractFileSet fs = filesets.elementAt(i);
                 if (fs instanceof DirSet) {
                     if (!FileDirBoth.DIR.equals(type)) {
                         log("Found a nested dirset but type is " + type + ". "
-                            + "Temporarily switching to type=\"dir\" on the"
-                            + " assumption that you really did mean"
-                            + " <dirset> not <fileset>.", Project.MSG_DEBUG);
+                            + "Temporarily switching to type=\"dir\" on the assumption that you really did mean <dirset> not <fileset>.",
+                            Project.MSG_DEBUG);
                         currentType = FileDirBoth.DIR;
                     }
                 }
@@ -372,33 +377,31 @@
                     String[] s = getFiles(base, ds);
                     for (int j = 0; j < s.length; j++) {
                         totalFiles++;
-                        fileNames.addElement(s[j]);
-                        baseDirs.addElement(base);
+                        fileNames.add(s[j]);
+                        baseDirs.add(base);
                     }
                 }
                 if (!FileDirBoth.FILE.equals(currentType)) {
                     String[] s = getDirs(base, ds);
                     for (int j = 0; j < s.length; j++) {
                         totalDirs++;
-                        fileNames.addElement(s[j]);
-                        baseDirs.addElement(base);
+                        fileNames.add(s[j]);
+                        baseDirs.add(base);
                     }
                 }
-                if (fileNames.size() == 0 && skipEmpty) {
+                if (fileNames.isEmpty() && skipEmpty) {
                     logSkippingFileset(currentType, ds, base);
                     continue;
                 }
                 if (!parallel) {
-                    String[] s = new String[fileNames.size()];
-                    fileNames.copyInto(s);
-                    for (int j = 0; j < s.length; j++) {
-                        String[] command = getCommandline(s[j], base);
+                    for (String srcFile : fileNames) {
+                        String[] command = getCommandline(srcFile, base);
                         log(Commandline.describeCommand(command), Project.MSG_VERBOSE);
                         exe.setCommandline(command);
 
                         if (redirectorElement != null) {
                             setupRedirector();
-                            redirectorElement.configure(redirector, s[j]);
+                            redirectorElement.configure(redirector, srcFile);
                         }
                         if (redirectorElement != null || haveExecuted) {
                             // need to reset the stream handler to restart
@@ -409,8 +412,8 @@
                         runExecute(exe);
                         haveExecuted = true;
                     }
-                    fileNames.removeAllElements();
-                    baseDirs.removeAllElements();
+                    fileNames.clear();
+                    baseDirs.clear();
                 }
             }
 
@@ -464,12 +467,12 @@
                         }
                         runExecute(exe);
                         haveExecuted = true;
-                        fileNames.removeAllElements();
-                        baseDirs.removeAllElements();
+                        fileNames.clear();
+                        baseDirs.clear();
                     }
                 }
             }
-            if (parallel && (fileNames.size() > 0 || !skipEmpty)) {
+            if (parallel && (!fileNames.isEmpty() || !skipEmpty)) {
                 runParallel(exe, fileNames, baseDirs);
                 haveExecuted = true;
             }
@@ -514,31 +517,31 @@
      */
     protected String[] getCommandline(String[] srcFiles, File[] baseDirs) {
         final char fileSeparator = File.separatorChar;
-        Vector<String> targets = new Vector<String>();
+        List<String> targets = new ArrayList<>();
         if (targetFilePos != null) {
-            HashSet<String> addedFiles = new HashSet<String>();
+            Set<String> addedFiles = new HashSet<>();
             for (int i = 0; i < srcFiles.length; i++) {
                 String[] subTargets = mapper.mapFileName(srcFiles[i]);
                 if (subTargets != null) {
-                    for (int j = 0; j < subTargets.length; j++) {
-                        String name = null;
-                        if (!relative) {
-                            name = new File(destDir, subTargets[j]).getAbsolutePath();
+                    for (String subTarget : subTargets) {
+                        String name;
+                        if (relative) {
+                            name = subTarget;
                         } else {
-                            name = subTargets[j];
+                            name = new File(destDir, subTarget).getAbsolutePath();
                         }
                         if (forwardSlash && fileSeparator != '/') {
                             name = name.replace(fileSeparator, '/');
                         }
                         if (!addedFiles.contains(name)) {
-                            targets.addElement(name);
+                            targets.add(name);
                             addedFiles.add(name);
                         }
                     }
                 }
             }
         }
-        String[] targetFiles = (String[]) targets.toArray(new String[targets.size()]);
+        String[] targetFiles = targets.toArray(new String[targets.size()]);
 
         if (!addSourceFile) {
             srcFiles = new String[0];
@@ -686,10 +689,8 @@
     protected void runParallel(Execute exe, Vector<String> fileNames,
                                Vector<File> baseDirs)
         throws IOException, BuildException {
-        String[] s = new String[fileNames.size()];
-        fileNames.copyInto(s);
-        File[] b = new File[baseDirs.size()];
-        baseDirs.copyInto(b);
+        String[] s = fileNames.toArray(new String[fileNames.size()]);
+        File[] b = baseDirs.toArray(new File[baseDirs.size()]);
 
         if (maxParallel <= 0 || s.length == 0 /* this is skipEmpty == false */) {
             String[] command = getCommandline(s, b);
@@ -740,7 +741,7 @@
                                           String[] arguments,
                                           int insertPosition,
                                           String prefix, String suffix) {
-        if (prefix.length() == 0 && suffix.length() == 0) {
+        if (prefix.isEmpty() && suffix.isEmpty()) {
             System.arraycopy(targetFiles, 0, arguments, insertPosition,
                              targetFiles.length);
         } else {
@@ -760,11 +761,13 @@
         public static final String FILE = "file";
         /** Dir value */
         public static final String DIR = "dir";
+
         /**
+         * {@inheritDoc}
          * @see EnumeratedAttribute#getValues
          */
-        /** {@inheritDoc}. */
-       public String[] getValues() {
+        @Override
+        public String[] getValues() {
             return new String[] {FILE, DIR, "both"};
         }
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/ExecuteWatchdog.java b/src/main/org/apache/tools/ant/taskdefs/ExecuteWatchdog.java
index cc3933e..4925f54 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ExecuteWatchdog.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ExecuteWatchdog.java
@@ -74,6 +74,7 @@
      *             Use constructor with a long type instead.
      * (1.4.x compatibility)
      */
+    @Deprecated
     public ExecuteWatchdog(int timeout) {
         this((long) timeout);
     }
@@ -112,6 +113,7 @@
      * This can be called in the watchdog thread
      * @param w the watchdog
      */
+    @Override
     public synchronized void timeoutOccured(Watchdog w) {
         try {
             try {
@@ -174,4 +176,3 @@
         return killedProcess;
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/Exit.java b/src/main/org/apache/tools/ant/taskdefs/Exit.java
index 3f82302..9749c8d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Exit.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Exit.java
@@ -50,12 +50,13 @@
 public class Exit extends Task {
 
     private static class NestedCondition extends ConditionBase implements Condition {
+        @Override
         public boolean eval() {
             if (countConditions() != 1) {
                 throw new BuildException(
                     "A single nested condition is required.");
             }
-            return ((Condition) (getConditions().nextElement())).eval();
+            return getConditions().nextElement().eval();
         }
     }
 
@@ -131,12 +132,13 @@
      * the if and unless parameters (if present).
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         boolean fail = (nestedConditionPresent()) ? testNestedCondition()
                      : (testIfCondition() && testUnlessCondition());
         if (fail) {
             String text = null;
-            if (message != null && message.trim().length() > 0) {
+            if (!(message == null || message.trim().isEmpty())) {
                 text = message.trim();
             } else {
                 if (ifCondition != null && !"".equals(ifCondition)
@@ -154,15 +156,13 @@
                 }
                 if (nestedConditionPresent()) {
                     text = "condition satisfied";
-                } else {
-                    if (text == null) {
-                        text = "No message";
-                    }
+                } else if (text == null) {
+                    text = "No message";
                 }
             }
             log("failing due to " + text, Project.MSG_DEBUG);
-            throw ((status == null) ? new BuildException(text)
-             : new ExitStatusException(text, status.intValue()));
+            throw status == null ? new BuildException(text)
+                : new ExitStatusException(text, status.intValue());
         }
     }
 
@@ -217,8 +217,8 @@
         boolean result = nestedConditionPresent();
 
         if (result && ifCondition != null || unlessCondition != null) {
-            throw new BuildException("Nested conditions "
-                + "not permitted in conjunction with if/unless attributes");
+            throw new BuildException(
+                "Nested conditions not permitted in conjunction with if/unless attributes");
         }
 
         return result && nestedCondition.eval();
diff --git a/src/main/org/apache/tools/ant/taskdefs/Expand.java b/src/main/org/apache/tools/ant/taskdefs/Expand.java
index a586556..6ae42e8 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Expand.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Expand.java
@@ -20,13 +20,15 @@
 
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
 import java.util.Date;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 import java.util.Vector;
 
@@ -58,25 +60,26 @@
  *           name="unwar"
  */
 public class Expand extends Task {
+    public static final String NATIVE_ENCODING = "native-encoding";
+
+    /** Error message when more that one mapper is defined */
+    public static final String ERROR_MULTIPLE_MAPPERS = "Cannot define more than one mapper";
+
+    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
     private static final int BUFFER_SIZE = 1024;
     private File dest; //req
     private File source; // req
     private boolean overwrite = true;
     private Mapper mapperElement = null;
-    private Vector<PatternSet> patternsets = new Vector<PatternSet>();
+    private List<PatternSet> patternsets = new Vector<>();
     private Union resources = new Union();
     private boolean resourcesSpecified = false;
     private boolean failOnEmptyArchive = false;
     private boolean stripAbsolutePathSpec = false;
     private boolean scanForUnicodeExtraFields = true;
 
-    public static final String NATIVE_ENCODING = "native-encoding";
-
     private String encoding;
-    /** Error message when more that one mapper is defined */
-    public static final String ERROR_MULTIPLE_MAPPERS = "Cannot define more than one mapper";
-
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
 
     /**
      * Creates an Expand instance and sets encoding to UTF-8.
@@ -120,14 +123,15 @@
      *
      * @exception BuildException Thrown in unrecoverable error.
      */
+    @Override
     public void execute() throws BuildException {
         if ("expand".equals(getTaskType())) {
             log("!! expand is deprecated. Use unzip instead. !!");
         }
 
         if (source == null && !resourcesSpecified) {
-            throw new BuildException("src attribute and/or resources must be "
-                                     + "specified");
+            throw new BuildException(
+                "src attribute and/or resources must be specified");
         }
 
         if (dest == null) {
@@ -143,13 +147,14 @@
             if (source.isDirectory()) {
                 throw new BuildException("Src must not be a directory."
                     + " Use nested filesets instead.", getLocation());
-            } else if (!source.exists()) {
-                throw new BuildException("src '" + source + "' doesn't exist.");
-            } else if (!source.canRead()) {
-                throw new BuildException("src '" + source + "' cannot be read.");
-            } else {
-                expandFile(FILE_UTILS, source, dest);
             }
+            if (!source.exists()) {
+                throw new BuildException("src '" + source + "' doesn't exist.");
+            }
+            if (!source.canRead()) {
+                throw new BuildException("src '" + source + "' cannot be read.");
+            }
+            expandFile(FILE_UTILS, source, dest);
         }
         for (Resource r : resources) {
             if (!r.isExists()) {
@@ -175,7 +180,6 @@
      */
     protected void expandFile(FileUtils fileUtils, File srcF, File dir) {
         log("Expanding: " + srcF + " into " + dir, Project.MSG_INFO);
-        ZipFile zf = null;
         FileNameMapper mapper = getMapper();
         if (!srcF.exists()) {
             throw new BuildException("Unable to expand "
@@ -183,8 +187,9 @@
                     + " as the file does not exist",
                     getLocation());
         }
-        try {
-            zf = new ZipFile(srcF, encoding, scanForUnicodeExtraFields);
+        try (
+            ZipFile
+            zf = new ZipFile(srcF, encoding, scanForUnicodeExtraFields)){
             boolean empty = true;
             Enumeration<ZipEntry> e = zf.getEntries();
             while (e.hasMoreElements()) {
@@ -202,7 +207,7 @@
                 }
             }
             if (empty && getFailOnEmptyArchive()) {
-                throw new BuildException("archive '" + srcF + "' is empty");
+                throw new BuildException("archive '%s' is empty", srcF);
             }
             log("expand complete", Project.MSG_VERBOSE);
         } catch (IOException ioe) {
@@ -210,8 +215,6 @@
                 "Error while expanding " + srcF.getPath()
                 + "\n" + ioe.toString(),
                 ioe);
-        } finally {
-            ZipFile.closeQuietly(zf);
         }
     }
 
@@ -222,8 +225,8 @@
      * @param dir       the destination directory
      */
     protected void expandResource(Resource srcR, File dir) {
-        throw new BuildException("only filesystem based resources are"
-                                 + " supported by this task.");
+        throw new BuildException(
+            "only filesystem based resources are supported by this task.");
     }
 
     /**
@@ -231,13 +234,10 @@
      * @return a filenamemapper for a file
      */
     protected FileNameMapper getMapper() {
-        FileNameMapper mapper = null;
         if (mapperElement != null) {
-            mapper = mapperElement.getImplementation();
-        } else {
-            mapper = new IdentityMapper();
+            return mapperElement.getImplementation();
         }
-        return mapper;
+        return new IdentityMapper();
     }
 
     // CheckStyle:ParameterNumberCheck OFF - bc
@@ -259,7 +259,7 @@
                                boolean isDirectory, FileNameMapper mapper)
                                throws IOException {
 
-        if (stripAbsolutePathSpec && entryName.length() > 0
+        if (stripAbsolutePathSpec && !entryName.isEmpty()
             && (entryName.charAt(0) == File.separatorChar
                 || entryName.charAt(0) == '/'
                 || entryName.charAt(0) == '\\')) {
@@ -268,16 +268,16 @@
             entryName = entryName.substring(1);
         }
 
-        if (patternsets != null && patternsets.size() > 0) {
+        if (!(patternsets == null || patternsets.isEmpty())) {
             String name = entryName.replace('/', File.separatorChar)
                 .replace('\\', File.separatorChar);
 
             boolean included = false;
-            Set<String> includePatterns = new HashSet<String>();
-            Set<String> excludePatterns = new HashSet<String>();
+            Set<String> includePatterns = new HashSet<>();
+            Set<String> excludePatterns = new HashSet<>();
             final int size = patternsets.size();
             for (int v = 0; v < size; v++) {
-                PatternSet p = patternsets.elementAt(v);
+                PatternSet p = patternsets.get(v);
                 String[] incls = p.getIncludePatterns(getProject());
                 if (incls == null || incls.length == 0) {
                     // no include pattern implicitly means includes="**"
@@ -352,20 +352,11 @@
                 f.mkdirs();
             } else {
                 byte[] buffer = new byte[BUFFER_SIZE];
-                int length = 0;
-                FileOutputStream fos = null;
-                try {
-                    fos = new FileOutputStream(f);
-
-                    while ((length =
-                            compressedInputStream.read(buffer)) >= 0) {
+                try (OutputStream fos = Files.newOutputStream(f.toPath())) {
+                    int length;
+                    while ((length = compressedInputStream.read(buffer)) >= 0) {
                         fos.write(buffer, 0, length);
                     }
-
-                    fos.close();
-                    fos = null;
-                } finally {
-                    FileUtils.close(fos);
                 }
             }
 
@@ -412,7 +403,7 @@
      * @param set a pattern set
      */
     public void addPatternset(PatternSet set) {
-        patternsets.addElement(set);
+        patternsets.add(set);
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/taskdefs/Filter.java b/src/main/org/apache/tools/ant/taskdefs/Filter.java
index 390ba5b..da4b350 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Filter.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Filter.java
@@ -69,6 +69,7 @@
      * Execute the task.
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         boolean isFiltersFromFile =
             filtersFile != null && token == null && value == null;
@@ -76,9 +77,9 @@
             filtersFile == null && token != null && value != null;
 
         if (!isFiltersFromFile && !isSingleFilter) {
-            throw new BuildException("both token and value parameters, or "
-                                     + "only a filtersFile parameter is "
-                                     + "required", getLocation());
+            throw new BuildException(
+                "both token and value parameters, or only a filtersFile parameter is required",
+                getLocation());
         }
 
         if (isSingleFilter) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java b/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java
index 867c579..9660ec4 100644
--- a/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java
+++ b/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java
@@ -20,11 +20,11 @@
 
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.file.Files;
 import java.util.Enumeration;
 import java.util.NoSuchElementException;
 import java.util.Vector;
@@ -115,6 +115,7 @@
      * @return a Reader.
      * @since Ant 1.7?
      */
+    @Override
     public final Reader chain(final Reader rdr) {
         return filter.chain(rdr);
     }
@@ -181,15 +182,16 @@
      * @deprecated since 1.4.x.
      *             Use {@link #setEol setEol} instead.
      */
+    @Deprecated
     public void setCr(AddAsisRemove attr) {
         log("DEPRECATED: The cr attribute has been deprecated,",
             Project.MSG_WARN);
         log("Please use the eol attribute instead", Project.MSG_WARN);
         String option = attr.getValue();
         CrLf c = new CrLf();
-        if (option.equals("remove")) {
+        if ("remove".equals(option)) {
             c.setValue("lf");
-        } else if (option.equals("asis")) {
+        } else if ("asis".equals(option)) {
             c.setValue("asis");
         } else {
             // must be "add"
@@ -282,6 +284,7 @@
      * Executes the task.
      * @throws BuildException on error.
      */
+    @Override
     public void execute() throws BuildException {
         // first off, make sure that we've got a srcdir and destdir
         validate();
@@ -322,22 +325,21 @@
         }
         if (!srcDir.exists()) {
             throw new BuildException(
-                FIXCRLF_ERROR + "srcdir does not exist: '" + srcDir + "'");
+                FIXCRLF_ERROR + "srcdir does not exist: '%s'", srcDir);
         }
         if (!srcDir.isDirectory()) {
             throw new BuildException(
-                FIXCRLF_ERROR + "srcdir is not a directory: '" + srcDir + "'");
+                FIXCRLF_ERROR + "srcdir is not a directory: '%s'", srcDir);
         }
         if (destDir != null) {
             if (!destDir.exists()) {
                 throw new BuildException(
-                    FIXCRLF_ERROR + "destdir does not exist: '"
-                    + destDir + "'");
+                    FIXCRLF_ERROR + "destdir does not exist: '%s'", destDir);
             }
             if (!destDir.isDirectory()) {
                 throw new BuildException(
-                    FIXCRLF_ERROR + "destdir is not a directory: '"
-                    + destDir + "'");
+                    FIXCRLF_ERROR + "destdir is not a directory: '%s'",
+                    destDir);
             }
         }
     }
@@ -350,7 +352,7 @@
         if (fcv == null) {
             FilterChain fc = new FilterChain();
             fc.add(filter);
-            fcv = new Vector<FilterChain>(1);
+            fcv = new Vector<>(1);
             fcv.add(fc);
         }
         File tmpFile = FILE_UTILS.createTempFile("fixcrlf", "", null, true, true);
@@ -391,6 +393,7 @@
      * Deprecated, the functionality has been moved to filters.FixCrLfFilter.
      * @deprecated since 1.7.0.
      */
+    @Deprecated
     protected class OneLiner implements Enumeration<Object> {
         private static final int UNDEF = -1;
         private static final int NOTJAVA = 0;
@@ -421,7 +424,7 @@
                 reader = new BufferedReader(
                     ((encoding == null) ? new FileReader(srcFile)
                     : new InputStreamReader(
-                    new FileInputStream(srcFile), encoding)), INBUFLEN);
+                    Files.newInputStream(srcFile.toPath()), encoding)), INBUFLEN);
 
                 nextLine();
             } catch (IOException e) {
@@ -549,6 +552,7 @@
         /**
          * @return true if there is more elements.
          */
+        @Override
         public boolean hasMoreElements() {
             return !reachedEof;
         }
@@ -558,6 +562,7 @@
          * @return the next element.
          * @throws NoSuchElementException if there is no more.
          */
+        @Override
         public Object nextElement()
             throws NoSuchElementException {
             if (!hasMoreElements()) {
@@ -673,22 +678,24 @@
      */
     public static class AddAsisRemove extends EnumeratedAttribute {
         /** {@inheritDoc}. */
+        @Override
         public String[] getValues() {
             return new String[] {"add", "asis", "remove"};
         }
     }
 
     /**
-     * Enumerated attribute with the values "asis", "cr", "lf" and "crlf".
+     * Enumerated attribute with the values "asis", "cr", "lf", "crlf", "mac", "unix" and "dos.
      */
     public static class CrLf extends EnumeratedAttribute {
         /**
          * @see EnumeratedAttribute#getValues
          * {@inheritDoc}.
          */
+        @Override
         public String[] getValues() {
             return new String[] {"asis", "cr", "lf", "crlf", "mac", "unix",
-                    "dos"};
+                "dos"};
         }
     }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/GUnzip.java b/src/main/org/apache/tools/ant/taskdefs/GUnzip.java
index b891bae..d0fe4b0 100644
--- a/src/main/org/apache/tools/ant/taskdefs/GUnzip.java
+++ b/src/main/org/apache/tools/ant/taskdefs/GUnzip.java
@@ -18,13 +18,12 @@
 
 package org.apache.tools.ant.taskdefs;
 
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
 import java.util.zip.GZIPInputStream;
 
 import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.util.FileUtils;
 
 /**
  * Expands a file that has been compressed with the GZIP
@@ -44,6 +43,7 @@
      * Get the default extension.
      * @return the value ".gz"
      */
+    @Override
     protected String getDefaultExtension() {
         return DEFAULT_EXTENSION;
     }
@@ -51,18 +51,14 @@
     /**
      * Implement the gunzipping.
      */
+    @Override
     protected void extract() {
         if (srcResource.getLastModified() > dest.lastModified()) {
             log("Expanding " + srcResource.getName() + " to "
                         + dest.getAbsolutePath());
-
-            FileOutputStream out = null;
-            GZIPInputStream zIn = null;
-            InputStream fis = null;
-            try {
-                out = new FileOutputStream(dest);
-                fis = srcResource.getInputStream();
-                zIn = new GZIPInputStream(fis);
+            try (OutputStream out = Files.newOutputStream(dest.toPath());
+                    GZIPInputStream zIn =
+                        new GZIPInputStream(srcResource.getInputStream())) {
                 byte[] buffer = new byte[BUFFER_SIZE];
                 int count = 0;
                 do {
@@ -72,10 +68,6 @@
             } catch (IOException ioe) {
                 String msg = "Problem expanding gzip " + ioe.getMessage();
                 throw new BuildException(msg, ioe, getLocation());
-            } finally {
-                FileUtils.close(fis);
-                FileUtils.close(out);
-                FileUtils.close(zIn);
             }
         }
     }
@@ -91,6 +83,7 @@
      * @return true if this task supports non file resources.
      * @since Ant 1.7
      */
+    @Override
     protected boolean supportsNonFileResources() {
         return getClass().equals(GUnzip.class);
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/GZip.java b/src/main/org/apache/tools/ant/taskdefs/GZip.java
index 029f414..8803647 100644
--- a/src/main/org/apache/tools/ant/taskdefs/GZip.java
+++ b/src/main/org/apache/tools/ant/taskdefs/GZip.java
@@ -18,12 +18,11 @@
 
 package org.apache.tools.ant.taskdefs;
 
-import java.io.FileOutputStream;
 import java.io.IOException;
+import java.nio.file.Files;
 import java.util.zip.GZIPOutputStream;
 
 import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.util.FileUtils;
 
 /**
  * Compresses a file with the GZIP algorithm. Normally used to compress
@@ -38,16 +37,14 @@
     /**
      * perform the GZip compression operation.
      */
+    @Override
     protected void pack() {
-        GZIPOutputStream zOut = null;
-        try {
-            zOut = new GZIPOutputStream(new FileOutputStream(zipFile));
+        try (GZIPOutputStream zOut =
+            new GZIPOutputStream(Files.newOutputStream(zipFile.toPath()))) {
             zipResource(getSrcResource(), zOut);
         } catch (IOException ioe) {
             String msg = "Problem creating gzip " + ioe.getMessage();
             throw new BuildException(msg, ioe, getLocation());
-        } finally {
-            FileUtils.close(zOut);
         }
     }
 
@@ -62,6 +59,7 @@
      * @return true if this case supports non file resources.
      * @since Ant 1.7
      */
+    @Override
     protected boolean supportsNonFileResources() {
         return getClass().equals(GZip.class);
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/GenerateKey.java b/src/main/org/apache/tools/ant/taskdefs/GenerateKey.java
index c26ac36..7270e67 100644
--- a/src/main/org/apache/tools/ant/taskdefs/GenerateKey.java
+++ b/src/main/org/apache/tools/ant/taskdefs/GenerateKey.java
@@ -17,8 +17,12 @@
  */
 package org.apache.tools.ant.taskdefs;
 
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.List;
 import java.util.Vector;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Task;
@@ -83,7 +87,7 @@
      * A class corresponding to the dname nested element.
      */
     public static class DistinguishedName {
-        private Vector<DnameParam> params = new Vector<DnameParam>();
+        private List<DnameParam> params = new Vector<>();
 
         /**
          * Create a param nested element.
@@ -91,8 +95,7 @@
          */
         public Object createParam() {
             DnameParam param = new DnameParam();
-            params.addElement(param);
-
+            params.add(param);
             return param;
         }
 
@@ -101,7 +104,7 @@
          * @return an enumeration of the nested parameters.
          */
         public Enumeration<DnameParam> getParams() {
-            return params.elements();
+            return Collections.enumeration(params);
         }
 
         /**
@@ -111,26 +114,10 @@
          * This is used on the command line.
          * @return a string rep of this name
          */
+        @Override
         public String toString() {
-            final int size = params.size();
-            final StringBuffer sb = new StringBuffer();
-            boolean firstPass = true;
-
-            for (int i = 0; i < size; i++) {
-                if (!firstPass) {
-                    sb.append(" ,");
-                }
-                firstPass = false;
-
-                final DnameParam param = (DnameParam) params.elementAt(i);
-                if (param.isComplete()) {
-                    sb.append(encode(param.getName()));
-                    sb.append('=');
-                    sb.append(encode(param.getValue()));
-                }
-            }
-
-            return sb.toString();
+            return params.stream().map(p -> p.getName() + "=" + p.getValue())
+                .collect(Collectors.joining(", "));
         }
 
         /**
@@ -141,26 +128,8 @@
          * @return the encoded value.
          */
         public String encode(final String string) {
-            int end = string.indexOf(',');
-
-            if (-1 == end) {
-              return string;
-            }
-
-            final StringBuffer sb = new StringBuffer();
-
-            int start = 0;
-
-            while (-1 != end) {
-                sb.append(string.substring(start, end));
-                sb.append("\\,");
-                start = end + 1;
-                end = string.indexOf(',', start);
-            }
-
-            sb.append(string.substring(start));
-
-            return sb.toString();
+            return Stream.of(string.split(","))
+                .collect(Collectors.joining("\\,"));
         }
     }
 
@@ -197,12 +166,11 @@
      */
     public DistinguishedName createDname() throws BuildException {
         if (null != expandedDname) {
-            throw new BuildException("DName sub-element can only be "
-                                     + "specified once.");
+            throw new BuildException("DName sub-element can only be specified once.");
         }
         if (null != dname) {
-            throw new BuildException("It is not possible to specify dname "
-                                    + " both as attribute and element.");
+            throw new BuildException(
+                "It is not possible to specify dname  both as attribute and element.");
         }
         expandedDname = new DistinguishedName();
         return expandedDname;
@@ -215,8 +183,8 @@
      */
     public void setDname(final String dname) {
         if (null != expandedDname) {
-            throw new BuildException("It is not possible to specify dname "
-                                    + " both as attribute and element.");
+            throw new BuildException(
+                "It is not possible to specify dname  both as attribute and element.");
         }
         this.dname = dname;
     }
@@ -324,6 +292,7 @@
      * Execute the task.
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
 
         if (null == alias) {
@@ -338,7 +307,7 @@
             throw new BuildException("dname must be set");
         }
 
-        final StringBuffer sb = new StringBuffer();
+        final StringBuilder sb = new StringBuilder();
 
         sb.append("-genkey ");
 
@@ -400,7 +369,6 @@
             sb.append("\" ");
         }
 
-
         if (0 < keysize) {
             sb.append("-keysize \"");
             sb.append(keysize);
diff --git a/src/main/org/apache/tools/ant/taskdefs/Get.java b/src/main/org/apache/tools/ant/taskdefs/Get.java
index 13f610c..34c1dd7 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Get.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Get.java
@@ -19,7 +19,6 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -27,6 +26,7 @@
 import java.net.HttpURLConnection;
 import java.net.URL;
 import java.net.URLConnection;
+import java.nio.file.Files;
 import java.util.Date;
 import java.util.zip.GZIPInputStream;
 
@@ -35,6 +35,7 @@
 import org.apache.tools.ant.Main;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.email.Header;
 import org.apache.tools.ant.types.Mapper;
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.types.ResourceCollection;
@@ -43,6 +44,10 @@
 import org.apache.tools.ant.types.resources.URLResource;
 import org.apache.tools.ant.util.FileNameMapper;
 import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
 
 /**
  * Gets a particular file from a URL source.
@@ -89,6 +94,9 @@
                            DEFAULT_AGENT_PREFIX + "/"
                            + Main.getShortAntVersion());
 
+    // Store headers as key/value pair without duplicate in keyz
+    private Map<String, String> headers = new LinkedHashMap<>();
+
     /**
      * Does the work.
      *
@@ -109,7 +117,7 @@
                     if (path.endsWith("/")) {
                         path = path.substring(0, path.length() - 1);
                     }
-                    final int slash = path.lastIndexOf("/");
+                    final int slash = path.lastIndexOf('/');
                     if (slash > -1) {
                         path = path.substring(slash + 1);
                     }
@@ -121,11 +129,13 @@
                         log("skipping " + r + " - mapper can't handle it",
                             Project.MSG_WARN);
                         continue;
-                    } else if (d.length == 0) {
+                    }
+                    if (d.length == 0) {
                         log("skipping " + r + " - mapper returns no file name",
                             Project.MSG_WARN);
                         continue;
-                    } else if (d.length > 1) {
+                    }
+                    if (d.length > 1) {
                         log("skipping " + r + " - mapper returns multiple file"
                             + " names", Project.MSG_WARN);
                         continue;
@@ -279,8 +289,8 @@
         for (final Resource r : sources) {
             final URLProvider up = r.as(URLProvider.class);
             if (up == null) {
-                throw new BuildException("Only URLProvider resources are"
-                                         + " supported", getLocation());
+                throw new BuildException(
+                    "Only URLProvider resources are supported", getLocation());
             }
         }
 
@@ -290,9 +300,8 @@
 
         if (destination.exists() && sources.size() > 1
             && !destination.isDirectory()) {
-            throw new BuildException("The specified destination is not a"
-                                     + " directory",
-                                     getLocation());
+            throw new BuildException(
+                "The specified destination is not a directory", getLocation());
         }
 
         if (destination.exists() && !destination.canWrite()) {
@@ -383,7 +392,6 @@
         useTimestamp = v;
     }
 
-
     /**
      * Username for basic auth.
      *
@@ -485,6 +493,21 @@
     }
 
     /**
+     * Add a nested header
+     * @param header to be added
+     *
+     */
+    public void addConfiguredHeader(Header header) {
+        if (header != null) {
+            String key = StringUtils.trimToNull(header.getName());
+            String value = StringUtils.trimToNull(header.getValue());
+            if (key != null && value != null) {
+                this.headers.put(key, value);
+            }
+        }
+    }
+
+    /**
      * Define the mapper to map source to destination files.
      * @return a mapper to be configured.
      * @exception BuildException if more than one mapper is defined.
@@ -545,6 +568,7 @@
         /**
          * begin a download
          */
+        @Override
         public void beginDownload() {
         }
 
@@ -552,12 +576,14 @@
          * tick handler
          *
          */
+        @Override
         public void onTick() {
         }
 
         /**
          * end a download
          */
+        @Override
         public void endDownload() {
         }
     }
@@ -582,6 +608,7 @@
         /**
          * begin a download
          */
+        @Override
         public void beginDownload() {
             dots = 0;
         }
@@ -590,6 +617,7 @@
          * tick handler
          *
          */
+        @Override
         public void onTick() {
             out.print(".");
             if (dots++ > DOTS_PER_LINE) {
@@ -601,6 +629,7 @@
         /**
          * end a download
          */
+        @Override
         public void endDownload() {
             out.println();
             out.flush();
@@ -722,6 +751,12 @@
                 connection.setRequestProperty("Accept-Encoding", GZIP_CONTENT_ENCODING);
             }
 
+            for (final Map.Entry<String, String> header : headers.entrySet()) {
+                //we do not log the header value as it may contain sensitive data like passwords
+                log(String.format("Adding header '%s' ", header.getKey()));
+                connection.setRequestProperty(header.getKey(), header.getValue());
+            }
+
             if (connection instanceof HttpURLConnection) {
                 ((HttpURLConnection) connection).setInstanceFollowRedirects(false);
                 connection.setUseCaches(httpUseCaches);
@@ -767,9 +802,8 @@
                     if (ignoreErrors) {
                         log(message, logLevel);
                         return null;
-                    } else {
-                        throw new BuildException(message);
                     }
+                    throw new BuildException(message);
                 }
             }
 
@@ -814,7 +848,7 @@
                 is = new GZIPInputStream(is);
             }
 
-            os = new FileOutputStream(dest);
+            os = Files.newOutputStream(dest.toPath());
             progress.beginDownload();
             boolean finished = false;
             try {
diff --git a/src/main/org/apache/tools/ant/taskdefs/HostInfo.java b/src/main/org/apache/tools/ant/taskdefs/HostInfo.java
index 1391298..771ae7b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/HostInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/HostInfo.java
@@ -105,8 +105,9 @@
      * @throws BuildException
      *             on error.
      */
+    @Override
     public void execute() throws BuildException {
-        if (host == null || "".equals(host)) {
+        if (host == null || host.isEmpty()) {
             executeLocal();
         } else {
             executeRemote();
@@ -115,7 +116,7 @@
 
     private void executeLocal() {
         try {
-            inetAddrs = new LinkedList<InetAddress>();
+            inetAddrs = new LinkedList<>();
             Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
             while (interfaces.hasMoreElements()) {
                 NetworkInterface currentif = interfaces.nextElement();
@@ -175,34 +176,32 @@
         if (best == null) {
             // none selected so far, so this one is better.
             best = current;
+        } else if (current == null || current.isLoopbackAddress()) {
+            // definitely not better than the previously selected address.
+        } else if (current.isLinkLocalAddress()) {
+            // link local considered better than loopback
+            if (best.isLoopbackAddress()) {
+                best = current;
+            }
+        } else if (current.isSiteLocalAddress()) {
+            // site local considered better than link local (and loopback)
+            // address with hostname resolved considered better than
+            // address without hostname
+            if (best.isLoopbackAddress()
+                    || best.isLinkLocalAddress()
+                    || (best.isSiteLocalAddress() && !hasHostName(best))) {
+                best = current;
+            }
         } else {
-            if (current == null || current.isLoopbackAddress()) {
-                // definitely not better than the previously selected address.
-            } else if (current.isLinkLocalAddress()) {
-                // link local considered better than loopback
-                if (best.isLoopbackAddress()) {
-                    best = current;
-                }
-            } else if (current.isSiteLocalAddress()) {
-                // site local considered better than link local (and loopback)
-                // address with hostname resolved considered better than
-                // address without hostname
-                if (best.isLoopbackAddress()
-                        || best.isLinkLocalAddress()
-                        || (best.isSiteLocalAddress() && !hasHostName(best))) {
-                    best = current;
-                }
-            } else {
-                // current is a "Global address", considered better than
-                // site local (and better than link local, loopback)
-                // address with hostname resolved considered better than
-                // address without hostname
-                if (best.isLoopbackAddress()
-                        || best.isLinkLocalAddress()
-                        || best.isSiteLocalAddress()
-                        || !hasHostName(best)) {
-                    best = current;
-                }
+            // current is a "Global address", considered better than
+            // site local (and better than link local, loopback)
+            // address with hostname resolved considered better than
+            // address without hostname
+            if (best.isLoopbackAddress()
+                    || best.isLinkLocalAddress()
+                    || best.isSiteLocalAddress()
+                    || !hasHostName(best)) {
+                best = current;
             }
         }
         return best;
diff --git a/src/main/org/apache/tools/ant/taskdefs/ImportTask.java b/src/main/org/apache/tools/ant/taskdefs/ImportTask.java
index 0ddd597..9fd4fc7 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ImportTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ImportTask.java
@@ -63,12 +63,13 @@
  * @ant.task category="control"
  */
 public class ImportTask extends Task {
+    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
     private String file;
     private boolean optional;
     private String targetPrefix = ProjectHelper.USE_PROJECT_NAME_AS_TARGET_PREFIX;
     private String prefixSeparator = ".";
     private final Union resources = new Union();
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
 
     public ImportTask() {
         resources.setCache(true);
@@ -126,18 +127,18 @@
         resources.add(r);
     }
 
+    @Override
     public void execute() {
-        if (file == null && resources.size() == 0) {
-            throw new BuildException("import requires file attribute or"
-                                     + " at least one nested resource");
+        if (file == null && resources.isEmpty()) {
+            throw new BuildException(
+                "import requires file attribute or at least one nested resource");
         }
         if (getOwningTarget() == null
-            || !"".equals(getOwningTarget().getName())) {
+            || !getOwningTarget().getName().isEmpty()) {
             throw new BuildException("import only allowed as a top-level task");
         }
 
-        ProjectHelper helper =
-                (ProjectHelper) getProject().
+        ProjectHelper helper = getProject().
                     getReference(ProjectHelper.PROJECTHELPER_REFERENCE);
 
         if (helper == null) {
@@ -145,9 +146,7 @@
             throw new BuildException("import requires support in ProjectHelper");
         }
 
-        Vector<Object> importStack = helper.getImportStack();
-
-        if (importStack.size() == 0) {
+        if (helper.getImportStack().isEmpty()) {
             // this happens if ant is used with a project
             // helper that doesn't set the import.
             throw new BuildException("import requires support in ProjectHelper");
@@ -169,8 +168,6 @@
 
     private void importResource(ProjectHelper helper,
                                 Resource importedResource) {
-        Vector<Object> importStack = helper.getImportStack();
-
         getProject().log("Importing file " + importedResource + " from "
                          + getLocation().getFileName(), Project.MSG_VERBOSE);
 
@@ -181,13 +178,12 @@
             if (optional) {
                 getProject().log(message, Project.MSG_VERBOSE);
                 return;
-            } else {
-                throw new BuildException(message);
             }
+            throw new BuildException(message);
         }
 
-        if (!isInIncludeMode() &&
-            hasAlreadyBeenImported(importedResource, importStack)) {
+        if (!isInIncludeMode() && hasAlreadyBeenImported(importedResource,
+            helper.getImportStack())) {
             getProject().log(
                 "Skipped already imported file:\n   "
                 + importedResource + "\n", Project.MSG_VERBOSE);
@@ -206,10 +202,10 @@
                 prefix = oldPrefix + oldSep + targetPrefix;
             } else if (isInIncludeMode()) {
                 prefix = targetPrefix;
-            } else if (!ProjectHelper.USE_PROJECT_NAME_AS_TARGET_PREFIX.equals(targetPrefix)) {
-                prefix = targetPrefix;
-            } else {
+            } else if (ProjectHelper.USE_PROJECT_NAME_AS_TARGET_PREFIX.equals(targetPrefix)) {
                 prefix = oldPrefix;
+            } else {
+                prefix = targetPrefix;
             }
             setProjectHelperProps(prefix, prefixSeparator,
                                   isInIncludeMode());
@@ -263,9 +259,8 @@
             } catch (MalformedURLException ex) {
                 log(ex.toString(), Project.MSG_VERBOSE);
             }
-            throw new BuildException("failed to resolve " + file
-                                     + " relative to "
-                                     + getLocation().getFileName());
+            throw new BuildException("failed to resolve %s relative to %s",
+                file, getLocation().getFileName());
         }
         return null;
     }
@@ -277,22 +272,14 @@
 
     private boolean hasAlreadyBeenImported(Resource importedResource,
                                            Vector<Object> importStack) {
-        File importedFile = null;
-        FileProvider fp = importedResource.as(FileProvider.class);
-        if (fp != null) {
-            importedFile = fp.getFile();
-        }
-        URL importedURL = null;
-        URLProvider up = importedResource.as(URLProvider.class);
-        if (up != null) {
-            importedURL = up.getURL();
-        }
-        for (Object o : importStack) {
-            if (isOneOf(o, importedResource, importedFile, importedURL)) {
-                return true;
-            }
-        }
-        return false;
+        File importedFile = importedResource.asOptional(FileProvider.class)
+            .map(FileProvider::getFile).orElse(null);
+
+        URL importedURL = importedResource.asOptional(URLProvider.class)
+            .map(URLProvider::getURL).orElse(null);
+
+        return importStack.stream().anyMatch(
+            o -> isOneOf(o, importedResource, importedFile, importedURL));
     }
 
     private boolean isOneOf(Object o, Resource importedResource,
diff --git a/src/main/org/apache/tools/ant/taskdefs/Input.java b/src/main/org/apache/tools/ant/taskdefs/Input.java
index 2f5eea0..5eabe73 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Input.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Input.java
@@ -18,8 +18,7 @@
 
 package org.apache.tools.ant.taskdefs;
 
-import java.util.Vector;
-
+import java.util.List;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Task;
 import org.apache.tools.ant.input.DefaultInputHandler;
@@ -59,6 +58,7 @@
         public void setRefid(final String refid) {
             this.refid = refid;
         }
+
         /**
          * Get the refid of this Handler.
          * @return String refid.
@@ -66,6 +66,7 @@
         public String getRefid() {
             return refid;
         }
+
         /**
          * Set the InputHandler classname.
          * @param classname the String classname.
@@ -73,6 +74,7 @@
         public void setClassname(final String classname) {
             this.classname = classname;
         }
+
         /**
          * Get the classname of the InputHandler.
          * @return String classname.
@@ -80,6 +82,7 @@
         public String getClassname() {
             return classname;
         }
+
         /**
          * Set the handler type.
          * @param type a HandlerType.
@@ -87,6 +90,7 @@
         public void setType(final HandlerType type) {
             this.type = type;
         }
+
         /**
          * Get the handler type.
          * @return a HandlerType object.
@@ -94,6 +98,7 @@
         public HandlerType getType() {
             return type;
         }
+
         private InputHandler getInputHandler() {
             if (type != null) {
                return type.getInputHandler();
@@ -107,8 +112,8 @@
                }
             }
             if (classname != null) {
-               return (InputHandler) (ClasspathUtils.newInstance(classname,
-                   createLoader(), InputHandler.class));
+               return ClasspathUtils.newInstance(classname,
+                   createLoader(), InputHandler.class);
             }
             throw new BuildException(
                 "Must specify refid, classname or type");
@@ -132,6 +137,7 @@
         public String[] getValues() {
             return VALUES;
         }
+
         private InputHandler getInputHandler() {
             return HANDLERS[getIndex()];
         }
@@ -192,19 +198,13 @@
      * @param msg The message to be displayed.
      */
     public void addText(final String msg) {
-        if (messageAttribute && "".equals(msg.trim())) {
+        if (messageAttribute && msg.trim().isEmpty()) {
             return;
         }
         message += getProject().replaceProperties(msg);
     }
 
     /**
-     * No arg constructor.
-     */
-    public Input () {
-    }
-
-    /**
      * Actual method executed by ant.
      * @throws BuildException on error
      */
@@ -219,7 +219,7 @@
 
         InputRequest request = null;
         if (validargs != null) {
-            final Vector<String> accept = StringUtils.split(validargs, ',');
+            final List<String> accept = StringUtils.split(validargs, ',');
             request = new MultipleChoiceInputRequest(message, accept);
         } else {
             request = new InputRequest(message);
@@ -233,7 +233,7 @@
         h.handleInput(request);
 
         String value = request.getInput();
-        if ((value == null || value.trim().length() == 0)
+        if ((value == null || value.trim().isEmpty())
             && defaultvalue != null) {
             value = defaultvalue;
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java b/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java
index 0954e70..3b8dd46 100644
--- a/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java
@@ -24,7 +24,6 @@
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Properties;
@@ -98,7 +97,7 @@
      * getting an OutOfMemoryError when calling this task
      * multiple times in a row.
      */
-    private static Hashtable<String, AntClassLoader> LOADER_MAP = new Hashtable<String, AntClassLoader>(HASH_TABLE_SIZE);
+    private static Hashtable<String, AntClassLoader> LOADER_MAP = new Hashtable<>(HASH_TABLE_SIZE);
 
     private boolean caching = true;
 
@@ -152,7 +151,7 @@
      *
      * @since Ant 1.8.0
      */
-    private List<Property> connectionProperties = new ArrayList<Property>();
+    private List<Property> connectionProperties = new ArrayList<>();
 
     /**
      * Sets the classpath for loading the driver.
@@ -344,20 +343,17 @@
             throw new BuildException("Url attribute must be set!", getLocation());
         }
         try {
-
             log("connecting to " + getUrl(), Project.MSG_VERBOSE);
             Properties info = new Properties();
             info.put("user", getUserId());
             info.put("password", getPassword());
 
-            for (Iterator<Property> props = connectionProperties.iterator();
-                 props.hasNext();) {
-                Property p = props.next();
-                String name = p.getName();
-                String value = p.getValue();
+            for (Property p : connectionProperties) {
+            String name = p.getName();
+            String value = p.getValue();
                 if (name == null || value == null) {
-                    log("Only name/value pairs are supported as connection"
-                        + " properties.", Project.MSG_WARN);
+                    log("Only name/value pairs are supported as connection properties.",
+                        Project.MSG_WARN);
                 } else {
                     log("Setting connection property " + name + " to " + value,
                         Project.MSG_VERBOSE);
@@ -376,14 +372,12 @@
             return conn;
         } catch (SQLException e) {
             // failed to connect
-            if (!failOnConnectionError) {
-                log("Failed to connect: " + e.getMessage(), Project.MSG_WARN);
-                return null;
-            } else {
+            if (failOnConnectionError) {
                 throw new BuildException(e, getLocation());
             }
+            log("Failed to connect: " + e.getMessage(), Project.MSG_WARN);
+            return null;
         }
-
     }
 
     /**
@@ -397,9 +391,9 @@
             throw new BuildException("Driver attribute must be set!", getLocation());
         }
 
-        Driver driverInstance = null;
+        Driver driverInstance;
         try {
-            Class<?> dc;
+            Class<? extends Driver> dc;
             if (classpath != null) {
                 // check first that it is not already loaded otherwise
                 // consecutive runs seems to end into an OutOfMemoryError
@@ -425,13 +419,13 @@
                                 Project.MSG_VERBOSE);
                     }
                 }
-                dc = loader.loadClass(driver);
+                dc = loader.loadClass(driver).asSubclass(Driver.class);
             } else {
                 log("Loading " + driver + " using system loader.",
                     Project.MSG_VERBOSE);
-                dc = Class.forName(driver);
+                dc = Class.forName(driver).asSubclass(Driver.class);
             }
-            driverInstance = (Driver) dc.newInstance();
+            driverInstance = dc.newInstance();
         } catch (ClassNotFoundException e) {
             throw new BuildException(
                     "Class Not Found: JDBC driver " + driver + " could not be loaded",
@@ -451,7 +445,6 @@
         return driverInstance;
     }
 
-
     /**
      * Set the caching attribute.
      * @param value a <code>boolean</code> value
diff --git a/src/main/org/apache/tools/ant/taskdefs/Jar.java b/src/main/org/apache/tools/ant/taskdefs/Jar.java
index f31ac6f..f105cb4 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Jar.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Jar.java
@@ -21,7 +21,6 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -29,12 +28,16 @@
 import java.io.PrintWriter;
 import java.io.Reader;
 import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
+import java.util.SortedMap;
 import java.util.StringTokenizer;
 import java.util.TreeMap;
 import java.util.Vector;
@@ -74,7 +77,7 @@
     /**
      * List of all known SPI Services
      */
-    private List<Service> serviceList = new ArrayList<Service>();
+    private List<Service> serviceList = new ArrayList<>();
 
     /** merged manifests added through addConfiguredManifest */
     private Manifest configuredManifest;
@@ -138,7 +141,7 @@
      *
      * @since Ant 1.6
      */
-    private Vector<String> rootEntries;
+    private List<String> rootEntries;
 
     /**
      * Path containing jars that shall be indexed in addition to this archive.
@@ -182,7 +185,7 @@
         emptyBehavior = "create";
         setEncoding("UTF8");
         setZip64Mode(Zip64ModeAttribute.NEVER);
-        rootEntries = new Vector<String>();
+        rootEntries = new Vector<>();
     }
 
     /**
@@ -190,6 +193,7 @@
      * @param we not used
      * @ant.attribute ignore="true"
      */
+    @Override
     public void setWhenempty(WhenEmpty we) {
         log("JARs are never empty, they contain at least a manifest file",
             Project.MSG_WARN);
@@ -225,6 +229,7 @@
      * @deprecated since 1.5.x.
      *             Use setDestFile(File) instead.
      */
+    @Deprecated
     public void setJarfile(File jarFile) {
         setDestFile(jarFile);
     }
@@ -301,29 +306,13 @@
     }
 
     private Manifest getManifest(File manifestFile) {
-
-        Manifest newManifest = null;
-        FileInputStream fis = null;
-        InputStreamReader isr = null;
-        try {
-            fis = new FileInputStream(manifestFile);
-            if (manifestEncoding == null) {
-                isr = new InputStreamReader(fis);
-            } else {
-                isr = new InputStreamReader(fis, manifestEncoding);
-            }
-            newManifest = getManifest(isr);
-        } catch (UnsupportedEncodingException e) {
-            throw new BuildException("Unsupported encoding while reading manifest: "
-                                     + e.getMessage(), e);
+        try (InputStreamReader isr = new InputStreamReader(
+            Files.newInputStream(manifestFile.toPath()), getManifestCharset())) {
+            return getManifest(isr);
         } catch (IOException e) {
             throw new BuildException("Unable to read manifest file: "
-                                     + manifestFile
-                                     + " (" + e.getMessage() + ")", e);
-        } finally {
-            FileUtils.close(isr);
+                + manifestFile + " (" + e.getMessage() + ")", e);
         }
-        return newManifest;
     }
 
     /**
@@ -332,38 +321,27 @@
      * @since Ant 1.5.2
      */
     private Manifest getManifestFromJar(File jarFile) throws IOException {
-        ZipFile zf = null;
-        try {
-            zf = new ZipFile(jarFile);
+        try (ZipFile zf = new ZipFile(jarFile)) {
 
             // must not use getEntry as "well behaving" applications
             // must accept the manifest in any capitalization
             Enumeration<? extends ZipEntry> e = zf.entries();
             while (e.hasMoreElements()) {
                 ZipEntry ze = e.nextElement();
-                if (ze.getName().equalsIgnoreCase(MANIFEST_NAME)) {
-                    InputStreamReader isr =
-                        new InputStreamReader(zf.getInputStream(ze), "UTF-8");
-                    return getManifest(isr);
+                if (MANIFEST_NAME.equalsIgnoreCase(ze.getName())) {
+                    try (InputStreamReader isr =
+                        new InputStreamReader(zf.getInputStream(ze), "UTF-8")) {
+                        return getManifest(isr);
+                    }
                 }
             }
             return null;
-        } finally {
-            if (zf != null) {
-                try {
-                    zf.close();
-                } catch (IOException e) {
-                    // TODO - log an error?  throw an exception?
-                }
-            }
         }
     }
 
     private Manifest getManifest(Reader r) {
-
-        Manifest newManifest = null;
         try {
-            newManifest = new Manifest(r);
+            return new Manifest(r);
         } catch (ManifestException e) {
             log("Manifest is invalid: " + e.getMessage(), Project.MSG_ERR);
             throw new BuildException("Invalid Manifest: " + manifestFile,
@@ -372,29 +350,18 @@
             throw new BuildException("Unable to read manifest file"
                                      + " (" + e.getMessage() + ")", e);
         }
-        return newManifest;
     }
 
     private boolean jarHasIndex(File jarFile) throws IOException {
-        ZipFile zf = null;
-        try {
-            zf = new ZipFile(jarFile);
+        try (ZipFile zf = new ZipFile(jarFile)) {
             Enumeration<? extends ZipEntry> e = zf.entries();
             while (e.hasMoreElements()) {
                 ZipEntry ze = e.nextElement();
-                if (ze.getName().equalsIgnoreCase(INDEX_NAME)) {
+                if (INDEX_NAME.equalsIgnoreCase(ze.getName())) {
                     return true;
                 }
             }
             return false;
-        } finally {
-            if (zf != null) {
-                try {
-                    zf.close();
-                } catch (IOException e) {
-                    // TODO - log an error?  throw an exception?
-                }
-            }
         }
     }
 
@@ -416,7 +383,7 @@
         mergeManifestsMain = config != null && "merge".equals(config.getValue());
 
         if (filesetManifestConfig != null
-            && !filesetManifestConfig.getValue().equals("skip")) {
+            && !"skip".equals(filesetManifestConfig.getValue())) {
 
             doubleFilePass = true;
         }
@@ -461,19 +428,12 @@
      */
     private void writeServices(ZipOutputStream zOut) throws IOException {
         for (Service service : serviceList) {
-           InputStream is = null;
-           try {
-               is = service.getAsStream();
-               //stolen from writeManifest
+            try (InputStream is = service.getAsStream()) {
+                //stolen from writeManifest
                super.zipFile(is, zOut,
                              "META-INF/services/" + service.getType(),
                              System.currentTimeMillis(), null,
                              ZipFileSet.DEFAULT_FILE_MODE);
-           } finally {
-               // technically this is unnecessary since
-               // Service.getAsStream returns a ByteArrayInputStream
-               // and not closing it wouldn't do any harm.
-               FileUtils.close(is);
            }
         }
     }
@@ -505,6 +465,7 @@
      * @throws IOException on I/O errors
      * @throws BuildException on other errors
      */
+    @Override
     protected void initZipOutputStream(ZipOutputStream zOut)
         throws IOException, BuildException {
 
@@ -518,12 +479,10 @@
     private Manifest createManifest()
         throws BuildException {
         try {
-            if (manifest == null) {
-                if (manifestFile != null) {
-                    // if we haven't got the manifest yet, attempt to
-                    // get it now and have manifest be the final merge
-                    manifest = getManifest(manifestFile);
-                }
+            if (manifest == null && manifestFile != null) {
+                // if we haven't got the manifest yet, attempt to
+                // get it now and have manifest be the final merge
+                manifest = getManifest(manifestFile);
             }
 
             // fileset manifest must come even before the default
@@ -612,6 +571,7 @@
      * @throws IOException on I/O errors
      * @throws BuildException on other errors
      */
+    @Override
     protected void finalizeZipOutputStream(ZipOutputStream zOut)
         throws IOException, BuildException {
 
@@ -681,14 +641,10 @@
             throw new IOException("Encountered an error writing jar index");
         }
         writer.close();
-        ByteArrayInputStream bais =
-            new ByteArrayInputStream(baos.toByteArray());
-        try {
+        try (ByteArrayInputStream bais =
+            new ByteArrayInputStream(baos.toByteArray())) {
             super.zipFile(bais, zOut, INDEX_NAME, System.currentTimeMillis(),
                           null, ZipFileSet.DEFAULT_FILE_MODE);
-        } finally {
-            // not really required
-            FileUtils.close(bais);
         }
     }
 
@@ -704,6 +660,7 @@
      * @param mode the Unix permissions to set.
      * @throws IOException on error
      */
+    @Override
     protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath,
                            long lastModified, File fromArchive, int mode)
         throws IOException {
@@ -717,8 +674,8 @@
                            + " be replaced by a newly generated one.",
                            Project.MSG_WARN);
         } else {
-            if (index && vPath.indexOf("/") == -1) {
-                rootEntries.addElement(vPath);
+            if (index && vPath.indexOf('/') == -1) {
+                rootEntries.add(vPath);
             }
             super.zipFile(is, zOut, vPath, lastModified, fromArchive, mode);
         }
@@ -729,40 +686,29 @@
             // If this is the same name specified in 'manifest', this
             // is the manifest to use
             log("Found manifest " + file, Project.MSG_VERBOSE);
-            try {
-                if (is != null) {
-                    InputStreamReader isr;
-                    if (manifestEncoding == null) {
-                        isr = new InputStreamReader(is);
-                    } else {
-                        isr = new InputStreamReader(is, manifestEncoding);
-                    }
+            if (is == null) {
+                manifest = getManifest(file);
+            } else {
+                try (InputStreamReader isr =
+                    new InputStreamReader(is, getManifestCharset())) {
                     manifest = getManifest(isr);
-                } else {
-                    manifest = getManifest(file);
                 }
-            } catch (UnsupportedEncodingException e) {
-                throw new BuildException("Unsupported encoding while reading "
-                    + "manifest: " + e.getMessage(), e);
             }
         } else if (filesetManifestConfig != null
-                    && !filesetManifestConfig.getValue().equals("skip")) {
+                    && !"skip".equals(filesetManifestConfig.getValue())) {
             // we add this to our group of fileset manifests
             logWhenWriting("Found manifest to merge in file " + file,
                            Project.MSG_VERBOSE);
 
             try {
-                Manifest newManifest = null;
-                if (is != null) {
-                    InputStreamReader isr;
-                    if (manifestEncoding == null) {
-                        isr = new InputStreamReader(is);
-                    } else {
-                        isr = new InputStreamReader(is, manifestEncoding);
-                    }
-                    newManifest = getManifest(isr);
-                } else {
+                Manifest newManifest;
+                if (is == null) {
                     newManifest = getManifest(file);
+                } else {
+                    try (InputStreamReader isr =
+                        new InputStreamReader(is, getManifestCharset())) {
+                        newManifest = getManifest(isr);
+                    }
                 }
 
                 if (filesetManifest == null) {
@@ -818,6 +764,7 @@
      *
      * @exception BuildException if it likes
      */
+    @Override
     protected ArchiveState getResourcesToAdd(ResourceCollection[] rcs,
                                              File zipFile,
                                              boolean needsUpdate)
@@ -888,33 +835,32 @@
      * @return true for historic reasons
      * @throws BuildException on error
      */
+    @Override
     protected boolean createEmptyZip(File zipFile) throws BuildException {
         if (!createEmpty) {
             return true;
         }
 
-        if (emptyBehavior.equals("skip")) {
+        if ("skip".equals(emptyBehavior)) {
             if (!skipWriting) {
                 log("Warning: skipping " + archiveType + " archive "
                     + zipFile + " because no files were included.",
                     Project.MSG_WARN);
             }
             return true;
-        } else if (emptyBehavior.equals("fail")) {
+        }
+        if ("fail".equals(emptyBehavior)) {
             throw new BuildException("Cannot create " + archiveType
                                      + " archive " + zipFile
                                      + ": no files were included.",
                                      getLocation());
         }
 
-        ZipOutputStream zOut = null;
-        try {
-            if (!skipWriting) {
-                log("Building MANIFEST-only jar: "
+        if (!skipWriting) {
+            log("Building MANIFEST-only jar: "
                     + getDestFile().getAbsolutePath());
-            }
-            zOut = new ZipOutputStream(getDestFile());
-
+        }
+        try (ZipOutputStream zOut = new ZipOutputStream(getDestFile())) {
             zOut.setEncoding(getEncoding());
             zOut.setUseZip64(getZip64Mode().getMode());
             if (isCompress()) {
@@ -929,8 +875,6 @@
                                      + " (" + ioe.getMessage() + ")", ioe,
                                      getLocation());
         } finally {
-            // Close the output stream.
-            FileUtils.close(zOut);
             createEmpty = false;
         }
         return true;
@@ -942,6 +886,7 @@
      *
      * @see Zip#cleanUp
      */
+    @Override
     protected void cleanUp() {
         super.cleanUp();
         checkJarSpec();
@@ -953,7 +898,7 @@
             filesetManifest = null;
             originalManifest = null;
         }
-        rootEntries.removeAllElements();
+        rootEntries.clear();
     }
 
     // CheckStyle:LineLength OFF - Link is too long.
@@ -964,7 +909,7 @@
     // CheckStyle:LineLength ON
     private void checkJarSpec() {
         String br = System.getProperty("line.separator");
-        StringBuffer message = new StringBuffer();
+        StringBuilder message = new StringBuilder();
         Section mainSection = (configuredManifest == null)
                             ? null
                             : configuredManifest.getMainSection();
@@ -989,11 +934,10 @@
             message.append(br);
             message.append("Location: ").append(getLocation());
             message.append(br);
-            if (strict.getValue().equalsIgnoreCase("fail")) {
+            if ("fail".equalsIgnoreCase(strict.getValue())) {
                 throw new BuildException(message.toString(), getLocation());
-            } else {
-                logWhenWriting(message.toString(), strict.getLogLevel());
             }
+            logWhenWriting(message.toString(), strict.getLogLevel());
         }
     }
 
@@ -1004,6 +948,7 @@
      *
      * @since 1.44, Ant 1.5
      */
+    @Override
     public void reset() {
         super.reset();
         emptyBehavior = "create";
@@ -1022,6 +967,7 @@
          * Get the list of valid strings.
          * @return the list of values - "skip", "merge" and "mergewithoutmain"
          */
+        @Override
         public String[] getValues() {
             return new String[] {"skip", "merge", "mergewithoutmain"};
         }
@@ -1069,9 +1015,7 @@
             writer.println(dir);
         }
 
-        for (String file : files) {
-            writer.println(file);
-        }
+        files.forEach(writer::println);
     }
 
     /**
@@ -1097,39 +1041,27 @@
     protected static String findJarName(String fileName,
                                               String[] classpath) {
         if (classpath == null) {
-            return (new File(fileName)).getName();
+            return new File(fileName).getName();
         }
         fileName = fileName.replace(File.separatorChar, '/');
-        TreeMap<String, String> matches = new TreeMap<String, String>(new Comparator<Object>() {
-                // longest match comes first
-                public int compare(Object o1, Object o2) {
-                    if (o1 instanceof String && o2 instanceof String) {
-                        return ((String) o2).length()
-                            - ((String) o1).length();
-                    }
-                    return 0;
-                }
-            });
+        SortedMap<String, String> matches = new TreeMap<>(Comparator
+            .<String> comparingInt(s -> s == null ? 0 : s.length()).reversed());
 
-        for (int i = 0; i < classpath.length; i++) {
-            if (fileName.endsWith(classpath[i])) {
-                matches.put(classpath[i], classpath[i]);
-            } else {
-                int slash = classpath[i].indexOf("/");
-                String candidate = classpath[i];
-                while (slash > -1) {
-                    candidate = candidate.substring(slash + 1);
-                    if (fileName.endsWith(candidate)) {
-                        matches.put(candidate, classpath[i]);
-                        break;
-                    }
-                    slash = candidate.indexOf("/");
+        for (String element : classpath) {
+            String candidate = element;
+            while (true) {
+                if (fileName.endsWith(candidate)) {
+                    matches.put(candidate, element);
+                    break;
                 }
+                int slash = candidate.indexOf('/');
+                if (slash < 0) {
+                    break;
+                }
+                candidate = candidate.substring(slash + 1);
             }
         }
-
-        return matches.size() == 0
-            ? null : (String) matches.get(matches.firstKey());
+        return matches.isEmpty() ? null : matches.get(matches.firstKey());
     }
 
     /**
@@ -1144,43 +1076,38 @@
     protected static void grabFilesAndDirs(String file, List<String> dirs,
                                                  List<String> files)
         throws IOException {
-        org.apache.tools.zip.ZipFile zf = null;
-        try {
-            zf = new org.apache.tools.zip.ZipFile(file, "utf-8");
+        try (org.apache.tools.zip.ZipFile zf = new org.apache.tools.zip.ZipFile(file, "utf-8")) {
             Enumeration<org.apache.tools.zip.ZipEntry> entries = zf.getEntries();
-            HashSet<String> dirSet = new HashSet<String>();
+            Set<String> dirSet = new HashSet<>();
             while (entries.hasMoreElements()) {
                 org.apache.tools.zip.ZipEntry ze =
                     entries.nextElement();
                 String name = ze.getName();
                 if (ze.isDirectory()) {
                     dirSet.add(name);
-                } else if (name.indexOf("/") == -1) {
+                } else if (name.indexOf('/') == -1) {
                     files.add(name);
                 } else {
                     // a file, not in the root
                     // since the jar may be one without directory
                     // entries, add the parent dir of this file as
                     // well.
-                    dirSet.add(name.substring(0, name.lastIndexOf("/") + 1));
+                    dirSet.add(name.substring(0, name.lastIndexOf('/') + 1));
                 }
             }
             dirs.addAll(dirSet);
-        } finally {
-            if (zf != null) {
-                zf.close();
-            }
         }
     }
 
     private Resource[][] grabManifests(ResourceCollection[] rcs) {
         Resource[][] manifests = new Resource[rcs.length][];
         for (int i = 0; i < rcs.length; i++) {
-            Resource[][] resources = null;
+            Resource[][] resources;
             if (rcs[i] instanceof FileSet) {
                 resources = grabResources(new FileSet[] {(FileSet) rcs[i]});
             } else {
-                resources = grabNonFileSetResources(new ResourceCollection[] {rcs[i]});
+                resources = grabNonFileSetResources(
+                    new ResourceCollection[] {rcs[i]});
             }
             for (int j = 0; j < resources[0].length; j++) {
                 String name = resources[0][j].getName().replace('\\', '/');
@@ -1196,7 +1123,7 @@
                         name = prefix + name;
                     }
                 }
-                if (name.equalsIgnoreCase(MANIFEST_NAME)) {
+                if (MANIFEST_NAME.equalsIgnoreCase(name)) {
                     manifests[i] = new Resource[] {resources[0][j]};
                     break;
                 }
@@ -1208,11 +1135,26 @@
         return manifests;
     }
 
+    private Charset getManifestCharset() {
+        if (manifestEncoding == null) {
+            return Charset.defaultCharset();
+        }
+        try {
+            return Charset.forName(manifestEncoding);
+        } catch (IllegalArgumentException e) {
+            throw new BuildException(
+                "Unsupported encoding while reading manifest: "
+                    + e.getMessage(),
+                e);
+        }
+    }
+
     /** The strict enumerated type. */
     public static class StrictMode extends EnumeratedAttribute {
         /** Public no arg constructor. */
         public StrictMode() {
         }
+
         /**
          * Constructor with an arg.
          * @param value the enumerated value as a string.
@@ -1220,18 +1162,21 @@
         public StrictMode(String value) {
             setValue(value);
         }
+
         /**
          * Get List of valid strings.
          * @return the list of values.
          */
+        @Override
         public String[] getValues() {
             return new String[] {"fail", "warn", "ignore"};
         }
+
         /**
          * @return The log level according to the strict mode.
          */
         public int getLogLevel() {
-            return (getValue().equals("ignore")) ? Project.MSG_VERBOSE : Project.MSG_WARN;
+            return "ignore".equals(getValue()) ? Project.MSG_VERBOSE : Project.MSG_WARN;
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Java.java b/src/main/org/apache/tools/ant/taskdefs/Java.java
index ed9f906..b4b5a7e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Java.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Java.java
@@ -20,8 +20,6 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.Vector;
 
 import org.apache.tools.ant.BuildException;
@@ -52,6 +50,8 @@
  * @ant.task category="java"
  */
 public class Java extends Task {
+    private static final String TIMEOUT_MESSAGE =
+            "Timeout: killed the sub-process";
 
     private CommandlineJava cmdl = new CommandlineJava();
     private Environment env = new Environment();
@@ -78,9 +78,6 @@
     private boolean spawn = false;
     private boolean incompatibleWithSpawn = false;
 
-    private static final String TIMEOUT_MESSAGE =
-        "Timeout: killed the sub-process";
-
     /**
      * Normal constructor
      */
@@ -100,6 +97,7 @@
      * @throws BuildException if failOnError is set to true and the application
      * returns a nonzero result code.
      */
+    @Override
     public void execute() throws BuildException {
         File savedDir = dir;
         Permissions savedPermissions = perm;
@@ -148,30 +146,32 @@
             throw new BuildException("Classname must not be null.");
         }
         if (!fork && getCommandLine().getJar() != null) {
-            throw new BuildException("Cannot execute a jar in non-forked mode."
-                                     + " Please set fork='true'. ");
+            throw new BuildException(
+                "Cannot execute a jar in non-forked mode. Please set fork='true'. ");
         }
         if (!fork && getCommandLine().getModule() != null) {
-            throw new BuildException("Cannot execute a module in non-forked mode."
-                                     + " Please set fork='true'. ");
+            throw new BuildException(
+                "Cannot execute a module in non-forked mode. Please set fork='true'. ");
         }
         if (spawn && !fork) {
-            throw new BuildException("Cannot spawn a java process in non-forked mode."
-                                     + " Please set fork='true'. ");
+            throw new BuildException(
+                "Cannot spawn a java process in non-forked mode. Please set fork='true'. ");
         }
         if (getCommandLine().getClasspath() != null
             && getCommandLine().getJar() != null) {
-            log("When using 'jar' attribute classpath-settings are ignored. "
-                + "See the manual for more information.", Project.MSG_VERBOSE);
+            log("When using 'jar' attribute classpath-settings are ignored. See the manual for more information.",
+                Project.MSG_VERBOSE);
         }
         if (spawn && incompatibleWithSpawn) {
-            getProject().log("spawn does not allow attributes related to input, "
-            + "output, error, result", Project.MSG_ERR);
+            getProject().log(
+                "spawn does not allow attributes related to input, output, error, result",
+                Project.MSG_ERR);
             getProject().log("spawn also does not allow timeout", Project.MSG_ERR);
-            getProject().log("finally, spawn is not compatible "
-                + "with a nested I/O <redirector>", Project.MSG_ERR);
-            throw new BuildException("You have used an attribute "
-                + "or nested element which is not compatible with spawn");
+            getProject().log(
+                "finally, spawn is not compatible with a nested I/O <redirector>",
+                Project.MSG_ERR);
+            throw new BuildException(
+                "You have used an attribute or nested element which is not compatible with spawn");
         }
         if (getCommandLine().getAssertions() != null && !fork) {
             log("Assertion statements are currently ignored in non-forked mode");
@@ -191,8 +191,8 @@
                     Project.MSG_WARN);
             }
             if (newEnvironment || null != env.getVariables()) {
-                log("Changes to environment variables are ignored when same "
-                    + "JVM is used.", Project.MSG_WARN);
+                log("Changes to environment variables are ignored when same JVM is used.",
+                    Project.MSG_WARN);
             }
             if (getCommandLine().getBootclasspath() != null) {
                 log("bootclasspath ignored when same JVM is used.",
@@ -217,19 +217,17 @@
     protected int executeJava(CommandlineJava commandLine) {
         try {
             if (fork) {
-                if (!spawn) {
-                    return fork(commandLine.getCommandline());
-                } else {
+                if (spawn) {
                     spawn(commandLine.getCommandline());
                     return 0;
                 }
-            } else {
-                try {
-                    run(commandLine);
-                    return 0;
-                } catch (ExitException ex) {
-                    return ex.getStatus();
-                }
+                return fork(commandLine.getCommandline());
+            }
+            try {
+                run(commandLine);
+                return 0;
+            } catch (ExitException ex) {
+                return ex.getStatus();
             }
         } catch (BuildException e) {
             if (e.getLocation() == null && getLocation() != null) {
@@ -237,23 +235,21 @@
             }
             if (failOnError) {
                 throw e;
-            } else {
-                if (TIMEOUT_MESSAGE.equals(e.getMessage())) {
-                    log(TIMEOUT_MESSAGE);
-                } else {
-                    log(e);
-                }
-                return -1;
             }
+            if (TIMEOUT_MESSAGE.equals(e.getMessage())) {
+                log(TIMEOUT_MESSAGE);
+            } else {
+                log(e);
+            }
+            return -1;
         } catch (ThreadDeath t) {
             throw t; // cf. NB #47191
         } catch (Throwable t) {
             if (failOnError) {
                 throw new BuildException(t, getLocation());
-            } else {
-                log(t);
-                return -1;
             }
+            log(t);
+            return -1;
         }
     }
 
@@ -363,8 +359,8 @@
      */
     public void setJar(File jarfile) throws BuildException {
         if (getCommandLine().getClassname() != null || getCommandLine().getModule() != null) {
-            throw new BuildException("Cannot use 'jar' with 'classname' or 'module' "
-                                     + "attributes in same command.");
+            throw new BuildException(
+                "Cannot use 'jar' with 'classname' or 'module' attributes in same command.");
         }
         getCommandLine().setJar(jarfile.getAbsolutePath());
     }
@@ -378,8 +374,8 @@
      */
     public void setClassname(String s) throws BuildException {
         if (getCommandLine().getJar() != null) {
-            throw new BuildException("Cannot use 'jar' and 'classname' "
-                                     + "attributes in same command");
+            throw new BuildException(
+                "Cannot use 'jar' and 'classname' attributes in same command");
         }
         getCommandLine().setClassname(s);
     }
@@ -394,8 +390,8 @@
      */
     public void setModule(String module) throws BuildException {
         if (getCommandLine().getJar() != null) {
-            throw new BuildException("Cannot use 'jar' and 'module' "
-                                     + "attributes in same command");
+            throw new BuildException(
+                "Cannot use 'jar' and 'module' attributes in same command");
         }
         getCommandLine().setModule(module);
     }
@@ -409,8 +405,8 @@
      * @ant.attribute ignore="true"
      */
     public void setArgs(String s) {
-        log("The args attribute is deprecated. "
-            + "Please use nested arg elements.", Project.MSG_WARN);
+        log("The args attribute is deprecated. Please use nested arg elements.",
+            Project.MSG_WARN);
         getCommandLine().createArgument().setLine(s);
     }
 
@@ -477,8 +473,8 @@
      * @param s jvmargs.
      */
     public void setJvmargs(String s) {
-        log("The jvmargs attribute is deprecated. "
-            + "Please use nested jvmarg elements.", Project.MSG_WARN);
+        log("The jvmargs attribute is deprecated. Please use nested jvmarg elements.",
+            Project.MSG_WARN);
         getCommandLine().createVmArgument().setLine(s);
     }
 
@@ -559,8 +555,8 @@
      */
     public void setInput(File input) {
         if (inputString != null) {
-            throw new BuildException("The \"input\" and \"inputstring\" "
-                + "attributes cannot both be specified");
+            throw new BuildException(
+                "The \"input\" and \"inputstring\" attributes cannot both be specified");
         }
         this.input = input;
         incompatibleWithSpawn = true;
@@ -573,8 +569,8 @@
      */
     public void setInputString(String inputString) {
         if (input != null) {
-            throw new BuildException("The \"input\" and \"inputstring\" "
-                + "attributes cannot both be specified");
+            throw new BuildException(
+                "The \"input\" and \"inputstring\" attributes cannot both be specified");
         }
         this.inputString = inputString;
         incompatibleWithSpawn = true;
@@ -728,6 +724,7 @@
      *
      * @since Ant 1.5
      */
+    @Override
     protected void handleOutput(String output) {
         if (redirector.getOutputStream() != null) {
             redirector.handleOutput(output);
@@ -748,6 +745,7 @@
      * @exception IOException if the data cannot be read.
      * @since Ant 1.6
      */
+    @Override
     public int handleInput(byte[] buffer, int offset, int length)
         throws IOException {
         // Should work whether or not redirector.inputStream == null:
@@ -761,6 +759,7 @@
      *
      * @since Ant 1.5.2
      */
+    @Override
     protected void handleFlush(String output) {
         if (redirector.getOutputStream() != null) {
             redirector.handleFlush(output);
@@ -776,6 +775,7 @@
      *
      * @since Ant 1.5
      */
+    @Override
     protected void handleErrorOutput(String output) {
         if (redirector.getErrorStream() != null) {
             redirector.handleErrorOutput(output);
@@ -791,6 +791,7 @@
      *
      * @since Ant 1.5.2
      */
+    @Override
     protected void handleErrorFlush(String output) {
         if (redirector.getErrorStream() != null) {
             redirector.handleErrorFlush(output);
@@ -897,8 +898,8 @@
     private void setupEnvironment(Execute exe) {
         String[] environment = env.getVariables();
         if (environment != null) {
-            for (int i = 0; i < environment.length; i++) {
-                log("Setting environment variable: " + environment[i],
+            for (String element : environment) {
+                log("Setting environment variable: " + element,
                     Project.MSG_VERBOSE);
             }
         }
@@ -914,7 +915,7 @@
     private void setupWorkingDir(Execute exe) {
         if (dir == null) {
             dir = getProject().getBaseDir();
-        } else if (!dir.exists() || !dir.isDirectory()) {
+        } else if (!dir.isDirectory()) {
             throw new BuildException(dir.getAbsolutePath()
                                      + " is not a valid directory",
                                      getLocation());
@@ -962,10 +963,7 @@
     protected void run(String classname, Vector<String> args) throws BuildException {
         CommandlineJava cmdj = new CommandlineJava();
         cmdj.setClassname(classname);
-        final int size = args.size();
-        for (int i = 0; i < size; i++) {
-            cmdj.createArgument().setValue(args.elementAt(i));
-        }
+        args.forEach(arg -> cmdj.createArgument().setValue(arg));
         run(cmdj);
     }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/Javac.java b/src/main/org/apache/tools/ant/taskdefs/Javac.java
index 0237ab6..0302be6 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Javac.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Javac.java
@@ -19,16 +19,14 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
-import java.io.FileFilter;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.TreeMap;
 
 import org.apache.tools.ant.BuildException;
@@ -139,7 +137,7 @@
     protected boolean failOnError = true;
     protected boolean listFiles = false;
     protected File[] compileList = new File[0];
-    private Map<String, Long> packageInfos = new HashMap<String, Long>();
+    private Map<String, Long> packageInfos = new HashMap<>();
     // CheckStyle:VisibilityModifier ON
 
     private String source;
@@ -163,21 +161,26 @@
     private String assumedJavaVersion() {
         if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_4)) {
             return JAVAC14;
-        } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_5)) {
-            return JAVAC15;
-        } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_6)) {
-            return JAVAC16;
-        } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_7)) {
-            return JAVAC17;
-        } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_8)) {
-            return JAVAC18;
-        } else if (JavaEnvUtils.isAtLeastJavaVersion("10")) {
-            return JAVAC10_PLUS;
-        } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_9)) {
-            return JAVAC9;
-        } else {
-            return CLASSIC;
         }
+        if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_5)) {
+            return JAVAC15;
+        }
+        if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_6)) {
+            return JAVAC16;
+        }
+        if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_7)) {
+            return JAVAC17;
+        }
+        if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_8)) {
+            return JAVAC18;
+        }
+        if (JavaEnvUtils.isAtLeastJavaVersion("10")) {
+            return JAVAC10_PLUS;
+        }
+        if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_9)) {
+            return JAVAC9;
+        }
+        return CLASSIC;
     }
 
     /**
@@ -1091,8 +1094,8 @@
      */
     public void add(final CompilerAdapter adapter) {
         if (nestedAdapter != null) {
-            throw new BuildException("Can't have more than one compiler"
-                                     + " adapter");
+            throw new BuildException(
+                "Can't have more than one compiler adapter");
         }
         nestedAdapter = adapter;
     }
@@ -1140,7 +1143,7 @@
      */
     protected void resetFileLists() {
         compileList = new File[0];
-        packageInfos = new HashMap<String, Long>();
+        packageInfos = new HashMap<>();
     }
 
     /**
@@ -1155,8 +1158,8 @@
         final GlobPatternMapper m = new GlobPatternMapper();
         final String[] extensions = findSupportedFileExtensions();
 
-        for (int i = 0; i < extensions.length; i++) {
-            m.setFrom(extensions[i]);
+        for (String extension : extensions) {
+            m.setFrom(extension);
             m.setTo("*.class");
             final SourceFileScanner sfs = new SourceFileScanner(this);
             final File[] newFiles = sfs.restrictAsFiles(files, srcDir, destDir, m);
@@ -1195,7 +1198,8 @@
         final FileUtils fu = FileUtils.getFileUtils();
         for (String pathElement : moduleSourcepath.list()) {
             boolean valid = false;
-            for (Map.Entry<String,Collection<File>> modules : resolveModuleSourcePathElement(getProject().getBaseDir(), pathElement).entrySet()) {
+            for (Map.Entry<String, Collection<File>> modules : resolveModuleSourcePathElement(
+                getProject().getBaseDir(), pathElement).entrySet()) {
                 final String moduleName = modules.getKey();
                 for (File srcDir : modules.getValue()) {
                     if (srcDir.exists()) {
@@ -1307,8 +1311,8 @@
             if (isJdkCompiler(compilerImpl)) {
                 compilerImpl = EXTJAVAC;
             } else {
-                log("Since compiler setting isn't classic or modern, "
-                    + "ignoring fork setting.", Project.MSG_WARN);
+                log("Since compiler setting isn't classic or modern, ignoring fork setting.",
+                    Project.MSG_WARN);
             }
         }
         return compilerImpl;
@@ -1363,13 +1367,12 @@
         if (destDir != null && !destDir.isDirectory()) {
             throw new BuildException("destination directory \""
                                      + destDir
-                                     + "\" does not exist "
-                                     + "or is not a directory", getLocation());
+                                     + "\" does not exist or is not a directory", getLocation());
         }
         if (includeAntRuntime == null && getProject().getProperty("build.sysclasspath") == null) {
-            log(getLocation() + "warning: 'includeantruntime' was not set, " +
-                    "defaulting to build.sysclasspath=last; set to false for repeatable builds",
-                    Project.MSG_WARN);
+            log(getLocation()
+                + "warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds",
+                Project.MSG_WARN);
         }
     }
 
@@ -1387,9 +1390,8 @@
                 + (destDir != null ? " to " + destDir : ""));
 
             if (listFiles) {
-                for (int i = 0; i < compileList.length; i++) {
-                  final String filename = compileList[i].getAbsolutePath();
-                  log(filename);
+                for (File element : compileList) {
+                  log(element.getAbsolutePath());
                 }
             }
 
@@ -1424,9 +1426,8 @@
                 }
                 if (failOnError) {
                     throw new BuildException(FAIL_MSG, getLocation());
-                } else {
-                    log(FAIL_MSG, Project.MSG_ERR);
                 }
+                log(FAIL_MSG, Project.MSG_ERR);
             }
         }
     }
@@ -1448,9 +1449,8 @@
     }
 
     private void lookForPackageInfos(final File srcDir, final File[] newFiles) {
-        for (int i = 0; i < newFiles.length; i++) {
-            final File f = newFiles[i];
-            if (!f.getName().equals("package-info.java")) {
+        for (File f : newFiles) {
+            if (!"package-info.java".equals(f.getName())) {
                 continue;
             }
             final String path = FILE_UTILS.removeLeadingPath(srcDir, f).
@@ -1461,7 +1461,7 @@
                 continue;
             }
             final String pkg = path.substring(0, path.length() - suffix.length());
-            packageInfos.put(pkg, new Long(f.lastModified()));
+            packageInfos.put(pkg, Long.valueOf(f.lastModified()));
         }
     }
 
@@ -1471,7 +1471,7 @@
      * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=43114">Bug #43114</a>
      */
     private void generateMissingPackageInfoClasses(final File dest) throws IOException {
-        for (final Entry<String, Long> entry : packageInfos.entrySet()) {
+        for (final Map.Entry<String, Long> entry : packageInfos.entrySet()) {
             final String pkg = entry.getKey();
             final Long sourceLastMod = entry.getValue();
             final File pkgBinDir = new File(dest, pkg.replace('/', File.separatorChar));
@@ -1481,8 +1481,7 @@
                 continue;
             }
             log("Creating empty " + pkgInfoClass);
-            final OutputStream os = new FileOutputStream(pkgInfoClass);
-            try {
+            try (OutputStream os = Files.newOutputStream(pkgInfoClass.toPath())) {
                 os.write(PACKAGE_INFO_CLASS_HEADER);
                 final byte[] name = pkg.getBytes("UTF-8");
                 final int length = name.length + /* "/package-info" */ 13;
@@ -1490,8 +1489,6 @@
                 os.write((byte) length % 256);
                 os.write(name);
                 os.write(PACKAGE_INFO_CLASS_FOOTER);
-            } finally {
-                os.close();
             }
         }
     }
@@ -1503,7 +1500,7 @@
      * @since 1.9.7
      */
     private static boolean hasPath(final Path path) {
-        return path != null && path.size() > 0;
+        return path != null && !path.isEmpty();
     }
 
     /**
@@ -1537,7 +1534,7 @@
      */
     private static Collection<? extends CharSequence> expandGroups(
             final CharSequence element) {
-        List<StringBuilder> result = new ArrayList<StringBuilder>();
+        List<StringBuilder> result = new ArrayList<>();
         result.add(new StringBuilder());
         StringBuilder resolved = new StringBuilder();
         for (int i = 0; i < element.length(); i++) {
@@ -1560,7 +1557,7 @@
                             break;
                         default:
                             final List<StringBuilder> oldRes = result;
-                            result = new ArrayList<StringBuilder>(oldRes.size() * parts.size());
+                            result = new ArrayList<>(oldRes.size() * parts.size());
                             for (CharSequence part : parts) {
                                 for (CharSequence prefix : oldRes) {
                                     result.add(new StringBuilder(prefix).append(resolved).append(part));
@@ -1587,7 +1584,7 @@
      * @since 1.9.7
      */
     private static Collection<? extends CharSequence> resolveGroup(final CharSequence group) {
-        final Collection<CharSequence> result = new ArrayList<CharSequence>();
+        final Collection<CharSequence> result = new ArrayList<>();
         int start = 0;
         int depth = 0;
         for (int i = 0; i < group.length(); i++) {
@@ -1656,25 +1653,25 @@
         final int startIndex = pattern.indexOf(MODULE_MARKER);
         if (startIndex == -1) {
             findModules(root, pattern, null, collector);
-        } else {
-            if (startIndex == 0) {
-                throw new BuildException("The modulesourcepath entry must be a folder.");
-            }
-            final int endIndex = startIndex + MODULE_MARKER.length();
-            if (pattern.charAt(startIndex - 1) != File.separatorChar) {
-                    throw new BuildException("The module mark must be preceded by separator");
-            }
-            if (endIndex < pattern.length() && pattern.charAt(endIndex) != File.separatorChar) {
-                throw new BuildException("The module mark must be followed by separator");
-            }
-            if (pattern.indexOf(MODULE_MARKER, endIndex) != -1) {
-                throw new BuildException("The modulesourcepath entry must contain at most one module mark");
-            }
-            final String pathToModule = pattern.substring(0, startIndex);
-            final String pathInModule = endIndex == pattern.length()
-                    ? null : pattern.substring(endIndex + 1);  //+1 the separator
-            findModules(root, pathToModule, pathInModule, collector);
+            return;
         }
+        if (startIndex == 0) {
+            throw new BuildException("The modulesourcepath entry must be a folder.");
+        }
+        final int endIndex = startIndex + MODULE_MARKER.length();
+        if (pattern.charAt(startIndex - 1) != File.separatorChar) {
+                throw new BuildException("The module mark must be preceded by separator");
+        }
+        if (endIndex < pattern.length() && pattern.charAt(endIndex) != File.separatorChar) {
+            throw new BuildException("The module mark must be followed by separator");
+        }
+        if (pattern.indexOf(MODULE_MARKER, endIndex) != -1) {
+            throw new BuildException("The modulesourcepath entry must contain at most one module mark");
+        }
+        final String pathToModule = pattern.substring(0, startIndex);
+        final String pathInModule = endIndex == pattern.length()
+                ? null : pattern.substring(endIndex + 1);  //+1 the separator
+        findModules(root, pathToModule, pathInModule, collector);
     }
 
     /**
@@ -1695,19 +1692,14 @@
         if (!f.isDirectory()) {
             return;
         }
-        final File[] modules = f.listFiles(new FileFilter() {
-            public boolean accept(File pathname) {
-                return pathname.isDirectory();
-            }
-        });
-        for (File module : modules) {
+        for (File module : f.listFiles(File::isDirectory)) {
             final String moduleName = module.getName();
             final File moduleSourceRoot = pathInModule == null ?
                     module :
                     new File(module, pathInModule);
             Collection<File> moduleRoots = collector.get(moduleName);
             if (moduleRoots == null) {
-                moduleRoots = new ArrayList<File>();
+                moduleRoots = new ArrayList<>();
                 collector.put(moduleName, moduleRoots);
             }
             moduleRoots.add(moduleSourceRoot);
diff --git a/src/main/org/apache/tools/ant/taskdefs/Javadoc.java b/src/main/org/apache/tools/ant/taskdefs/Javadoc.java
index 931449f..b087c4c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Javadoc.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Javadoc.java
@@ -20,25 +20,27 @@
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.FileWriter;
-import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.nio.file.Files;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Locale;
+import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.Vector;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.DirectoryScanner;
@@ -225,7 +227,7 @@
     public class DocletInfo extends ExtensionInfo {
 
         /** Collection of doclet parameters. */
-        private final Vector<DocletParam> params = new Vector<DocletParam>();
+        private final List<DocletParam> params = new Vector<>();
 
         /**
          * Create a doclet parameter to be configured by Ant.
@@ -234,8 +236,7 @@
          */
         public DocletParam createParam() {
             final DocletParam param = new DocletParam();
-            params.addElement(param);
-
+            params.add(param);
             return param;
         }
 
@@ -245,7 +246,7 @@
          * @return an Enumeration of DocletParam instances.
          */
         public Enumeration<DocletParam> getParams() {
-            return params.elements();
+            return Collections.enumeration(params);
         }
     }
 
@@ -378,8 +379,11 @@
      * contains special handling for FileSets that has to occur at
      * task runtime.</p>
      */
-    public class ResourceCollectionContainer {
-        private final ArrayList<ResourceCollection> rcs = new ArrayList<ResourceCollection>();
+    public class ResourceCollectionContainer
+        implements Iterable<ResourceCollection> {
+
+        private final List<ResourceCollection> rcs = new ArrayList<>();
+
         /**
          * Add a resource collection to the container.
          * @param rc the collection to add.
@@ -392,7 +396,8 @@
          * Get an iterator on the collection.
          * @return an iterator.
          */
-        private Iterator<ResourceCollection> iterator() {
+        @Override
+        public Iterator<ResourceCollection> iterator() {
             return rcs.iterator();
         }
     }
@@ -422,12 +427,12 @@
      * @param value the argument value.
      */
     private void addArgIfNotEmpty(final String key, final String value) {
-        if (value != null && value.length() != 0) {
-            cmd.createArgument().setValue(key);
-            cmd.createArgument().setValue(value);
-        } else {
+        if (value == null || value.isEmpty()) {
             log("Warning: Leaving out empty argument '" + key + "'",
                 Project.MSG_WARN);
+        } else {
+            cmd.createArgument().setValue(key);
+            cmd.createArgument().setValue(value);
         }
     }
 
@@ -443,9 +448,9 @@
     private boolean failOnWarning = false;
     private Path sourcePath = null;
     private File destDir = null;
-    private final Vector<SourceFile> sourceFiles = new Vector<SourceFile>();
-    private final Vector<PackageName> packageNames = new Vector<PackageName>();
-    private final Vector<PackageName> excludePackageNames = new Vector<PackageName>(1);
+    private final List<SourceFile> sourceFiles = new Vector<>();
+    private final List<PackageName> packageNames = new Vector<>();
+    private final List<PackageName> excludePackageNames = new Vector<>(1);
     private boolean author = true;
     private boolean version = true;
     private DocletInfo doclet = null;
@@ -453,9 +458,9 @@
     private Path bootclasspath = null;
     private String group = null;
     private String packageList = null;
-    private final Vector<LinkArgument> links = new Vector<LinkArgument>();
-    private final Vector<GroupArgument> groups = new Vector<GroupArgument>();
-    private final Vector<Object> tags = new Vector<Object>();
+    private final List<LinkArgument> links = new Vector<>();
+    private final List<GroupArgument> groups = new Vector<>();
+    private final List<Object> tags = new Vector<>();
     private boolean useDefaultExcludes = true;
     private Html doctitle = null;
     private Html header = null;
@@ -475,7 +480,7 @@
 
     private final ResourceCollectionContainer nestedSourceFiles
         = new ResourceCollectionContainer();
-    private final Vector<DirSet> packageSets = new Vector<DirSet>();
+    private final List<DirSet> packageSets = new Vector<>();
 
     /**
      * Work around command line length limit by using an external file
@@ -593,7 +598,7 @@
      * @param sf the source file to be processed.
      */
     public void addSource(final SourceFile sf) {
-        sourceFiles.addElement(sf);
+        sourceFiles.add(sf);
     }
 
     /**
@@ -623,7 +628,7 @@
      * @param pn the package name, possibly wildcarded.
      */
     public void addPackage(final PackageName pn) {
-        packageNames.addElement(pn);
+        packageNames.add(pn);
     }
 
     /**
@@ -648,7 +653,7 @@
      * @param pn the name of the package (wildcards are not permitted).
      */
     public void addExcludePackage(final PackageName pn) {
-        excludePackageNames.addElement(pn);
+        excludePackageNames.add(pn);
     }
 
     /**
@@ -772,7 +777,7 @@
      * @param tagletInfo information about the taglet.
      */
     public void addTaglet(final ExtensionInfo tagletInfo) {
-        tags.addElement(tagletInfo);
+        tags.add(tagletInfo);
     }
 
     /**
@@ -1191,7 +1196,7 @@
      */
     public LinkArgument createLink() {
         final LinkArgument la = new LinkArgument();
-        links.addElement(la);
+        links.add(la);
         return la;
     }
 
@@ -1304,7 +1309,7 @@
      */
     public TagArgument createTag() {
         final TagArgument ta = new TagArgument();
-        tags.addElement (ta);
+        tags.add(ta);
         return ta;
     }
 
@@ -1377,48 +1382,47 @@
             final StringTokenizer tok = new StringTokenizer(verboseScope, ",");
             while (tok.hasMoreTokens()) {
                 final String next = tok.nextToken().trim();
-                if (next.equals("all")) {
+                if ("all".equals(next)) {
                     if (gotAll) {
-                        getProject().log ("Repeated tag scope element: all",
+                        getProject().log("Repeated tag scope element: all",
                                           Project.MSG_VERBOSE);
                     }
                     gotAll = true;
                 } else {
                     int i;
                     for (i = 0; i < SCOPE_ELEMENTS.length; i++) {
-                        if (next.equals (SCOPE_ELEMENTS[i])) {
+                        if (SCOPE_ELEMENTS[i].equals(next)) {
                             break;
                         }
                     }
                     if (i == SCOPE_ELEMENTS.length) {
-                        throw new BuildException ("Unrecognised scope element: "
-                                                  + next);
-                    } else {
-                        if (elements[i]) {
-                            getProject().log ("Repeated tag scope element: "
-                                              + next, Project.MSG_VERBOSE);
-                        }
-                        elements[i] = true;
-                        gotNotAll = true;
+                        throw new BuildException(
+                            "Unrecognised scope element: %s", next);
                     }
+                    if (elements[i]) {
+                        getProject().log("Repeated tag scope element: " + next,
+                            Project.MSG_VERBOSE);
+                    }
+                    elements[i] = true;
+                    gotNotAll = true;
                 }
             }
 
             if (gotNotAll && gotAll) {
-                throw new BuildException ("Mixture of \"all\" and other scope "
-                                          + "elements in tag parameter.");
+                throw new BuildException(
+                    "Mixture of \"all\" and other scope elements in tag parameter.");
             }
             if (!gotNotAll && !gotAll) {
-                throw new BuildException ("No scope elements specified in tag "
-                                          + "parameter.");
+                throw new BuildException(
+                    "No scope elements specified in tag parameter.");
             }
             if (gotAll) {
                 this.scope = "a";
             } else {
-                final StringBuffer buff = new StringBuffer (elements.length);
+                final StringBuilder buff = new StringBuilder(elements.length);
                 for (int i = 0; i < elements.length; i++) {
                     if (elements[i]) {
-                        buff.append (SCOPE_ELEMENTS[i].charAt(0));
+                        buff.append(SCOPE_ELEMENTS[i].charAt(0));
                     }
                 }
                 this.scope = buff.toString();
@@ -1441,17 +1445,17 @@
          *                           is <code>null</code> or empty.
          */
         public String getParameter() throws BuildException {
-            if (name == null || name.equals("")) {
-                throw new BuildException ("No name specified for custom tag.");
+            if (name == null || name.isEmpty()) {
+                throw new BuildException("No name specified for custom tag.");
             }
             if (getDescription() != null) {
                 return name + ":" + (enabled ? "" : "X")
                     + scope + ":" + getDescription();
-            } else if (!enabled || !"a".equals(scope)) {
-                return name + ":" + (enabled ? "" : "X") + scope;
-            } else {
-                return name;
             }
+            if (!enabled || !"a".equals(scope)) {
+                return name + ":" + (enabled ? "" : "X") + scope;
+            }
+            return name;
         }
     }
 
@@ -1462,22 +1466,16 @@
      */
     public GroupArgument createGroup() {
         final GroupArgument ga = new GroupArgument();
-        groups.addElement(ga);
+        groups.add(ga);
         return ga;
     }
 
-
     /**
      * A class corresponding to the group nested element.
      */
     public class GroupArgument {
         private Html title;
-        private final Vector<PackageName> packages = new Vector<PackageName>();
-
-        /** Constructor for GroupArgument */
-        public GroupArgument() {
-            //empty
-        }
+        private final List<PackageName> packages = new Vector<>();
 
         /**
          * Set the title attribute using a string.
@@ -1488,6 +1486,7 @@
             h.addText(src);
             addTitle(h);
         }
+
         /**
          * Set the title attribute using a nested Html value.
          * @param text a <code>Html</code> value
@@ -1517,12 +1516,13 @@
                 addPackage(pn);
             }
         }
+
         /**
          * Add a package nested element.
          * @param pn a nested element specifying the package.
          */
         public void addPackage(final PackageName pn) {
-            packages.addElement(pn);
+            packages.add(pn);
         }
 
         /**
@@ -1530,15 +1530,8 @@
          * @return the packages as a string
          */
         public String getPackages() {
-            final StringBuffer p = new StringBuffer();
-            final int size = packages.size();
-            for (int i = 0; i < size; i++) {
-                if (i > 0) {
-                    p.append(":");
-                }
-                p.append(packages.elementAt(i).toString());
-            }
-            return p.toString();
+            return packages.stream().map(Object::toString)
+                .collect(Collectors.joining(":"));
         }
     }
 
@@ -1602,7 +1595,7 @@
      * @since 1.5
      */
     public void addPackageset(final DirSet packageSet) {
-        packageSets.addElement(packageSet);
+        packageSets.add(packageSet);
     }
 
     /**
@@ -1709,7 +1702,7 @@
     public void execute() throws BuildException {
         checkTaskName();
 
-        final Vector<String> packagesToDoc = new Vector<String>();
+        final List<String> packagesToDoc = new Vector<>();
         final Path sourceDirs = new Path(getProject());
 
         checkPackageAndSourcePath();
@@ -1721,15 +1714,14 @@
         parsePackages(packagesToDoc, sourceDirs);
         checkPackages(packagesToDoc, sourceDirs);
 
-        @SuppressWarnings("unchecked")
-        final Vector<SourceFile> sourceFilesToDoc = (Vector<SourceFile>) sourceFiles.clone();
+        final List<SourceFile> sourceFilesToDoc = new ArrayList<>(sourceFiles);
         addSourceFiles(sourceFilesToDoc);
 
         checkPackagesToDoc(packagesToDoc, sourceFilesToDoc);
 
         log("Generating Javadoc", Project.MSG_INFO);
 
-        final Commandline toExecute = (Commandline) cmd.clone();
+        final Commandline toExecute = cmd.clone();
         if (executable != null) {
             toExecute.setExecutable(executable);
         } else {
@@ -1850,25 +1842,24 @@
         }
     }
 
-    private void checkPackages(final Vector<String> packagesToDoc, final Path sourceDirs) {
-        if (packagesToDoc.size() != 0 && sourceDirs.size() == 0) {
-            final String msg = "sourcePath attribute must be set when "
-                + "specifying package names.";
-            throw new BuildException(msg);
+    private void checkPackages(final List<String> packagesToDoc, final Path sourceDirs) {
+        if (!packagesToDoc.isEmpty() && sourceDirs.isEmpty()) {
+            throw new BuildException(
+                "sourcePath attribute must be set when specifying package names.");
         }
     }
 
     private void checkPackagesToDoc(
-        final Vector<String> packagesToDoc, final Vector<SourceFile> sourceFilesToDoc) {
-        if (packageList == null && packagesToDoc.size() == 0
-            && sourceFilesToDoc.size() == 0) {
-            throw new BuildException("No source files and no packages have "
-                                     + "been specified.");
+        final List<String> packagesToDoc, final List<SourceFile> sourceFilesToDoc) {
+        if (packageList == null && packagesToDoc.isEmpty()
+            && sourceFilesToDoc.isEmpty()) {
+            throw new BuildException(
+                "No source files and no packages have been specified.");
         }
     }
 
     private void doSourcePath(final Commandline toExecute, final Path sourceDirs) {
-        if (sourceDirs.size() > 0) {
+        if (!sourceDirs.isEmpty()) {
             toExecute.createArgument().setValue("-sourcepath");
             toExecute.createArgument().setPath(sourceDirs);
         }
@@ -1893,7 +1884,7 @@
         }
 
         if (classpath == null) {
-            classpath = (new Path(getProject())).concatSystemClasspath("last");
+            classpath = new Path(getProject()).concatSystemClasspath("last");
         } else {
             classpath = classpath.concatSystemClasspath("ignore");
         }
@@ -1918,32 +1909,31 @@
     private void doDoclet(final Commandline toExecute) {
         if (doclet != null) {
             if (doclet.getName() == null) {
-                throw new BuildException("The doclet name must be "
-                                         + "specified.", getLocation());
-            } else {
-                toExecute.createArgument().setValue("-doclet");
-                toExecute.createArgument().setValue(doclet.getName());
-                if (doclet.getPath() != null) {
-                    final Path docletPath
-                        = doclet.getPath().concatSystemClasspath("ignore");
-                    if (docletPath.size() != 0) {
-                        toExecute.createArgument().setValue("-docletpath");
-                        toExecute.createArgument().setPath(docletPath);
-                    }
+                throw new BuildException("The doclet name must be specified.",
+                    getLocation());
+            }
+            toExecute.createArgument().setValue("-doclet");
+            toExecute.createArgument().setValue(doclet.getName());
+            if (doclet.getPath() != null) {
+                final Path docletPath
+                    = doclet.getPath().concatSystemClasspath("ignore");
+                if (docletPath.size() != 0) {
+                    toExecute.createArgument().setValue("-docletpath");
+                    toExecute.createArgument().setPath(docletPath);
                 }
-                for (final Enumeration<DocletParam> e = doclet.getParams();
-                     e.hasMoreElements();) {
-                    final DocletParam param = e.nextElement();
-                    if (param.getName() == null) {
-                        throw new BuildException("Doclet parameters must "
-                                                 + "have a name");
-                    }
+            }
+            for (final Enumeration<DocletParam> e = doclet.getParams();
+                 e.hasMoreElements();) {
+                final DocletParam param = e.nextElement();
+                if (param.getName() == null) {
+                    throw new BuildException(
+                        "Doclet parameters must have a name");
+                }
 
-                    toExecute.createArgument().setValue(param.getName());
-                    if (param.getValue() != null) {
-                        toExecute.createArgument()
-                            .setValue(param.getValue());
-                    }
+                toExecute.createArgument().setValue(param.getName());
+                if (param.getValue() != null) {
+                    toExecute.createArgument()
+                        .setValue(param.getValue());
                 }
             }
         }
@@ -1952,7 +1942,6 @@
     private void writeExternalArgs(final Commandline toExecute) {
         // If using an external file, write the command line options to it
         File optionsTmpFile = null;
-        BufferedWriter optionsListWriter = null;
         try {
             optionsTmpFile = FILE_UTILS.createTempFile(
                 "javadocOptions", "", null, true, true);
@@ -1960,23 +1949,20 @@
             toExecute.clearArgs();
             toExecute.createArgument().setValue(
                 "@" + optionsTmpFile.getAbsolutePath());
-            optionsListWriter = new BufferedWriter(
-                new FileWriter(optionsTmpFile.getAbsolutePath(), true));
-            for (int i = 0; i < listOpt.length; i++) {
-                final String string = listOpt[i];
-                if (string.startsWith("-J-")) {
-                    toExecute.createArgument().setValue(string);
-                } else  {
-                    if (string.startsWith("-")) {
-                        optionsListWriter.write(string);
+            try (BufferedWriter optionsListWriter = new BufferedWriter(
+                new FileWriter(optionsTmpFile.getAbsolutePath(), true))) {
+                for (final String opt : listOpt) {
+                    if (opt.startsWith("-J-")) {
+                        toExecute.createArgument().setValue(opt);
+                    } else if (opt.startsWith("-")) {
+                        optionsListWriter.write(opt);
                         optionsListWriter.write(" ");
                     } else {
-                        optionsListWriter.write(quoteString(string));
+                        optionsListWriter.write(quoteString(opt));
                         optionsListWriter.newLine();
                     }
                 }
             }
-            optionsListWriter.close();
         } catch (final IOException ex) {
             if (optionsTmpFile != null) {
                 optionsTmpFile.delete();
@@ -1984,8 +1970,6 @@
             throw new BuildException(
                 "Error creating or writing temporary file for javadoc options",
                 ex, getLocation());
-        } finally {
-            FileUtils.close(optionsListWriter);
         }
     }
 
@@ -2002,85 +1986,78 @@
     }
 
     private void doLinks(final Commandline toExecute) {
-        if (links.size() != 0) {
-            for (final Enumeration<LinkArgument> e = links.elements(); e.hasMoreElements();) {
-                final LinkArgument la = e.nextElement();
-
-                if (la.getHref() == null || la.getHref().length() == 0) {
-                    log("No href was given for the link - skipping",
-                        Project.MSG_VERBOSE);
+        for (final LinkArgument la : links) {
+            if (la.getHref() == null || la.getHref().isEmpty()) {
+                log("No href was given for the link - skipping",
+                    Project.MSG_VERBOSE);
+                continue;
+            }
+            String link = null;
+            if (la.shouldResolveLink()) {
+                final File hrefAsFile =
+                    getProject().resolveFile(la.getHref());
+                if (hrefAsFile.exists()) {
+                    try {
+                        link = FILE_UTILS.getFileURL(hrefAsFile)
+                            .toExternalForm();
+                    } catch (final MalformedURLException ex) {
+                        // should be impossible
+                        log("Warning: link location was invalid "
+                            + hrefAsFile, Project.MSG_WARN);
+                    }
+                }
+            }
+            if (link == null) {
+                // is the href a valid URL
+                try {
+                    final URL base = new URL("file://.");
+                    // created for the side effect of throwing a MalformedURLException
+                    new URL(base, la.getHref()); //NOSONAR
+                    link = la.getHref();
+                } catch (final MalformedURLException mue) {
+                    // ok - just skip
+                    log("Link href \"" + la.getHref()
+                        + "\" is not a valid url - skipping link",
+                        Project.MSG_WARN);
                     continue;
                 }
-                String link = null;
-                if (la.shouldResolveLink()) {
-                    final File hrefAsFile =
-                        getProject().resolveFile(la.getHref());
-                    if (hrefAsFile.exists()) {
-                        try {
-                            link = FILE_UTILS.getFileURL(hrefAsFile)
-                                .toExternalForm();
-                        } catch (final MalformedURLException ex) {
-                            // should be impossible
-                            log("Warning: link location was invalid "
-                                + hrefAsFile, Project.MSG_WARN);
-                        }
-                    }
-                }
-                if (link == null) {
-                    // is the href a valid URL
-                    try {
-                        final URL base = new URL("file://.");
-                        // created for the side effect of throwing a MalformedURLException
-                        new URL(base, la.getHref()); //NOSONAR
-                        link = la.getHref();
-                    } catch (final MalformedURLException mue) {
-                        // ok - just skip
-                        log("Link href \"" + la.getHref()
-                            + "\" is not a valid url - skipping link",
-                            Project.MSG_WARN);
-                        continue;
-                    }
-                }
+            }
 
-                if (la.isLinkOffline()) {
-                    final File packageListLocation = la.getPackagelistLoc();
-                    URL packageListURL = la.getPackagelistURL();
-                    if (packageListLocation == null
-                        && packageListURL == null) {
-                        throw new BuildException("The package list"
-                                                 + " location for link "
-                                                 + la.getHref()
-                                                 + " must be provided "
-                                                 + "because the link is "
-                                                 + "offline");
-                    }
-                    if (packageListLocation != null) {
-                        final File packageListFile =
-                            new File(packageListLocation, "package-list");
-                        if (packageListFile.exists()) {
-                            try {
-                                packageListURL =
-                                    FILE_UTILS.getFileURL(packageListLocation);
-                            } catch (final MalformedURLException ex) {
-                                log("Warning: Package list location was "
-                                    + "invalid " + packageListLocation,
-                                    Project.MSG_WARN);
-                            }
-                        } else {
-                            log("Warning: No package list was found at "
-                                + packageListLocation, Project.MSG_VERBOSE);
-                        }
-                    }
-                    if (packageListURL != null) {
-                        toExecute.createArgument().setValue("-linkoffline");
-                        toExecute.createArgument().setValue(link);
-                        toExecute.createArgument()
-                            .setValue(packageListURL.toExternalForm());
-                    }
-                } else {
-                    toExecute.createArgument().setValue("-link");
-                    toExecute.createArgument().setValue(link);
+            if (la.isLinkOffline()) {
+                final File packageListLocation = la.getPackagelistLoc();
+                URL packageListURL = la.getPackagelistURL();
+                if (packageListLocation == null
+                    && packageListURL == null) {
+                    throw new BuildException(
+                        "The package list location for link " + la.getHref()
+                            + " must be provided because the link is offline");
                 }
+                if (packageListLocation != null) {
+                    final File packageListFile =
+                        new File(packageListLocation, "package-list");
+                    if (packageListFile.exists()) {
+                        try {
+                            packageListURL =
+                                FILE_UTILS.getFileURL(packageListLocation);
+                        } catch (final MalformedURLException ex) {
+                            log("Warning: Package list location was "
+                                + "invalid " + packageListLocation,
+                                Project.MSG_WARN);
+                        }
+                    } else {
+                        log("Warning: No package list was found at "
+                            + packageListLocation, Project.MSG_VERBOSE);
+                    }
+                }
+                if (packageListURL != null) {
+                    toExecute.createArgument().setValue("-linkoffline");
+                    toExecute.createArgument().setValue(link);
+                    toExecute.createArgument()
+                        .setValue(packageListURL.toExternalForm());
+                }
+            } else {
+                toExecute.createArgument().setValue("-link");
+                toExecute.createArgument().setValue(link);
             }
         }
     }
@@ -2102,7 +2079,7 @@
             final StringTokenizer tok = new StringTokenizer(group, ",", false);
             while (tok.hasMoreTokens()) {
                 final String grp = tok.nextToken().trim();
-                final int space = grp.indexOf(" ");
+                final int space = grp.indexOf(' ');
                 if (space > 0) {
                     final String name = grp.substring(0, space);
                     final String pkgList = grp.substring(space + 1);
@@ -2116,36 +2093,30 @@
 
     // add the group arguments
     private void doGroups(final Commandline toExecute) {
-        if (groups.size() != 0) {
-            for (final Enumeration<GroupArgument> e = groups.elements(); e.hasMoreElements();) {
-                final GroupArgument ga = e.nextElement();
-                final String title = ga.getTitle();
-                final String packages = ga.getPackages();
-                if (title == null || packages == null) {
-                    throw new BuildException("The title and packages must "
-                                             + "be specified for group "
-                                             + "elements.");
-                }
-                toExecute.createArgument().setValue("-group");
-                toExecute.createArgument().setValue(expand(title));
-                toExecute.createArgument().setValue(packages);
+        for (final GroupArgument ga : groups) {
+            final String title = ga.getTitle();
+            final String packages = ga.getPackages();
+            if (title == null || packages == null) {
+                throw new BuildException(
+                    "The title and packages must be specified for group elements.");
             }
+            toExecute.createArgument().setValue("-group");
+            toExecute.createArgument().setValue(expand(title));
+            toExecute.createArgument().setValue(packages);
         }
     }
 
     // Do java1.4 arguments
     private void doJava14(final Commandline toExecute) {
-        for (final Enumeration<Object> e = tags.elements(); e.hasMoreElements();) {
-            final Object element = e.nextElement();
+        for (final Object element : tags) {
             if (element instanceof TagArgument) {
                 final TagArgument ta = (TagArgument) element;
                 final File tagDir = ta.getDir(getProject());
                 if (tagDir == null) {
                     // The tag element is not used as a fileset,
                     // but specifies the tag directly.
-                    toExecute.createArgument().setValue ("-tag");
-                    toExecute.createArgument()
-                        .setValue (ta.getParameter());
+                    toExecute.createArgument().setValue("-tag");
+                    toExecute.createArgument().setValue(ta.getParameter());
                 } else {
                     // The tag element is used as a
                     // fileset. Parse all the files and create
@@ -2153,26 +2124,22 @@
                     final DirectoryScanner tagDefScanner =
                         ta.getDirectoryScanner(getProject());
                     final String[] files = tagDefScanner.getIncludedFiles();
-                    for (int i = 0; i < files.length; i++) {
-                        final File tagDefFile = new File(tagDir, files[i]);
-                        try {
-                            final BufferedReader in
-                                = new BufferedReader(
-                                    new FileReader(tagDefFile)
-                                                     );
-                            String line = null;
+                    for (String file : files) {
+                        final File tagDefFile = new File(tagDir, file);
+                        try (final BufferedReader in =
+                            new BufferedReader(new FileReader(tagDefFile))) {
+                            String line;
                             while ((line = in.readLine()) != null) {
                                 toExecute.createArgument()
                                     .setValue("-tag");
                                 toExecute.createArgument()
                                     .setValue(line);
                             }
-                            in.close();
                         } catch (final IOException ioe) {
                             throw new BuildException(
-                                "Couldn't read "
-                                + " tag file from "
-                                + tagDefFile.getAbsolutePath(), ioe);
+                                "Couldn't read tag file from "
+                                    + tagDefFile.getAbsolutePath(),
+                                ioe);
                         }
                     }
                 }
@@ -2184,7 +2151,7 @@
                 if (tagletInfo.getPath() != null) {
                     final Path tagletPath = tagletInfo.getPath()
                         .concatSystemClasspath("ignore");
-                    if (tagletPath.size() != 0) {
+                    if (!tagletPath.isEmpty()) {
                         toExecute.createArgument()
                             .setValue("-tagletpath");
                         toExecute.createArgument().setPath(tagletPath);
@@ -2212,8 +2179,8 @@
     private void doDocFilesSubDirs(final Commandline toExecute) {
         if (docFilesSubDirs) {
             toExecute.createArgument().setValue("-docfilessubdirs");
-            if (excludeDocFilesSubDir != null
-                && excludeDocFilesSubDir.trim().length() > 0) {
+            if (!(excludeDocFilesSubDir == null
+                || excludeDocFilesSubDir.trim().isEmpty())) {
                 toExecute.createArgument().setValue("-excludedocfilessubdir");
                 toExecute.createArgument().setValue(excludeDocFilesSubDir);
             }
@@ -2222,10 +2189,10 @@
 
     private void doSourceAndPackageNames(
         final Commandline toExecute,
-        final Vector<String> packagesToDoc,
-        final Vector<SourceFile> sourceFilesToDoc,
+        final List<String> packagesToDoc,
+        final List<SourceFile> sourceFilesToDoc,
         final boolean useExternalFile,
-        final File    tmpList,
+        final File tmpList,
         final BufferedWriter srcListWriter)
         throws IOException {
         for (final String packageName : packagesToDoc) {
@@ -2242,7 +2209,7 @@
             if (useExternalFile) {
                 // TODO what is the following doing?
                 //     should it run if !javadoc4 && executable != null?
-                if (sourceFileName.indexOf(" ") > -1) {
+                if (sourceFileName.indexOf(' ') > -1) {
                     String name = sourceFileName;
                     if (File.separatorChar == '\\') {
                         name = sourceFileName.replace(File.separatorChar, '/');
@@ -2272,9 +2239,8 @@
         }
         if (str.indexOf('\'') == -1) {
             return quoteString(str, '\'');
-        } else {
-            return quoteString(str, '"');
         }
+        return quoteString(str, '"');
     }
 
     private boolean containsWhitespace(final String s) {
@@ -2288,7 +2254,7 @@
     }
 
     private String quoteString(final String str, final char delim) {
-        final StringBuffer buf = new StringBuffer(str.length() * 2);
+        final StringBuilder buf = new StringBuilder(str.length() * 2);
         buf.append(delim);
         final int len = str.length();
         boolean lastCharWasCR = false;
@@ -2336,18 +2302,16 @@
      *
      * @since 1.7
      */
-    private void addSourceFiles(final Vector<SourceFile> sf) {
-        final Iterator<ResourceCollection> e = nestedSourceFiles.iterator();
-        while (e.hasNext()) {
-            ResourceCollection rc = e.next();
+    private void addSourceFiles(final List<SourceFile> sf) {
+        for (ResourceCollection rc : nestedSourceFiles) {
             if (!rc.isFilesystemOnly()) {
-                throw new BuildException("only file system based resources are"
-                                         + " supported by javadoc");
+                throw new BuildException(
+                    "only file system based resources are supported by javadoc");
             }
             if (rc instanceof FileSet) {
                 final FileSet fs = (FileSet) rc;
                 if (!fs.hasPatterns() && !fs.hasSelectors()) {
-                    final FileSet fs2 = (FileSet) fs.clone();
+                    final FileSet fs2 = fs.clone();
                     fs2.createInclude().setName("**/*.java");
                     if (includeNoSourcePackages) {
                         fs2.createInclude().setName("**/package.html");
@@ -2356,7 +2320,7 @@
                 }
             }
             for (final Resource r : rc) {
-                sf.addElement(new SourceFile(r.as(FileProvider.class).getFile()));
+                sf.add(new SourceFile(r.as(FileProvider.class).getFile()));
             }
         }
     }
@@ -2369,10 +2333,9 @@
      *
      * @since 1.5
      */
-    private void parsePackages(final Vector<String> pn, final Path sp) {
-        final HashSet<String> addedPackages = new HashSet<String>();
-        @SuppressWarnings("unchecked")
-        final Vector<DirSet> dirSets = (Vector<DirSet>) packageSets.clone();
+    private void parsePackages(final List<String> pn, final Path sp) {
+        final Set<String> addedPackages = new HashSet<>();
+        final List<DirSet> dirSets = new ArrayList<>(packageSets);
 
         // for each sourcePath entry, add a directoryset with includes
         // taken from packagenames attribute and nested package
@@ -2381,51 +2344,35 @@
         if (sourcePath != null) {
             final PatternSet ps = new PatternSet();
             ps.setProject(getProject());
-            if (packageNames.size() > 0) {
-                final Enumeration<PackageName> e = packageNames.elements();
-                while (e.hasMoreElements()) {
-                    final PackageName p = e.nextElement();
-                    String pkg = p.getName().replace('.', '/');
-                    if (pkg.endsWith("*")) {
-                        pkg += "*";
-                    }
-                    ps.createInclude().setName(pkg);
-                }
-            } else {
+            if (packageNames.isEmpty()) {
                 ps.createInclude().setName("**");
+            } else {
+                packageNames.stream().map(PackageName::getName)
+                    .map(s -> s.replace('.', '/').replaceFirst("\\*$", "**"))
+                    .forEach(pkg -> ps.createInclude().setName(pkg));
             }
 
-            final Enumeration<PackageName> e = excludePackageNames.elements();
-            while (e.hasMoreElements()) {
-                final PackageName p = e.nextElement();
-                String pkg = p.getName().replace('.', '/');
-                if (pkg.endsWith("*")) {
-                    pkg += "*";
-                }
-                ps.createExclude().setName(pkg);
-            }
+            excludePackageNames.stream().map(PackageName::getName)
+                .map(s -> s.replace('.', '/').replaceFirst("\\*$", "**"))
+                .forEach(pkg -> ps.createExclude().setName(pkg));
 
-
-            final String[] pathElements = sourcePath.list();
-            for (int i = 0; i < pathElements.length; i++) {
-                final File dir = new File(pathElements[i]);
+            for (String pathElement : sourcePath.list()) {
+                final File dir = new File(pathElement);
                 if (dir.isDirectory()) {
                     final DirSet ds = new DirSet();
                     ds.setProject(getProject());
                     ds.setDefaultexcludes(useDefaultExcludes);
                     ds.setDir(dir);
                     ds.createPatternSet().addConfiguredPatternset(ps);
-                    dirSets.addElement(ds);
+                    dirSets.add(ds);
                 } else {
-                    log("Skipping " + pathElements[i]
+                    log("Skipping " + pathElement
                         + " since it is no directory.", Project.MSG_WARN);
                 }
             }
         }
 
-        final Enumeration<DirSet> e = dirSets.elements();
-        while (e.hasMoreElements()) {
-            final DirSet ds = e.nextElement();
+        for (DirSet ds : dirSets) {
             final File baseDir = ds.getDir(getProject());
             log("scanning " + baseDir + " for packages.", Project.MSG_DEBUG);
             final DirectoryScanner dsc = ds.getDirectoryScanner(getProject());
@@ -2434,20 +2381,14 @@
             for (int i = 0; i < dirs.length; i++) {
                 // are there any java files in this directory?
                 final File pd = new File(baseDir, dirs[i]);
-                final String[] files = pd.list(new FilenameFilter () {
-                        public boolean accept(final File dir1, final String name) {
-                            return name.endsWith(".java")
-                                || (includeNoSourcePackages
-                                    && name.equals("package.html"));
-                        }
-                    });
+                final String[] files = pd.list((dir1,
+                    name) -> name.endsWith(".java") || (includeNoSourcePackages
+                        && name.equals("package.html")));
 
                 if (files.length > 0) {
                     if ("".equals(dirs[i])) {
                         log(baseDir
-                            + " contains source files in the default package,"
-                            + " you must specify them as source files"
-                            + " not packages.",
+                            + " contains source files in the default package, you must specify them as source files not packages.",
                             Project.MSG_WARN);
                     } else {
                         containsPackages = true;
@@ -2455,7 +2396,7 @@
                             dirs[i].replace(File.separatorChar, '.');
                         if (!addedPackages.contains(packageName)) {
                             addedPackages.add(packageName);
-                            pn.addElement(packageName);
+                            pn.add(packageName);
                         }
                     }
                 }
@@ -2480,14 +2421,13 @@
                 Project.MSG_VERBOSE);
             return;
         }
-        final String fixData;
         final InputStream in = Javadoc.class
             .getResourceAsStream("javadoc-frame-injections-fix.txt");
         if (in == null) {
-            throw new FileNotFoundException("Missing resource "
-                                            + "'javadoc-frame-injections-fix.txt' in "
-                                            + "classpath.");
+            throw new FileNotFoundException(
+                "Missing resource 'javadoc-frame-injections-fix.txt' in classpath.");
         }
+        final String fixData;
         try {
             fixData =
                 fixLineFeeds(FileUtils
@@ -2520,14 +2460,10 @@
             : FILE_UTILS.getDefaultEncoding();
         // we load the whole file as one String (toc/index files are
         // generally small, because they only contain frameset declaration):
-        final InputStream fin = new FileInputStream(file);
         String fileContents;
-        try {
-            fileContents =
-                fixLineFeeds(FileUtils
-                             .safeReadFully(new InputStreamReader(fin, enc)));
-        } finally {
-            FileUtils.close(fin);
+        try (InputStreamReader reader =
+            new InputStreamReader(Files.newInputStream(file.toPath()), enc)) {
+            fileContents = fixLineFeeds(FileUtils.safeReadFully(reader));
         }
 
         // check if file may be vulnerable because it was not
@@ -2536,14 +2472,11 @@
             // we need to patch the file!
             final String patchedFileContents = patchContent(fileContents, fixData);
             if (!patchedFileContents.equals(fileContents)) {
-                final FileOutputStream fos = new FileOutputStream(file);
-                try {
-                    final OutputStreamWriter w = new OutputStreamWriter(fos, enc);
+                try (final OutputStreamWriter w =
+                    new OutputStreamWriter(Files.newOutputStream(file.toPath()), enc)) {
                     w.write(patchedFileContents);
                     w.close();
                     return 1;
-                } finally {
-                    FileUtils.close(fos);
                 }
             }
         }
@@ -2602,7 +2535,6 @@
             }
         }
 
-
         protected void logFlush() {
             if (queuedLine != null) {
                 super.processLine(queuedLine, Project.MSG_VERBOSE);
diff --git a/src/main/org/apache/tools/ant/taskdefs/Length.java b/src/main/org/apache/tools/ant/taskdefs/Length.java
index 68fb20a..2305ef7 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Length.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Length.java
@@ -108,7 +108,7 @@
      * @param ell the long length to compare with.
      */
     public synchronized void setLength(long ell) {
-        length = new Long(ell);
+        length = Long.valueOf(ell);
     }
 
     /**
@@ -152,7 +152,7 @@
      * @param trim <code>boolean</code>.
      */
     public synchronized void setTrim(boolean trim) {
-        this.trim = trim ? Boolean.TRUE : Boolean.FALSE;
+        this.trim = Boolean.valueOf(trim);
     }
 
     /**
@@ -160,25 +160,31 @@
      * @return boolean trim setting.
      */
     public boolean getTrim() {
-        return trim != null && trim.booleanValue();
+        return Boolean.TRUE.equals(trim);
     }
 
     /**
      * Execute the length task.
      */
+    @Override
     public void execute() {
         validate();
-        PrintStream ps = new PrintStream((property != null)
-            ? (OutputStream) new PropertyOutputStream(getProject(), property)
-            : (OutputStream) new LogOutputStream(this, Project.MSG_INFO));
+        OutputStream out =
+            property == null ? new LogOutputStream(this, Project.MSG_INFO)
+                : new PropertyOutputStream(getProject(), property);
+        PrintStream ps = new PrintStream(out);
 
-        if (STRING.equals(mode)) {
+        switch (mode) {
+        case STRING:
             ps.print(getLength(string, getTrim()));
             ps.close();
-        } else if (EACH.equals(mode)) {
+            break;
+        case EACH:
             handleResources(new EachHandler(ps));
-        } else if (ALL.equals(mode)) {
+            break;
+        case ALL:
             handleResources(new AllHandler(ps));
+            break;
         }
     }
 
@@ -187,6 +193,7 @@
      * @return true if the condition is true.
      * @throws BuildException if an error occurs.
      */
+    @Override
     public boolean eval() {
         validate();
         if (length == null) {
@@ -194,11 +201,11 @@
         }
         Long ell;
         if (STRING.equals(mode)) {
-            ell = new Long(getLength(string, getTrim()));
+            ell = Long.valueOf(getLength(string, getTrim()));
         } else {
             AccumHandler h = new AccumHandler();
             handleResources(h);
-            ell = new Long(h.getAccum());
+            ell = Long.valueOf(h.getAccum());
         }
         return when.evaluate(ell.compareTo(length));
     }
@@ -206,25 +213,26 @@
     private void validate() {
         if (string != null) {
             if (resources != null) {
-                throw new BuildException("the string length function"
-                    + " is incompatible with the file/resource length function");
+                throw new BuildException(
+                    "the string length function is incompatible with the file/resource length function");
             }
             if (!(STRING.equals(mode))) {
-                throw new BuildException("the mode attribute is for use"
-                    + " with the file/resource length function");
+                throw new BuildException(
+                    "the mode attribute is for use with the file/resource length function");
             }
         } else if (resources != null) {
             if (!(EACH.equals(mode) || ALL.equals(mode))) {
-                throw new BuildException("invalid mode setting for"
-                    + " file/resource length function: \"" + mode + "\"");
-            } else if (trim != null) {
-                throw new BuildException("the trim attribute is"
-                    + " for use with the string length function only");
+                throw new BuildException(
+                    "invalid mode setting for file/resource length function: \""
+                        + mode + "\"");
+            }
+            if (trim != null) {
+                throw new BuildException(
+                    "the trim attribute is for use with the string length function only");
             }
         } else {
-            throw new BuildException("you must set either the string attribute"
-                + " or specify one or more files using the file attribute or"
-                + " nested resource collections");
+            throw new BuildException(
+                "you must set either the string attribute or specify one or more files using the file attribute or nested resource collections");
         }
     }
 
@@ -253,6 +261,7 @@
          * Return the possible values for FileMode.
          * @return <code>String[]</code>.
          */
+        @Override
         public String[] getValues() {
             return MODES;
         }
@@ -268,6 +277,7 @@
 
     private abstract class Handler {
         private PrintStream ps;
+
         Handler(PrintStream ps) {
             this.ps = ps;
         }
@@ -287,6 +297,8 @@
         EachHandler(PrintStream ps) {
             super(ps);
         }
+
+        @Override
         protected void handle(Resource r) {
             getPs().print(r.toString());
             getPs().print(" : ");
@@ -306,12 +318,16 @@
         AccumHandler() {
             super(null);
         }
+
         protected AccumHandler(PrintStream ps) {
             super(ps);
         }
+
         protected long getAccum() {
             return accum;
         }
+
+        @Override
         protected synchronized void handle(Resource r) {
             long size = r.getSize();
             if (size == Resource.UNKNOWN_SIZE) {
@@ -326,6 +342,8 @@
         AllHandler(PrintStream ps) {
             super(ps);
         }
+
+        @Override
         void complete() {
             getPs().print(getAccum());
             super.complete();
diff --git a/src/main/org/apache/tools/ant/taskdefs/LoadProperties.java b/src/main/org/apache/tools/ant/taskdefs/LoadProperties.java
index 6086318..bc71660 100644
--- a/src/main/org/apache/tools/ant/taskdefs/LoadProperties.java
+++ b/src/main/org/apache/tools/ant/taskdefs/LoadProperties.java
@@ -17,12 +17,12 @@
  */
 package org.apache.tools.ant.taskdefs;
 
-import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
-import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.List;
 import java.util.Properties;
 import java.util.Vector;
 
@@ -30,6 +30,7 @@
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
 import org.apache.tools.ant.filters.util.ChainReaderHelper;
+import org.apache.tools.ant.filters.util.ChainReaderHelper.ChainReader;
 import org.apache.tools.ant.types.FilterChain;
 import org.apache.tools.ant.types.Path;
 import org.apache.tools.ant.types.Reference;
@@ -37,7 +38,6 @@
 import org.apache.tools.ant.types.ResourceCollection;
 import org.apache.tools.ant.types.resources.FileResource;
 import org.apache.tools.ant.types.resources.JavaResource;
-import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.ResourceUtils;
 
 /**
@@ -56,7 +56,7 @@
     /**
      * Holds filterchains
      */
-    private final Vector<FilterChain> filterChains = new Vector<FilterChain>();
+    private final List<FilterChain> filterChains = new Vector<>();
 
     /**
      * Encoding to use for input; defaults to the platform's default encoding.
@@ -159,6 +159,7 @@
      *
      * @exception BuildException if something goes wrong with the build
      */
+    @Override
     public final void execute() throws BuildException {
         //validation
         if (src == null) {
@@ -172,30 +173,21 @@
             }
             throw new BuildException("Source resource does not exist: " + src);
         }
-        BufferedInputStream bis = null;
-        Reader instream = null;
-        ByteArrayInputStream tis = null;
 
-        try {
-            bis = new BufferedInputStream(src.getInputStream());
-            if (encoding == null) {
-                instream = new InputStreamReader(bis);
-            } else {
-                instream = new InputStreamReader(bis, encoding);
-            }
-            ChainReaderHelper crh = new ChainReaderHelper();
-            crh.setPrimaryReader(instream);
-            crh.setFilterChains(filterChains);
-            crh.setProject(getProject());
-            instream = crh.getAssembledReader();
+        Charset charset = encoding == null ? Charset.defaultCharset() : Charset.forName(encoding);
 
-            String text = crh.readFully(instream);
+        try (ChainReader instream = new ChainReaderHelper(getProject(),
+            new InputStreamReader(src.getInputStream(), charset), filterChains)
+                .getAssembledReader()) {
 
-            if (text != null && text.length() != 0) {
+            String text = instream.readFully();
+
+            if (!(text == null || text.isEmpty())) {
                 if (!text.endsWith("\n")) {
                     text = text + "\n";
                 }
-                tis = new ByteArrayInputStream(text.getBytes(ResourceUtils.ISO_8859_1));
+                ByteArrayInputStream tis = new ByteArrayInputStream(
+                    text.getBytes(ResourceUtils.ISO_8859_1));
                 final Properties props = new Properties();
                 props.load(tis);
 
@@ -207,9 +199,6 @@
             }
         } catch (final IOException ioe) {
             throw new BuildException("Unable to load file: " + ioe, ioe, getLocation());
-        } finally {
-            FileUtils.close(bis);
-            FileUtils.close(tis);
         }
     }
 
@@ -218,7 +207,7 @@
      * @param filter the filter to add
      */
     public final void addFilterChain(FilterChain filter) {
-        filterChains.addElement(filter);
+        filterChains.add(filter);
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/taskdefs/LoadResource.java b/src/main/org/apache/tools/ant/taskdefs/LoadResource.java
index f68b5ba..1f44d20 100644
--- a/src/main/org/apache/tools/ant/taskdefs/LoadResource.java
+++ b/src/main/org/apache/tools/ant/taskdefs/LoadResource.java
@@ -19,19 +19,18 @@
 
 import java.io.BufferedInputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.List;
 import java.util.Vector;
-
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
 import org.apache.tools.ant.filters.util.ChainReaderHelper;
+import org.apache.tools.ant.filters.util.ChainReaderHelper.ChainReader;
 import org.apache.tools.ant.types.FilterChain;
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.types.ResourceCollection;
-import org.apache.tools.ant.util.FileUtils;
 
 /**
  * Load a resource into a property
@@ -70,7 +69,7 @@
     /**
      * Holds FilterChains
      */
-    private final Vector<FilterChain> filterChains = new Vector<FilterChain>();
+    private final List<FilterChain> filterChains = new Vector<>();
 
     /**
      * Encoding to use for input, defaults to the platform's default
@@ -124,6 +123,7 @@
      *
      * @exception BuildException if something goes wrong with the build
      */
+    @Override
     public final void execute()
         throws BuildException {
         //validation
@@ -134,82 +134,67 @@
             throw new BuildException("output property not defined");
         }
         if (quiet && failOnError) {
-            throw new BuildException("quiet and failonerror cannot both be "
-                                     + "set to true");
+            throw new BuildException("quiet and failonerror cannot both be set to true");
         }
         if (!src.isExists()) {
             String message = src + " doesn't exist";
             if (failOnError) {
                 throw new BuildException(message);
-            } else {
-                log(message, quiet ? Project.MSG_WARN : Project.MSG_ERR);
-                return;
             }
+            log(message, quiet ? Project.MSG_WARN : Project.MSG_ERR);
+            return;
         }
-        InputStream is = null;
-        BufferedInputStream bis = null;
-        Reader instream = null;
+
         log("loading " + src + " into property " + property,
             Project.MSG_VERBOSE);
+
+        Charset charset = encoding == null ? Charset.defaultCharset()
+            : Charset.forName(encoding);
         try {
             final long len = src.getSize();
-            log("resource size = "
-                + (len != Resource.UNKNOWN_SIZE ? String.valueOf(len)
-                   : "unknown"), Project.MSG_DEBUG);
+            log("resource size = " + (len != Resource.UNKNOWN_SIZE
+                ? String.valueOf(len) : "unknown"), Project.MSG_DEBUG);
             //discard most of really big resources
             final int size = (int) len;
             //open up the resource
-            is = src.getInputStream();
-            bis = new BufferedInputStream(is);
-            if (encoding == null) {
-                instream = new InputStreamReader(bis);
-            } else {
-                instream = new InputStreamReader(bis, encoding);
-            }
 
-            String text = "";
+            String text;
             if (size != 0) {
-                ChainReaderHelper crh = new ChainReaderHelper();
-                if (len != Resource.UNKNOWN_SIZE) {
-                    crh.setBufferSize(size);
-                }
-                crh.setPrimaryReader(instream);
-                crh.setFilterChains(filterChains);
-                crh.setProject(getProject());
-                instream = crh.getAssembledReader();
+                try (ChainReader chainReader = new ChainReaderHelper(
+                    getProject(),
+                    new InputStreamReader(
+                        new BufferedInputStream(src.getInputStream()), charset),
+                    filterChains).with(crh -> {
+                        if (src.getSize() != Resource.UNKNOWN_SIZE) {
+                            crh.setBufferSize(size);
+                        }
+                    }).getAssembledReader()) {
 
-                text = crh.readFully(instream);
+                    text = chainReader.readFully();
+                }
             } else {
                 log("Do not set property " + property + " as its length is 0.",
                     quiet ? Project.MSG_VERBOSE : Project.MSG_INFO);
+                text = null;
             }
 
-            if (text != null) {
-                if (text.length() > 0) {
-                    getProject().setNewProperty(property, text);
-                    log("loaded " + text.length() + " characters",
-                        Project.MSG_VERBOSE);
-                    log(property + " := " + text, Project.MSG_DEBUG);
-                }
+            if (!(text == null || text.isEmpty())) {
+                getProject().setNewProperty(property, text);
+                log("loaded " + text.length() + " characters",
+                    Project.MSG_VERBOSE);
+                log(property + " := " + text, Project.MSG_DEBUG);
             }
-
         } catch (final IOException ioe) {
-            final String message = "Unable to load resource: "
-                + ioe.toString();
+            final String message = "Unable to load resource: " + ioe;
             if (failOnError) {
                 throw new BuildException(message, ioe, getLocation());
-            } else {
-                log(message, quiet ? Project.MSG_VERBOSE : Project.MSG_ERR);
             }
+            log(message, quiet ? Project.MSG_VERBOSE : Project.MSG_ERR);
         } catch (final BuildException be) {
             if (failOnError) {
                 throw be;
-            } else {
-                log(be.getMessage(),
-                    quiet ? Project.MSG_VERBOSE : Project.MSG_ERR);
             }
-        } finally {
-            FileUtils.close(is);
+            log(be.getMessage(), quiet ? Project.MSG_VERBOSE : Project.MSG_ERR);
         }
     }
 
@@ -218,7 +203,7 @@
      * @param filter the filter to add
      */
     public final void addFilterChain(FilterChain filter) {
-        filterChains.addElement(filter);
+        filterChains.add(filter);
     }
 
     /**
@@ -227,8 +212,8 @@
      */
     public void addConfigured(ResourceCollection a) {
         if (a.size() != 1) {
-            throw new BuildException("only single argument resource collections"
-                                     + " are supported");
+            throw new BuildException(
+                "only single argument resource collections are supported");
         }
         src = a.iterator().next();
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java b/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java
index ed16cf3..d25ecb2 100644
--- a/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java
+++ b/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java
@@ -18,11 +18,9 @@
 
 package org.apache.tools.ant.taskdefs;
 
-import java.io.IOException;
-
-import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.ProjectComponent;
 import org.apache.tools.ant.Task;
+import org.apache.tools.ant.util.FileUtils;
 
 /**
  * Logs standard output and error of a subprocess to the log system of ant.
@@ -57,14 +55,10 @@
     /**
      * Stop the log stream handler.
      */
+    @Override
     public void stop() {
         super.stop();
-        try {
-            getErr().close();
-            getOut().close();
-        } catch (IOException e) {
-            // plain impossible
-            throw new BuildException(e);
-        }
+        FileUtils.close(getErr());
+        FileUtils.close(getOut());
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/MacroDef.java b/src/main/org/apache/tools/ant/taskdefs/MacroDef.java
index 95757b6..ce04612 100644
--- a/src/main/org/apache/tools/ant/taskdefs/MacroDef.java
+++ b/src/main/org/apache/tools/ant/taskdefs/MacroDef.java
@@ -23,6 +23,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Objects;
 
 import org.apache.tools.ant.AntTypeDefinition;
 import org.apache.tools.ant.BuildException;
@@ -42,13 +43,13 @@
 public class MacroDef extends AntlibDefinition  {
 
     private NestedSequential nestedSequential;
-    private String     name;
-    private boolean    backTrace = true;
-    private List<Attribute>       attributes = new ArrayList<Attribute>();
-    private Map<String, TemplateElement>        elements   = new HashMap<String, TemplateElement>();
-    private String     textName   = null;
-    private Text       text       = null;
-    private boolean    hasImplicitElement = false;
+    private String name;
+    private boolean backTrace = true;
+    private List<Attribute> attributes = new ArrayList<>();
+    private Map<String, TemplateElement> elements = new HashMap<>();
+    private String textName = null;
+    private Text text = null;
+    private boolean hasImplicitElement = false;
 
     /**
      * Name of the definition
@@ -76,8 +77,8 @@
         for (Attribute attribute : attributes) {
             if (text.getName().equals(attribute.getName())) {
                 throw new BuildException(
-                    "the name \"" + text.getName()
-                    + "\" is already used as an attribute");
+                    "the name \"%s\" is already used as an attribute",
+                    text.getName());
             }
         }
         this.text = text;
@@ -132,13 +133,14 @@
      * This is a simple task container.
      */
     public static class NestedSequential implements TaskContainer {
-        private List<Task> nested = new ArrayList<Task>();
+        private List<Task> nested = new ArrayList<>();
 
         /**
          * Add a task or type to the container.
          *
          * @param task an unknown element.
          */
+        @Override
         public void addTask(Task task) {
             nested.add(task);
         }
@@ -258,17 +260,16 @@
         }
         if (attribute.getName().equals(textName)) {
             throw new BuildException(
-                "the name \"" + attribute.getName()
-                + "\" has already been used by the text element");
+                "the name \"%s\" has already been used by the text element",
+                attribute.getName());
         }
         final int size = attributes.size();
         for (int i = 0; i < size; ++i) {
-            Attribute att = (Attribute) attributes.get(i);
+            Attribute att = attributes.get(i);
             if (att.getName().equals(attribute.getName())) {
                 throw new BuildException(
-                    "the name \"" + attribute.getName()
-                        + "\" has already been used in "
-                        + "another attribute element");
+                    "the name \"%s\" has already been used in another attribute element",
+                    attribute.getName());
             }
         }
         attributes.add(attribute);
@@ -286,11 +287,10 @@
         }
         if (elements.get(element.getName()) != null) {
             throw new BuildException(
-                "the element " + element.getName()
-                + " has already been specified");
+                "the element %s has already been specified", element.getName());
         }
         if (hasImplicitElement
-            || (element.isImplicit() && elements.size() != 0)) {
+            || (element.isImplicit() && !elements.isEmpty())) {
             throw new BuildException(
                 "Only one element allowed when using implicit elements");
         }
@@ -301,6 +301,7 @@
     /**
      * Create a new ant type based on the embedded tasks and types.
      */
+    @Override
     public void execute() {
         if (nestedSequential == null) {
             throw new BuildException("Missing sequential element");
@@ -322,7 +323,6 @@
         log("creating macro  " + name, Project.MSG_VERBOSE);
     }
 
-
     /**
      * An attribute for the MacroDef task.
      *
@@ -340,8 +340,8 @@
          */
         public void setName(String name) {
             if (!isValidName(name)) {
-                throw new BuildException(
-                    "Illegal name [" + name + "] for attribute");
+                throw new BuildException("Illegal name [%s] for attribute",
+                    name);
             }
             this.name = name.toLowerCase(Locale.ENGLISH);
         }
@@ -412,6 +412,7 @@
          * @param obj an <code>Object</code> value
          * @return a <code>boolean</code> value
          */
+        @Override
         public boolean equals(Object obj) {
             if (obj == null) {
                 return false;
@@ -440,8 +441,9 @@
         /**
          * @return a hash code value for this object.
          */
+        @Override
         public int hashCode() {
-            return objectHashCode(defaultValue) + objectHashCode(name);
+            return Objects.hashCode(defaultValue) + Objects.hashCode(name);
         }
     }
 
@@ -463,8 +465,8 @@
          */
         public void setName(String name) {
             if (!isValidName(name)) {
-                throw new BuildException(
-                    "Illegal name [" + name + "] for attribute");
+                throw new BuildException("Illegal name [%s] for element",
+                    name);
             }
             this.name = name.toLowerCase(Locale.ENGLISH);
         }
@@ -544,6 +546,7 @@
          * @param obj an <code>Object</code> value
          * @return a <code>boolean</code> value
          */
+        @Override
         public boolean equals(Object obj) {
             if (obj == null) {
                 return false;
@@ -552,24 +555,21 @@
                 return false;
             }
             Text other = (Text) obj;
-            return safeCompare(name, other.name)
+            return Objects.equals(name, other.name)
                 && optional == other.optional
                 && trim == other.trim
-                && safeCompare(defaultString, other.defaultString);
+                && Objects.equals(defaultString, other.defaultString);
         }
 
         /**
          * @return a hash code value for this object.
          */
+        @Override
         public int hashCode() {
-            return objectHashCode(name);
+            return Objects.hashCode(name);
         }
     }
 
-    private static boolean safeCompare(Object a, Object b) {
-        return a == null ? b == null : a.equals(b);
-    }
-
     /**
      * A nested element for the MacroDef task.
      */
@@ -587,8 +587,8 @@
          */
         public void setName(String name) {
             if (!isValidName(name)) {
-                throw new BuildException(
-                    "Illegal name [" + name + "] for macro element");
+                throw new BuildException("Illegal name [%s] for macro element",
+                    name);
             }
             this.name = name.toLowerCase(Locale.ENGLISH);
         }
@@ -668,6 +668,7 @@
          * @param obj an <code>Object</code> value
          * @return a <code>boolean</code> value
          */
+        @Override
         public boolean equals(Object obj) {
             if (obj == this) {
               return true;
@@ -685,8 +686,9 @@
         /**
          * @return a hash code value for this object.
          */
+        @Override
         public int hashCode() {
-            return objectHashCode(name)
+            return Objects.hashCode(name)
                 + (optional ? 1 : 0) + (implicit ? 1 : 0);
         }
 
@@ -729,21 +731,17 @@
             if (other.text != null) {
                 return false;
             }
-        } else {
-            if (!text.equals(other.text)) {
-                return false;
-            }
+        } else if (!text.equals(other.text)) {
+            return false;
         }
-        if (getURI() == null || getURI().equals("")
+        if (getURI() == null || "".equals(getURI())
             || getURI().equals(ProjectHelper.ANT_CORE_URI)) {
-            if (!(other.getURI() == null || other.getURI().equals("")
+            if (!(other.getURI() == null || "".equals(other.getURI())
                   || other.getURI().equals(ProjectHelper.ANT_CORE_URI))) {
                 return false;
             }
-        } else {
-            if (!getURI().equals(other.getURI())) {
-                return false;
-            }
+        } else if (!getURI().equals(other.getURI())) {
+            return false;
         }
 
         if (!nestedSequential.similar(other.nestedSequential)) {
@@ -801,6 +799,7 @@
          * @param project the current project
          * @return the created object
          */
+        @Override
         public Object create(Project project) {
             Object o = super.create(project);
             if (o == null) {
@@ -817,6 +816,7 @@
          * @param project the current project
          * @return true if the definitions are the same
          */
+        @Override
         public boolean sameDefinition(AntTypeDefinition other, Project project) {
             if (!super.sameDefinition(other, project)) {
                 return false;
@@ -832,6 +832,7 @@
          * @param project the current project
          * @return true if the definitions are the same
          */
+        @Override
         public boolean similarDefinition(
             AntTypeDefinition other, Project project) {
             if (!super.similarDefinition(other, project)) {
@@ -842,12 +843,4 @@
         }
     }
 
-    private static int objectHashCode(Object o) {
-        if (o == null) {
-            return 0;
-        } else {
-            return o.hashCode();
-        }
-    }
-
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java b/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java
index 9ffa9b2..12249e6 100644
--- a/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java
+++ b/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java
@@ -23,11 +23,9 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
 
 import org.apache.tools.ant.BuildException;
@@ -50,13 +48,13 @@
  */
 public class MacroInstance extends Task implements DynamicAttribute, TaskContainer {
     private MacroDef macroDef;
-    private Map<String, String>      map = new HashMap<String, String>();
-    private Map<String, MacroDef.TemplateElement>      nsElements = null;
-    private Map<String, UnknownElement>      presentElements;
-    private Hashtable<String, String> localAttributes;
-    private String    text = null;
-    private String    implicitTag =     null;
-    private List<Task>      unknownElements = new ArrayList<Task>();
+    private Map<String, String> map = new HashMap<>();
+    private Map<String, MacroDef.TemplateElement> nsElements = null;
+    private Map<String, UnknownElement> presentElements;
+    private Map<String, String> localAttributes;
+    private String text = null;
+    private String implicitTag = null;
+    private List<Task> unknownElements = new ArrayList<>();
 
     /**
      * Called from MacroDef.MyAntTypeDefinition#create()
@@ -80,6 +78,7 @@
      * @param name the name of the attribute
      * @param value the value of the attribute
      */
+    @Override
     public void setDynamicAttribute(String name, String value) {
         map.put(name.toLowerCase(Locale.ENGLISH), value);
     }
@@ -91,22 +90,22 @@
      * @deprecated since 1.6.x.
      * @throws BuildException always
      */
+    @Deprecated
     public Object createDynamicElement(String name) throws BuildException {
         throw new BuildException("Not implemented any more");
     }
 
     private Map<String, MacroDef.TemplateElement> getNsElements() {
         if (nsElements == null) {
-            nsElements = new HashMap<String, MacroDef.TemplateElement>();
-            for (Entry<String, MacroDef.TemplateElement> entry : macroDef.getElements().entrySet()) {
-            nsElements.put((String) entry.getKey(),
-                           entry.getValue());
-            MacroDef.TemplateElement te = (MacroDef.TemplateElement)
-                entry.getValue();
-            if (te.isImplicit()) {
-                implicitTag = te.getName();
+            nsElements = new HashMap<>();
+            for (Map.Entry<String, MacroDef.TemplateElement> entry : macroDef
+                .getElements().entrySet()) {
+                nsElements.put(entry.getKey(), entry.getValue());
+                MacroDef.TemplateElement te = entry.getValue();
+                if (te.isImplicit()) {
+                    implicitTag = te.getName();
+                }
             }
-         }
         }
         return nsElements;
     }
@@ -116,6 +115,7 @@
      *
      * @param nestedTask a nested element.
      */
+    @Override
     public void addTask(Task nestedTask) {
         unknownElements.add(nestedTask);
     }
@@ -124,15 +124,15 @@
         if (implicitTag != null) {
             return;
         }
-        for (Iterator<Task> i = unknownElements.iterator(); i.hasNext();) {
-            UnknownElement ue = (UnknownElement) i.next();
+        for (Task task : unknownElements) {
+            UnknownElement ue = (UnknownElement) task;
             String name = ProjectHelper.extractNameFromComponentName(
                 ue.getTag()).toLowerCase(Locale.ENGLISH);
             if (getNsElements().get(name) == null) {
-                throw new BuildException("unsupported element " + name);
+                throw new BuildException("unsupported element %s", name);
             }
             if (presentElements.get(name) != null) {
-                throw new BuildException("Element " + name + " already present");
+                throw new BuildException("Element %s already present", name);
             }
             presentElements.put(name, ue);
         }
@@ -142,13 +142,14 @@
      * Embedded element in macro instance
      */
     public static class Element implements TaskContainer {
-        private List<Task> unknownElements = new ArrayList<Task>();
+        private List<Task> unknownElements = new ArrayList<>();
 
         /**
          * Add an unknown element (to be snipped into the macroDef instance)
          *
          * @param nestedTask an unknown element
          */
+        @Override
         public void addTask(Task nestedTask) {
             unknownElements.add(nestedTask);
         }
@@ -169,8 +170,8 @@
         if (s == null) {
             return null;
         }
-        StringBuffer ret = new StringBuffer();
-        StringBuffer macroName = null;
+        StringBuilder ret = new StringBuilder();
+        StringBuilder macroName = null;
 
         int state = STATE_NORMAL;
         for (int i = 0; i < s.length(); ++i) {
@@ -186,7 +187,7 @@
                 case STATE_EXPECT_BRACKET:
                     if (ch == '{') {
                         state = STATE_EXPECT_NAME;
-                        macroName = new StringBuffer();
+                        macroName = new StringBuilder();
                     } else if (ch == '@') {
                         state = STATE_NORMAL;
                         ret.append('@');
@@ -203,7 +204,7 @@
                     if (ch == '}') {
                         state = STATE_NORMAL;
                         String name = macroName.toString().toLowerCase(Locale.ENGLISH); //NOSONAR
-                        String value = (String) macroMapping.get(name);
+                        String value = macroMapping.get(name);
                         if (value == null) {
                             ret.append("@{");
                             ret.append(name);
@@ -292,40 +293,36 @@
                 rc.addChild(child.getWrapper());
                 ret.addChild(child);
             } else if (templateElement.isImplicit()) {
-                if (unknownElements.size() == 0 && !templateElement.isOptional()) {
+                if (unknownElements.isEmpty() && !templateElement.isOptional()) {
                     throw new BuildException(
-                        "Missing nested elements for implicit element "
-                        + templateElement.getName());
+                        "Missing nested elements for implicit element %s",
+                        templateElement.getName());
                 }
-                for (Iterator<Task> i = unknownElements.iterator();
-                     i.hasNext();) {
-                    UnknownElement child
-                        = copy((UnknownElement) i.next(), true);
+                for (Task task : unknownElements) {
+                    UnknownElement child = copy((UnknownElement) task, true);
                     rc.addChild(child.getWrapper());
                     ret.addChild(child);
                 }
             } else {
                 UnknownElement presentElement =
-                    (UnknownElement) presentElements.get(tag);
+                    presentElements.get(tag);
                 if (presentElement == null) {
                     if (!templateElement.isOptional()) {
                         throw new BuildException(
-                            "Required nested element "
-                            + templateElement.getName() + " missing");
+                            "Required nested element %s missing",
+                            templateElement.getName());
                     }
                     continue;
                 }
                 String presentText =
                     presentElement.getWrapper().getText().toString();
-                if (!"".equals(presentText)) {
+                if (!presentText.isEmpty()) {
                     rc.addText(macroSubs(presentText, localAttributes));
                 }
                 List<UnknownElement> list = presentElement.getChildren();
                 if (list != null) {
-                    for (Iterator<UnknownElement> i = list.iterator();
-                         i.hasNext();) {
-                        UnknownElement child
-                            = copy(i.next(), true);
+                    for (UnknownElement unknownElement2 : list) {
+                        UnknownElement child = copy(unknownElement2, true);
                         rc.addChild(child.getWrapper());
                         ret.addChild(child);
                     }
@@ -341,14 +338,15 @@
      * and calls perform on the unknown element.
      *
      */
+    @Override
     public void execute() {
-        presentElements = new HashMap<String, UnknownElement>();
+        presentElements = new HashMap<>();
         getNsElements();
         processTasks();
-        localAttributes = new Hashtable<String, String>();
-        Set<String> copyKeys = new HashSet<String>(map.keySet());
+        localAttributes = new Hashtable<>();
+        Set<String> copyKeys = new HashSet<>(map.keySet());
         for (Attribute attribute : macroDef.getAttributes()) {
-            String value = (String) map.get(attribute.getName());
+            String value = map.get(attribute.getName());
             if (value == null && "description".equals(attribute.getName())) {
                 value = getDescription();
             }
@@ -357,21 +355,19 @@
                 value = macroSubs(value, localAttributes);
             }
             if (value == null) {
-                throw new BuildException(
-                    "required attribute " + attribute.getName() + " not set");
+                throw new BuildException("required attribute %s not set",
+                    attribute.getName());
             }
             localAttributes.put(attribute.getName(), value);
             copyKeys.remove(attribute.getName());
         }
-        if (copyKeys.contains("id")) {
-            copyKeys.remove("id");
-        }
+        copyKeys.remove("id");
+
         if (macroDef.getText() != null) {
             if (text == null) {
                 String defaultText =  macroDef.getText().getDefault();
                 if (!macroDef.getText().getOptional() && defaultText == null) {
-                    throw new BuildException(
-                        "required text missing");
+                    throw new BuildException("required text missing");
                 }
                 text = defaultText == null ? "" : defaultText;
             }
@@ -379,24 +375,20 @@
                 text = text.trim();
             }
             localAttributes.put(macroDef.getText().getName(), text);
-        } else {
-            if (text != null && !text.trim().equals("")) {
-                throw new BuildException(
-                    "The \"" + getTaskName() + "\" macro does not support"
-                    + " nested text data.");
-            }
-        }
-        if (copyKeys.size() != 0) {
+        } else if (!(text == null || text.trim().isEmpty())) {
             throw new BuildException(
-                "Unknown attribute" + (copyKeys.size() > 1 ? "s " : " ")
-                + copyKeys);
+                "The \"%s\" macro does not support nested text data.",
+                getTaskName());
+        }
+        if (!copyKeys.isEmpty()) {
+            throw new BuildException("Unknown attribute"
+                + (copyKeys.size() > 1 ? "s " : " ") + copyKeys);
         }
 
         // need to set the project on unknown element
         UnknownElement c = copy(macroDef.getNestedTask(), false);
         c.init();
-        LocalProperties localProperties
-            = LocalProperties.get(getProject());
+        LocalProperties localProperties = LocalProperties.get(getProject());
         localProperties.enterScope();
         try {
             c.perform();
diff --git a/src/main/org/apache/tools/ant/taskdefs/MakeUrl.java b/src/main/org/apache/tools/ant/taskdefs/MakeUrl.java
index 9fc94bc..961a3c8 100644
--- a/src/main/org/apache/tools/ant/taskdefs/MakeUrl.java
+++ b/src/main/org/apache/tools/ant/taskdefs/MakeUrl.java
@@ -21,7 +21,6 @@
 import java.io.File;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.ListIterator;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.DirectoryScanner;
@@ -42,6 +41,13 @@
  */
 
 public class MakeUrl extends Task {
+    // error message strings
+    /** Missing file */
+    public static final String ERROR_MISSING_FILE = "A source file is missing: ";
+    /** No property defined */
+    public static final String ERROR_NO_PROPERTY = "No property defined";
+    /** No files defined */
+    public static final String ERROR_NO_FILES = "No files defined";
 
     /**
      * name of the property to set
@@ -61,26 +67,18 @@
     /**
      * filesets of nested files to add to this url
      */
-    private List<FileSet> filesets = new LinkedList<FileSet>();
+    private List<FileSet> filesets = new LinkedList<>();
 
     /**
      * paths to add
      */
-    private List<Path> paths = new LinkedList<Path>();
+    private List<Path> paths = new LinkedList<>();
 
     /**
      * validation flag
      */
     private boolean validate = true;
 
-    // error message strings
-    /** Missing file */
-    public static final String ERROR_MISSING_FILE = "A source file is missing: ";
-    /** No property defined */
-    public static final String ERROR_NO_PROPERTY = "No property defined";
-    /** No files defined */
-    public static final String ERROR_NO_FILES = "No files defined";
-
     /**
      * set the name of a property to fill with the URL
      *
@@ -149,13 +147,10 @@
         }
         int count = 0;
         StringBuilder urls = new StringBuilder();
-        ListIterator<FileSet> list = filesets.listIterator();
-        while (list.hasNext()) {
-            FileSet set = list.next();
-            DirectoryScanner scanner = set.getDirectoryScanner(getProject());
-            String[] files = scanner.getIncludedFiles();
-            for (int i = 0; i < files.length; i++) {
-                File f = new File(scanner.getBasedir(), files[i]);
+        for (FileSet fs : filesets) {
+            DirectoryScanner scanner = fs.getDirectoryScanner(getProject());
+            for (String file : scanner.getIncludedFiles()) {
+                File f = new File(scanner.getBasedir(), file);
                 validateFile(f);
                 String asUrl = toURL(f);
                 urls.append(asUrl);
@@ -181,9 +176,8 @@
         if (count > 0) {
             urls.delete(urls.length() - separator.length(), urls.length());
             return new String(urls);
-        } else {
-            return "";
         }
+        return "";
     }
 
 
@@ -198,12 +192,9 @@
         }
         int count = 0;
         StringBuilder urls = new StringBuilder();
-        ListIterator<Path> list = paths.listIterator();
-        while (list.hasNext()) {
-            Path path = list.next();
-            String[] elements = path.list();
-            for (int i = 0; i < elements.length; i++) {
-                File f = new File(elements[i]);
+        for (Path path : paths) {
+            for (String element : path.list()) {
+                File f = new File(element);
                 validateFile(f);
                 String asUrl = toURL(f);
                 urls.append(asUrl);
@@ -224,7 +215,7 @@
      */
     private void validateFile(File fileToCheck) {
         if (validate && !fileToCheck.exists()) {
-            throw new BuildException(ERROR_MISSING_FILE + fileToCheck.toString());
+            throw new BuildException(ERROR_MISSING_FILE + fileToCheck);
         }
     }
 
@@ -243,23 +234,23 @@
         }
         String url;
         String filesetURL = filesetsToURL();
-        if (file != null) {
+        if (file == null) {
+            url = filesetURL;
+        } else {
             validateFile(file);
             url = toURL(file);
             //and add any files if also defined
-            if (filesetURL.length() > 0) {
+            if (!filesetURL.isEmpty()) {
                 url = url + separator + filesetURL;
             }
-        } else {
-            url = filesetURL;
         }
         //add path URLs
         String pathURL = pathsToURL();
-        if (pathURL.length() > 0) {
-            if (url.length() > 0) {
-                url = url + separator + pathURL;
-            } else {
+        if (!pathURL.isEmpty()) {
+            if (url.isEmpty()) {
                 url = pathURL;
+            } else {
+                url = url + separator + pathURL;
             }
         }
         log("Setting " + property + " to URL " + url, Project.MSG_VERBOSE);
@@ -287,12 +278,9 @@
      * @return the file converted to a URL
      */
     private String toURL(File fileToConvert) {
-        String url;
         //create the URL
         //ant equivalent of  fileToConvert.toURI().toURL().toExternalForm();
-        url = FileUtils.getFileUtils().toURI(fileToConvert.getAbsolutePath());
-
-        return url;
+        return FileUtils.getFileUtils().toURI(fileToConvert.getAbsolutePath());
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Manifest.java b/src/main/org/apache/tools/ant/taskdefs/Manifest.java
index 1daf52f..483d8c6 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Manifest.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Manifest.java
@@ -26,11 +26,15 @@
 import java.io.Reader;
 import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Vector;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.util.CollectionUtils;
@@ -168,14 +172,7 @@
          */
         @Override
         public int hashCode() {
-            int hashCode = 0;
-
-            if (name != null) {
-                hashCode += getKey().hashCode();
-            }
-
-            hashCode += values.hashCode();
-            return hashCode;
+            return Objects.hash(getKey(), values);
         }
 
         /**
@@ -216,8 +213,7 @@
             int index = line.indexOf(": ");
             if (index == -1) {
                 throw new ManifestException("Manifest line \"" + line
-                    + "\" is not valid as it does not "
-                    + "contain a name and a value separated by ': ' ");
+                    + "\" is not valid as it does not contain a name and a value separated by ': '");
             }
             name = line.substring(0, index);
             setValue(line.substring(index + 2));
@@ -273,16 +269,8 @@
          * @return the attribute's value.
          */
         public String getValue() {
-            if (values.size() == 0) {
-                return null;
-            }
-
-            String fullValue = "";
-            for (Enumeration<String> e = getValues(); e.hasMoreElements();) {
-                String value = e.nextElement();
-                fullValue += value + " ";
-            }
-            return fullValue.trim();
+            return values.isEmpty() ? null
+                : values.stream().collect(Collectors.joining(" "));
         }
 
         /**
@@ -343,12 +331,12 @@
          */
         public void write(PrintWriter writer, boolean flatten)
             throws IOException {
-            if (!flatten) {
-            for (Enumeration<String> e = getValues(); e.hasMoreElements();) {
-                writeValue(writer, e.nextElement());
-            }
-            } else {
+            if (flatten) {
                 writeValue(writer, getValue());
+            } else {
+                for (String value : values) {
+                    writeValue(writer, value);
+                }
             }
         }
 
@@ -362,7 +350,7 @@
          */
         private void writeValue(PrintWriter writer, String value)
              throws IOException {
-            String line = null;
+            String line;
             int nameLength = name.getBytes(JAR_ENCODING).length;
             if (nameLength > MAX_NAME_VALUE_LENGTH) {
                 if (nameLength > MAX_NAME_LENGTH) {
@@ -404,7 +392,7 @@
      */
     public static class Section {
         /** Warnings for this section */
-        private Vector<String> warnings = new Vector<String>();
+        private List<String> warnings = new Vector<>();
 
         /**
          * The section's name if any. The main section in a
@@ -413,7 +401,7 @@
         private String name = null;
 
         /** The section's attributes.*/
-        private Map<String, Attribute> attributes = new LinkedHashMap<String, Attribute>();
+        private Map<String, Attribute> attributes = new LinkedHashMap<>();
 
         /**
          * The name of the section; optional -default is the main section.
@@ -450,21 +438,20 @@
             Attribute attribute = null;
             while (true) {
                 String line = reader.readLine();
-                if (line == null || line.length() == 0) {
+                if (line == null || line.isEmpty()) {
                     return null;
                 }
                 if (line.charAt(0) == ' ') {
                     // continuation line
                     if (attribute == null) {
-                        if (name != null) {
-                            // a continuation on the first line is a
-                            // continuation of the name - concatenate this
-                            // line and the name
-                            name += line.substring(1);
-                        } else {
+                        if (name == null) {
                             throw new ManifestException("Can't start an "
                                 + "attribute with a continuation line " + line);
                         }
+                        // a continuation on the first line is a
+                        // continuation of the name - concatenate this
+                        // line and the name
+                        name += line.substring(1);
                     } else {
                         attribute.addContinuation(line);
                     }
@@ -507,8 +494,8 @@
                     && !(name.toLowerCase(Locale.ENGLISH)
                          .equals(section.getName().toLowerCase(Locale.ENGLISH))))
                 ) {
-                throw new ManifestException("Unable to merge sections "
-                    + "with different names");
+                throw new ManifestException(
+                    "Unable to merge sections with different names");
             }
 
             Enumeration<String> e = section.getAttributeKeys();
@@ -516,7 +503,7 @@
             while (e.hasMoreElements()) {
                 String attributeName = e.nextElement();
                 Attribute attribute = section.getAttribute(attributeName);
-                if (attributeName.equalsIgnoreCase(ATTRIBUTE_CLASSPATH)) {
+                if (ATTRIBUTE_CLASSPATH.equalsIgnoreCase(attributeName)) {
                     if (classpathAttribute == null) {
                         classpathAttribute = new Attribute();
                         classpathAttribute.setName(ATTRIBUTE_CLASSPATH);
@@ -547,10 +534,7 @@
             }
 
             // add in the warnings
-            Enumeration<String> warnEnum = section.warnings.elements();
-            while (warnEnum.hasMoreElements()) {
-                warnings.addElement(warnEnum.nextElement());
-            }
+            warnings.addAll(section.warnings);
         }
 
         /**
@@ -650,9 +634,8 @@
              throws ManifestException {
             String check = addAttributeAndCheck(attribute);
             if (check != null) {
-                throw new BuildException("Specify the section name using "
-                    + "the \"name\" attribute of the <section> element rather "
-                    + "than using a \"Name\" manifest attribute");
+                throw new BuildException(
+                    "Specify the section name using the \"name\" attribute of the <section> element rather than using a \"Name\" manifest attribute");
             }
         }
 
@@ -674,15 +657,14 @@
             }
             String attributeKey = attribute.getKey();
             if (attributeKey.equals(ATTRIBUTE_NAME_LC)) {
-                warnings.addElement("\"" + ATTRIBUTE_NAME + "\" attributes "
-                    + "should not occur in the main section and must be the "
-                    + "first element in all other sections: \""
+                warnings.add("\"" + ATTRIBUTE_NAME
+                    + "\" attributes should not occur in the main section and must be the first element in all other sections: \""
                     + attribute.getName() + ": " + attribute.getValue() + "\"");
                 return attribute.getValue();
             }
 
             if (attributeKey.startsWith(ATTRIBUTE_FROM_LC)) {
-                warnings.addElement(ERROR_FROM_FORBIDDEN
+                warnings.add(ERROR_FROM_FORBIDDEN
                     + attribute.getName() + ": " + attribute.getValue() + "\"");
             } else {
                 // classpath attributes go into a vector
@@ -693,10 +675,8 @@
                     if (classpathAttribute == null) {
                         storeAttribute(attribute);
                     } else {
-                        warnings.addElement("Multiple Class-Path attributes "
-                            + "are supported but violate the Jar "
-                            + "specification and may not be correctly "
-                            + "processed in all environments");
+                        warnings.add(
+                            "Multiple Class-Path attributes are supported but violate the Jar specification and may not be correctly processed in all environments");
                         Enumeration<String> e = attribute.getValues();
                         while (e.hasMoreElements()) {
                             String value = e.nextElement();
@@ -705,8 +685,8 @@
                     }
                 } else if (attributes.containsKey(attributeKey)) {
                     throw new ManifestException("The attribute \""
-                        + attribute.getName() + "\" may not occur more "
-                        + "than once in the same section");
+                        + attribute.getName()
+                        + "\" may not occur more than once in the same section");
                 } else {
                     storeAttribute(attribute);
                 }
@@ -721,7 +701,7 @@
          * @since Ant 1.5.2
          */
         @Override
-        public Object clone() {
+        public Section clone() {
             Section cloned = new Section();
             cloned.setName(name);
             Enumeration<String> e = getAttributeKeys();
@@ -753,7 +733,7 @@
          * @return an Enumeration of warning strings.
          */
         public Enumeration<String> getWarnings() {
-            return warnings.elements();
+            return Collections.enumeration(warnings);
         }
 
         /**
@@ -794,7 +774,7 @@
     private Section mainSection = new Section();
 
     /** The named sections of this manifest */
-    private Map<String, Section> sections = new LinkedHashMap<String, Section>();
+    private Map<String, Section> sections = new LinkedHashMap<>();
 
     /**
      * Construct a manifest from Ant's default manifest file.
@@ -804,14 +784,12 @@
      *            default manifest
      */
     public static Manifest getDefaultManifest() throws BuildException {
-        InputStream in = null;
         InputStreamReader insr = null;
-        try {
-            String defManifest = "/org/apache/tools/ant/defaultManifest.mf";
-            in = Manifest.class.getResourceAsStream(defManifest);
+        String defManifest = "/org/apache/tools/ant/defaultManifest.mf";
+        try (InputStream in = Manifest.class.getResourceAsStream(defManifest)) {
             if (in == null) {
-                throw new BuildException("Could not find default manifest: "
-                    + defManifest);
+                throw new BuildException("Could not find default manifest: %s",
+                    defManifest);
             }
             try {
                 insr = new InputStreamReader(in, "UTF-8");
@@ -835,7 +813,6 @@
             throw new BuildException("Unable to read default manifest", e);
         } finally {
             FileUtils.close(insr);
-            FileUtils.close(in);
         }
     }
 
@@ -864,20 +841,20 @@
             mainSection.removeAttribute(ATTRIBUTE_MANIFEST_VERSION);
         }
 
-        String line = null;
+        String line;
         while ((line = reader.readLine()) != null) {
-            if (line.length() == 0) {
+            if (line.isEmpty()) {
                 continue;
             }
 
             Section section = new Section();
             if (nextSectionName == null) {
                 Attribute sectionName = new Attribute(line);
-                if (!sectionName.getName().equalsIgnoreCase(ATTRIBUTE_NAME)) {
-                    throw new ManifestException("Manifest sections should "
-                        + "start with a \"" + ATTRIBUTE_NAME
-                        + "\" attribute and not \""
-                        + sectionName.getName() + "\"");
+                if (!ATTRIBUTE_NAME.equalsIgnoreCase(sectionName.getName())) {
+                    throw new ManifestException(
+                        "Manifest sections should start with a \""
+                            + ATTRIBUTE_NAME + "\" attribute and not \""
+                            + sectionName.getName() + "\"");
                 }
                 nextSectionName = sectionName.getValue();
             } else {
@@ -922,7 +899,7 @@
         if (attribute.getKey() == null || attribute.getValue() == null) {
             throw new BuildException("Attributes must have name and value");
         }
-        if (attribute.getKey().equals(ATTRIBUTE_MANIFEST_VERSION_LC)) {
+        if (ATTRIBUTE_MANIFEST_VERSION_LC.equals(attribute.getKey())) {
             manifestVersion = attribute.getValue();
         } else {
             mainSection.addConfiguredAttribute(attribute);
@@ -977,7 +954,7 @@
          throws ManifestException {
         if (other != null) {
              if (overwriteMain) {
-                 mainSection = (Section) other.mainSection.clone();
+                 mainSection = other.mainSection.clone();
              } else {
                  mainSection.merge(other.mainSection, mergeClassPaths);
              }
@@ -994,7 +971,7 @@
                     = other.sections.get(sectionName);
                  if (ourSection == null) {
                      if (otherSection != null) {
-                         addConfiguredSection((Section) otherSection.clone());
+                         addConfiguredSection(otherSection.clone());
                      }
                  } else {
                      ourSection.merge(otherSection, mergeClassPaths);
@@ -1077,7 +1054,7 @@
      * @return an enumeration of warning strings
      */
     public Enumeration<String> getWarnings() {
-        Vector<String> warnings = new Vector<String>();
+        Vector<String> warnings = new Vector<>();
 
         Enumeration<String> warnEnum = mainSection.getWarnings();
         while (warnEnum.hasMoreElements()) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java b/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java
index 4a4f231..96cc050 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java
@@ -18,7 +18,6 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
-import java.io.UnsupportedEncodingException;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Task;
@@ -52,6 +51,7 @@
      * separated list of files and directories relative to the jar
      * file's parent directory.
      */
+    @Override
     public void execute() {
         if (name == null) {
             throw new BuildException("Missing 'property' attribute!");
@@ -60,13 +60,13 @@
             throw new BuildException("Missing 'jarfile' attribute!");
         }
         if (getProject().getProperty(name) != null) {
-            throw new BuildException("Property '" + name + "' already set!");
+            throw new BuildException("Property '%s' already set!", name);
         }
         if (path == null) {
             throw new BuildException("Missing nested <classpath>!");
         }
 
-        StringBuffer tooLongSb = new StringBuffer();
+        StringBuilder tooLongSb = new StringBuilder();
         for (int i = 0; i < maxParentLevels + 1; i++) {
             tooLongSb.append("../");
         }
@@ -77,10 +77,10 @@
         dir = fileUtils.normalize(dir.getAbsolutePath());
 
         String[] elements = path.list();
-        StringBuffer buffer = new StringBuffer();
-        for (int i = 0; i < elements.length; ++i) {
+        StringBuilder buffer = new StringBuilder();
+        for (String element : elements) {
             // Normalize the current file
-            File pathEntry = new File(elements[i]);
+            File pathEntry = new File(element);
             String fullPath = pathEntry.getAbsolutePath();
             pathEntry = fileUtils.normalize(fullPath);
 
@@ -108,18 +108,15 @@
             // No match, so bail out!
             if (relPath.equals(canonicalPath)
                 || relPath.startsWith(tooLongPrefix)) {
-                throw new BuildException("No suitable relative path from "
-                                         + dir + " to " + fullPath);
+                throw new BuildException(
+                    "No suitable relative path from %s to %s", dir, fullPath);
             }
 
             if (pathEntry.isDirectory() && !relPath.endsWith("/")) {
                 relPath = relPath + '/';
             }
-            try {
-                relPath = Locator.encodeURI(relPath);
-            } catch (UnsupportedEncodingException exc) {
-                throw new BuildException(exc);
-            }
+            relPath = Locator.encodeURI(relPath);
+
             // Manifest's ClassPath: attribute always uses forward
             // slashes '/', and is space-separated. Ant will properly
             // format it on 72 columns with proper line continuation
@@ -149,7 +146,7 @@
     public void setJarFile(File jarfile) {
         File parent = jarfile.getParentFile();
         if (!parent.isDirectory()) {
-            throw new BuildException("Jar's directory not found: " + parent);
+            throw new BuildException("Jar's directory not found: %s", parent);
         }
         this.dir = parent;
     }
@@ -162,8 +159,8 @@
      */
     public void setMaxParentLevels(int levels) {
         if (levels < 0) {
-            throw new BuildException("maxParentLevels must not be a negative"
-                                     + " number");
+            throw new BuildException(
+                "maxParentLevels must not be a negative number");
         }
         this.maxParentLevels = levels;
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java b/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java
index ff6961b..151a3cf 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java
@@ -19,12 +19,12 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
 import java.util.Enumeration;
 
 import org.apache.tools.ant.BuildException;
@@ -32,7 +32,6 @@
 import org.apache.tools.ant.Task;
 import org.apache.tools.ant.taskdefs.Manifest.Attribute;
 import org.apache.tools.ant.types.EnumeratedAttribute;
-import org.apache.tools.ant.util.FileUtils;
 
 /**
  * Creates a manifest file for inclusion in a JAR, Ant task wrapper
@@ -91,6 +90,7 @@
          *
          * @return a String array of the allowed values.
          */
+        @Override
         public String[] getValues() {
             return new String[] {"update", "replace"};
         }
@@ -157,13 +157,15 @@
         char ch = name.charAt(0);
 
         if (ch == '-' || ch == '_') {
-            throw new BuildException("Manifest attribute names must not start with '" + ch + "'.");
+            throw new BuildException(
+                "Manifest attribute names must not start with '%c'.", ch);
         }
 
         for (int i = 0; i < name.length(); i++) {
             ch = name.charAt(i);
             if (VALID_ATTRIBUTE_CHARS.indexOf(ch) < 0) {
-                throw new BuildException("Manifest attribute names must not contain '" + ch + "'");
+                throw new BuildException(
+                    "Manifest attribute names must not contain '%c'", ch);
             }
         }
     }
@@ -219,6 +221,7 @@
      *
      * @throws BuildException if the manifest cannot be written.
      */
+    @Override
     public void execute() throws BuildException {
         if (manifestFile == null) {
             throw new BuildException("the file attribute is required");
@@ -229,15 +232,9 @@
         BuildException error = null;
 
         if (manifestFile.exists()) {
-            FileInputStream fis = null;
-            InputStreamReader isr = null;
-            try {
-                fis = new FileInputStream(manifestFile);
-                if (encoding == null) {
-                    isr = new InputStreamReader(fis, "UTF-8");
-                } else {
-                    isr = new InputStreamReader(fis, encoding);
-                }
+            Charset charset = Charset.forName(encoding == null ? "UTF-8" : encoding);
+            try (InputStreamReader isr = new InputStreamReader(
+                Files.newInputStream(manifestFile.toPath()), charset)) {
                 current = new Manifest(isr);
             } catch (ManifestException m) {
                 error = new BuildException("Existing manifest " + manifestFile
@@ -245,8 +242,6 @@
             } catch (IOException e) {
                 error = new BuildException("Failed to read " + manifestFile,
                                            e, getLocation());
-            } finally {
-                FileUtils.close(isr);
             }
         }
 
@@ -257,7 +252,7 @@
                     Project.MSG_WARN);
         }
         try {
-            if (mode.getValue().equals("update") && manifestFile.exists()) {
+            if ("update".equals(mode.getValue()) && manifestFile.exists()) {
                 if (current != null) {
                     toWrite.merge(current, false, mergeClassPaths);
                 } else if (error != null) {
@@ -276,11 +271,8 @@
             return;
         }
 
-        PrintWriter w = null;
-        try {
-            FileOutputStream fos = new FileOutputStream(manifestFile);
-            OutputStreamWriter osw = new OutputStreamWriter(fos, Manifest.JAR_ENCODING);
-            w = new PrintWriter(osw);
+        try (PrintWriter w = new PrintWriter(new OutputStreamWriter(
+            Files.newOutputStream(manifestFile.toPath()), Manifest.JAR_ENCODING))) {
             toWrite.write(w, flattenClassPaths);
             if (w.checkError()) {
                 throw new IOException("Encountered an error writing manifest");
@@ -288,8 +280,6 @@
         } catch (IOException e) {
             throw new BuildException("Failed to write " + manifestFile,
                                      e, getLocation());
-        } finally {
-            FileUtils.close(w);
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java b/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java
index c35af03..a7654db 100644
--- a/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java
@@ -62,6 +62,7 @@
     // CheckStyle:VisibilityModifier ON
 
     /** {@inheritDoc}. */
+    @Override
     public void setProject(Project project) {
         super.setProject(project);
         fileset.setProject(project);
@@ -128,8 +129,8 @@
     public void XsetItems(String itemString) {
         log("The items attribute is deprecated. "
             + "Please use the includes attribute.", Project.MSG_WARN);
-        if (itemString == null || itemString.equals("*")
-            || itemString.equals(".")) {
+        if (itemString == null || "*".equals(itemString)
+            || ".".equals(itemString)) {
             createInclude().setName("**");
         } else {
             StringTokenizer tok = new StringTokenizer(itemString, ", ");
@@ -161,7 +162,7 @@
     public void XsetIgnore(String ignoreString) {
         log("The ignore attribute is deprecated."
             + "Please use the excludes attribute.", Project.MSG_WARN);
-        if (ignoreString != null && ignoreString.length() > 0) {
+        if (!(ignoreString == null || ignoreString.isEmpty())) {
             StringTokenizer tok = new StringTokenizer(ignoreString, ", ",
                                                       false);
             while (tok.hasMoreTokens()) {
@@ -237,6 +238,7 @@
      *
      * @return whether any selectors are in this container
      */
+    @Override
     public boolean hasSelectors() {
         return fileset.hasSelectors();
     }
@@ -246,6 +248,7 @@
      *
      * @return the number of selectors in this container
      */
+    @Override
     public int selectorCount() {
         return fileset.selectorCount();
     }
@@ -255,6 +258,7 @@
      * @param p the current project
      * @return an array of selectors in this container
      */
+    @Override
     public FileSelector[] getSelectors(Project p) {
         return fileset.getSelectors(p);
     }
@@ -264,6 +268,7 @@
      *
      * @return an enumerator that goes through each of the selectors
      */
+    @Override
     public Enumeration<FileSelector> selectorElements() {
         return fileset.selectorElements();
     }
@@ -273,6 +278,7 @@
      *
      * @param selector the new selector to add
      */
+    @Override
     public void appendSelector(FileSelector selector) {
         fileset.appendSelector(selector);
     }
@@ -283,6 +289,7 @@
      * add a "Select" selector entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addSelector(SelectSelector selector) {
         fileset.addSelector(selector);
     }
@@ -291,6 +298,7 @@
      * add an "And" selector entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addAnd(AndSelector selector) {
         fileset.addAnd(selector);
     }
@@ -299,6 +307,7 @@
      * add an "Or" selector entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addOr(OrSelector selector) {
         fileset.addOr(selector);
     }
@@ -307,6 +316,7 @@
      * add a "Not" selector entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addNot(NotSelector selector) {
         fileset.addNot(selector);
     }
@@ -315,6 +325,7 @@
      * add a "None" selector entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addNone(NoneSelector selector) {
         fileset.addNone(selector);
     }
@@ -323,6 +334,7 @@
      * add a majority selector entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addMajority(MajoritySelector selector) {
         fileset.addMajority(selector);
     }
@@ -331,6 +343,7 @@
      * add a selector date entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addDate(DateSelector selector) {
         fileset.addDate(selector);
     }
@@ -339,6 +352,7 @@
      * add a selector size entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addSize(SizeSelector selector) {
         fileset.addSize(selector);
     }
@@ -347,6 +361,7 @@
      * add a selector filename entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addFilename(FilenameSelector selector) {
         fileset.addFilename(selector);
     }
@@ -355,6 +370,7 @@
      * add an extended selector entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addCustom(ExtendSelector selector) {
         fileset.addCustom(selector);
     }
@@ -363,6 +379,7 @@
      * add a contains selector entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addContains(ContainsSelector selector) {
         fileset.addContains(selector);
     }
@@ -371,6 +388,7 @@
      * add a present selector entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addPresent(PresentSelector selector) {
         fileset.addPresent(selector);
     }
@@ -379,6 +397,7 @@
      * add a depth selector entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addDepth(DepthSelector selector) {
         fileset.addDepth(selector);
     }
@@ -387,6 +406,7 @@
      * add a depends selector entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addDepend(DependSelector selector) {
         fileset.addDepend(selector);
     }
@@ -395,6 +415,7 @@
      * add a regular expression selector entry on the selector list
      * @param selector the selector to add
      */
+    @Override
     public void addContainsRegexp(ContainsRegexpSelector selector) {
         fileset.addContainsRegexp(selector);
     }
@@ -404,6 +425,7 @@
      * @param selector the selector to add
      * @since ant 1.6
      */
+    @Override
     public void addDifferent(DifferentSelector selector) {
         fileset.addDifferent(selector);
     }
@@ -413,6 +435,7 @@
      * @param selector the selector to add
      * @since ant 1.6
      */
+    @Override
     public void addType(TypeSelector selector) {
         fileset.addType(selector);
     }
@@ -422,6 +445,7 @@
      * @param selector the selector to add
      * @since ant 1.6
      */
+    @Override
     public void addModified(ModifiedSelector selector) {
         fileset.addModified(selector);
     }
@@ -431,6 +455,7 @@
      * @param selector the selector to add
      * @since Ant 1.6
      */
+    @Override
     public void add(FileSelector selector) {
         fileset.add(selector);
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Mkdir.java b/src/main/org/apache/tools/ant/taskdefs/Mkdir.java
index 71b6c94..8a672b6 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Mkdir.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Mkdir.java
@@ -46,29 +46,30 @@
      * create the directory and all parents
      * @throws BuildException if dir is somehow invalid, or creation failed.
      */
+    @Override
     public void execute() throws BuildException {
         if (dir == null) {
             throw new BuildException("dir attribute is required", getLocation());
         }
 
         if (dir.isFile()) {
-            throw new BuildException("Unable to create directory as a file "
-                                     + "already exists with that name: "
-                                     + dir.getAbsolutePath());
+            throw new BuildException(
+                "Unable to create directory as a file already exists with that name: %s",
+                dir.getAbsolutePath());
         }
 
         if (!dir.exists()) {
             boolean result = mkdirs(dir);
             if (!result) {
                 if (dir.exists()) {
-                    log("A different process or task has already created "
-                        + "dir " + dir.getAbsolutePath(),
-                        Project.MSG_VERBOSE);
+                    log("A different process or task has already created dir "
+                        + dir.getAbsolutePath(), Project.MSG_VERBOSE);
                     return;
                 }
-                String msg = "Directory " + dir.getAbsolutePath()
-                    + " creation was not successful for an unknown reason";
-                throw new BuildException(msg, getLocation());
+                throw new BuildException(
+                    "Directory " + dir.getAbsolutePath()
+                        + " creation was not successful for an unknown reason",
+                    getLocation());
             }
             log("Created dir: " + dir.getAbsolutePath());
         } else {
@@ -111,4 +112,3 @@
         return true;
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/Move.java b/src/main/org/apache/tools/ant/taskdefs/Move.java
index c549d1b..68ebfd5 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Move.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Move.java
@@ -19,14 +19,13 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.util.Iterator;
+import java.util.Map;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.DirectoryScanner;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.taskdefs.condition.Os;
 import org.apache.tools.ant.types.FileSet;
-import org.apache.tools.ant.types.FilterSet;
 import org.apache.tools.ant.types.FilterSetCollection;
 
 /**
@@ -80,6 +79,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     protected void validateAttributes() throws BuildException {
         if (file != null && file.isDirectory()) {
             if ((destFile != null && destDir != null)
@@ -103,12 +103,13 @@
     /**
      * Override copy's doFileOperations to move the files instead of copying them.
      */
+    @Override
     protected void doFileOperations() {
         //Attempt complete directory renames, if any, first.
         if (completeDirMap.size() > 0) {
-            for (Iterator fromDirs = completeDirMap.keySet().iterator(); fromDirs.hasNext();) {
-                File fromDir = (File) fromDirs.next();
-                File toDir = (File) completeDirMap.get(fromDir);
+            for (Map.Entry<File, File> entry : completeDirMap.entrySet()) {
+                File fromDir = entry.getKey();
+                File toDir = entry.getValue();
                 boolean renamed = false;
                 try {
                     log("Attempting to rename dir: " + fromDir + " to " + toDir, verbosity);
@@ -135,14 +136,14 @@
             log("Moving " + moveCount + " file" + ((moveCount == 1) ? "" : "s")
                     + " to " + destDir.getAbsolutePath());
 
-            for (Iterator fromFiles = fileCopyMap.keySet().iterator(); fromFiles.hasNext();) {
-                String fromFile = (String) fromFiles.next();
+            for (Map.Entry<String, String[]> entry : fileCopyMap.entrySet()) {
+                String fromFile = entry.getKey();
                 File f = new File(fromFile);
                 boolean selfMove = false;
                 if (f.exists()) { //Is this file still available to be moved?
-                    String[] toFiles = (String[]) fileCopyMap.get(fromFile);
+                    String[] toFiles = entry.getValue();
                     for (int i = 0; i < toFiles.length; i++) {
-                        String toFile = (String) toFiles[i];
+                        String toFile = toFiles[i];
 
                         if (fromFile.equals(toFile)) {
                             log("Skipping self-move of " + fromFile, verbosity);
@@ -167,9 +168,9 @@
 
         if (includeEmpty) {
             int createCount = 0;
-            for (Iterator fromDirNames = dirCopyMap.keySet().iterator(); fromDirNames.hasNext();) {
-                String fromDirName = (String) fromDirNames.next();
-                String[] toDirNames = (String[]) dirCopyMap.get(fromDirName);
+            for (Map.Entry<String, String[]> entry : dirCopyMap.entrySet()) {
+                String fromDirName = entry.getKey();
+                String[] toDirNames = entry.getValue();
                 boolean selfMove = false;
                 for (int i = 0; i < toDirNames.length; i++) {
                     if (fromDirName.equals(toDirNames[i])) {
@@ -214,16 +215,15 @@
             log("Attempting to rename: " + fromFile + " to " + toFile, verbosity);
             moved = renameFile(fromFile, toFile, filtering, forceOverwrite);
         } catch (IOException ioe) {
-            String msg = "Failed to rename " + fromFile
-                + " to " + toFile + " due to " + ioe.getMessage();
-            throw new BuildException(msg, ioe, getLocation());
+            throw new BuildException("Failed to rename " + fromFile + " to "
+                + toFile + " due to " + ioe.getMessage(), ioe, getLocation());
         }
 
         if (!moved) {
             copyFile(fromFile, toFile, filtering, overwrite);
             if (!getFileUtils().tryHardToDelete(fromFile, performGc)) {
-                throw new BuildException("Unable to delete " + "file "
-                        + fromFile.getAbsolutePath());
+                throw new BuildException("Unable to delete file %s",
+                    fromFile.getAbsolutePath());
             }
         }
     }
@@ -243,9 +243,7 @@
             if (filtering) {
                 executionFilters.addFilterSet(getProject().getGlobalFilterSet());
             }
-            for (Iterator filterIter = getFilterSets().iterator(); filterIter.hasNext();) {
-                executionFilters.addFilterSet((FilterSet) filterIter.next());
-            }
+            getFilterSets().forEach(executionFilters::addFilterSet);
             getFileUtils().copyFile(fromFile, toFile, executionFilters,
                                     getFilterChains(),
                                     forceOverwrite,
@@ -255,9 +253,8 @@
                                     getOutputEncoding(),
                                     getProject(), getForce());
         } catch (IOException ioe) {
-            String msg = "Failed to copy " + fromFile
-                    + " to " + toFile + " due to " + ioe.getMessage();
-            throw new BuildException(msg, ioe, getLocation());
+            throw new BuildException("Failed to copy " + fromFile + " to "
+                + toFile + " due to " + ioe.getMessage(), ioe, getLocation());
         }
     }
 
@@ -272,8 +269,7 @@
             return false;
         }     // maybe io error?
 
-        for (int i = 0; i < list.length; i++) {
-            String s = list[i];
+        for (String s : list) {
             File f = new File(d, s);
             if (f.isDirectory()) {
                 if (!okToDelete(f)) {
@@ -305,22 +301,24 @@
             return;
         }      // on an io error list() can return null
 
-        for (int i = 0; i < list.length; i++) {
-            String s = list[i];
+        for (String s : list) {
             File f = new File(d, s);
             if (f.isDirectory()) {
                 deleteDir(f);
-            } else if (deleteFiles && !getFileUtils().tryHardToDelete(f,
-                                                                      performGc)) {
-                throw new BuildException("Unable to delete file " + f.getAbsolutePath());
+            } else if (deleteFiles
+                && !getFileUtils().tryHardToDelete(f, performGc)) {
+                throw new BuildException("Unable to delete file %s",
+                    f.getAbsolutePath());
             } else {
-                throw new BuildException("UNEXPECTED ERROR - The file "
-                        + f.getAbsolutePath() + " should not exist!");
+                throw new BuildException(
+                    "UNEXPECTED ERROR - The file %s should not exist!",
+                    f.getAbsolutePath());
             }
         }
         log("Deleting directory " + d.getAbsolutePath(), verbosity);
         if (!getFileUtils().tryHardToDelete(d, performGc)) {
-            throw new BuildException("Unable to delete directory " + d.getAbsolutePath());
+            throw new BuildException("Unable to delete directory %s",
+                d.getAbsolutePath());
         }
     }
 
@@ -344,19 +342,21 @@
      */
     protected boolean renameFile(File sourceFile, File destFile, boolean filtering,
                                  boolean overwrite) throws IOException, BuildException {
-        if (destFile.isDirectory() || filtering || getFilterSets().size() > 0
-                || getFilterChains().size() > 0) {
+        if (destFile.isDirectory() || filtering || !getFilterSets().isEmpty()
+                || !getFilterChains().isEmpty()) {
             return false;
         }
 
         // identical logic lives in ResourceUtils.copyResource():
         if (destFile.isFile() && !destFile.canWrite()) {
             if (!getForce()) {
-                throw new IOException("can't replace read-only destination "
-                                      + "file " + destFile);
-            } else if (!getFileUtils().tryHardToDelete(destFile)) {
-                throw new IOException("failed to delete read-only "
-                                      + "destination file " + destFile);
+                throw new IOException(String.format(
+                    "can't replace read-only destination file %s", destFile));
+            }
+            if (!getFileUtils().tryHardToDelete(destFile)) {
+                throw new IOException(String.format(
+                    "failed to delete read-only destination file %s",
+                    destFile));
             }
         }
 
@@ -375,7 +375,8 @@
             }
             if (!(getFileUtils().areSame(sourceFile, destFile)
                   || getFileUtils().tryHardToDelete(destFile, performGc))) {
-                throw new BuildException("Unable to remove existing file " + destFile);
+                throw new BuildException("Unable to remove existing file %s",
+                    destFile);
             }
         }
         return sourceFile.renameTo(destFile);
diff --git a/src/main/org/apache/tools/ant/taskdefs/Nice.java b/src/main/org/apache/tools/ant/taskdefs/Nice.java
index 5898cae..4bd5beb 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Nice.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Nice.java
@@ -48,12 +48,11 @@
      */
     private String currentPriority;
 
-
-
     /**
      * Execute the task
      * @exception BuildException if something goes wrong with the build
      */
+    @Override
     public void execute() throws BuildException {
 
         Thread self = Thread.currentThread();
@@ -93,7 +92,7 @@
         if (newPriority < Thread.MIN_PRIORITY || newPriority > Thread.MAX_PRIORITY) {
             throw new BuildException("The thread priority is out of the range 1-10");
         }
-        this.newPriority = new Integer(newPriority);
+        this.newPriority = Integer.valueOf(newPriority);
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Pack.java b/src/main/org/apache/tools/ant/taskdefs/Pack.java
index 63dfe05..f617e61 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Pack.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Pack.java
@@ -38,6 +38,7 @@
 
 public abstract class Pack extends Task {
     private static final int BUFFER_SIZE = 8 * 1024;
+
     // CheckStyle:VisibilityModifier OFF - bc
     protected File zipFile;
     protected File source;
@@ -91,13 +92,14 @@
      */
     public void addConfigured(ResourceCollection a) {
         if (a.size() == 0) {
-            throw new BuildException("No resource selected, " + getTaskName()
-                    + " needs exactly one resource.");
+            throw new BuildException(
+                "No resource selected, %s needs exactly one resource.",
+                getTaskName());
         }
         if (a.size() != 1) {
-            throw new BuildException(getTaskName()
-                    + " cannot handle multiple resources at once. (" + a.size()
-                    + " resources were selected.)");
+            throw new BuildException(
+                "%s cannot handle multiple resources at once. (%d resources were selected.)",
+                getTaskName(), a.size());
         }
         setSrcResource(a.iterator().next());
     }
@@ -112,13 +114,14 @@
         }
 
         if (zipFile.isDirectory()) {
-            throw new BuildException("zipfile attribute must not "
-                                    + "represent a directory!", getLocation());
+            throw new BuildException(
+                "zipfile attribute must not represent a directory!",
+                getLocation());
         }
 
         if (getSrcResource() == null) {
-            throw new BuildException("src attribute or nested resource is"
-                                     + " required", getLocation());
+            throw new BuildException(
+                "src attribute or nested resource is required", getLocation());
         }
     }
 
@@ -126,6 +129,7 @@
      * validate, then hand off to the subclass
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         validate();
 
@@ -177,11 +181,8 @@
      */
     protected void zipResource(Resource resource, OutputStream zOut)
         throws IOException {
-        InputStream rIn = resource.getInputStream();
-        try {
+        try (InputStream rIn = resource.getInputStream()) {
             zipFile(rIn, zOut);
-        } finally {
-            rIn.close();
         }
     }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/Parallel.java b/src/main/org/apache/tools/ant/taskdefs/Parallel.java
index 469ba41..b3d400b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Parallel.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Parallel.java
@@ -18,7 +18,6 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.util.ArrayList;
-import java.util.Enumeration;
 import java.util.List;
 import java.util.Vector;
 
@@ -56,7 +55,7 @@
     /** Class which holds a list of tasks to execute */
     public static class TaskList implements TaskContainer {
         /** Collection holding the nested tasks */
-        private List tasks = new ArrayList();
+        private List<Task> tasks = new ArrayList<>();
 
         /**
          * Add a nested task to execute parallel (asynchron).
@@ -64,13 +63,14 @@
          * @param nestedTask  Nested task to be executed in parallel.
          *                    must not be null.
          */
+        @Override
         public void addTask(Task nestedTask) {
             tasks.add(nestedTask);
         }
     }
 
     /** Collection holding the nested tasks */
-    private Vector nestedTasks = new Vector();
+    private Vector<Task> nestedTasks = new Vector<>();
 
     /** Semaphore to notify of completed threads */
     private final Object semaphore = new Object();
@@ -150,6 +150,7 @@
      * Add a nested task to execute in parallel.
      * @param nestedTask  Nested task to be executed in parallel
      */
+    @Override
     public void addTask(Task nestedTask) {
         nestedTasks.addElement(nestedTask);
     }
@@ -195,13 +196,12 @@
         this.timeout = timeout;
     }
 
-
-
     /**
      * Execute the parallel tasks
      *
      * @exception BuildException if any of the threads failed.
      */
+    @Override
     public void execute() throws BuildException {
         updateThreadCounts();
         if (numThreads == 0) {
@@ -224,8 +224,8 @@
         if (runnables == null) {
             return;
         }
-        for (int i = 0; i < runnables.length; ++i) {
-            Throwable t = runnables[i].getException();
+        for (TaskRunnable runnable : runnables) {
+            Throwable t = runnable.getException();
             if (t != null) {
                 numExceptions++;
                 if (firstException == null) {
@@ -255,28 +255,21 @@
      * @exception BuildException if any of the threads failed.
      */
     private void spinThreads() throws BuildException {
-        final int numTasks = nestedTasks.size();
-        TaskRunnable[] runnables = new TaskRunnable[numTasks];
         stillRunning = true;
         timedOut = false;
         boolean interrupted = false;
 
-        int threadNumber = 0;
-        for (Enumeration e = nestedTasks.elements(); e.hasMoreElements();
-             threadNumber++) {
-            Task nestedTask = (Task) e.nextElement();
-            runnables[threadNumber]
-                = new TaskRunnable(nestedTask);
-        }
+        TaskRunnable[] runnables = nestedTasks.stream().map(TaskRunnable::new)
+            .toArray(TaskRunnable[]::new);
 
+        final int numTasks = nestedTasks.size();
         final int maxRunning = numTasks < numThreads ? numTasks : numThreads;
-        TaskRunnable[] running = new TaskRunnable[maxRunning];
 
-        threadNumber = 0;
+        TaskRunnable[] running = new TaskRunnable[maxRunning];
         ThreadGroup group = new ThreadGroup("parallel");
 
         TaskRunnable[] daemons = null;
-        if (daemonTasks != null && daemonTasks.tasks.size() != 0) {
+        if (!(daemonTasks == null || daemonTasks.tasks.isEmpty())) {
             daemons = new TaskRunnable[daemonTasks.tasks.size()];
         }
 
@@ -292,7 +285,7 @@
             // start any daemon threads
             if (daemons != null) {
                 for (int i = 0; i < daemons.length; ++i) {
-                    daemons[i] = new TaskRunnable((Task) daemonTasks.tasks.get(i));
+                    daemons[i] = new TaskRunnable(daemonTasks.tasks.get(i));
                     Thread daemonThread =  new Thread(group, daemons[i]);
                     daemonThread.setDaemon(true);
                     daemonThread.start();
@@ -301,6 +294,7 @@
 
             // now run main threads in limited numbers...
             // start initial batch of threads
+            int threadNumber = 0;
             for (int i = 0; i < maxRunning; ++i) {
                 running[i] = runnables[threadNumber++];
                 Thread thread =  new Thread(group, running[i]);
@@ -310,6 +304,7 @@
             if (timeout != 0) {
                 // start the timeout thread
                 Thread timeoutThread = new Thread() {
+                    @Override
                     public synchronized void run() {
                         try {
                             final long start = System.currentTimeMillis();
@@ -393,17 +388,16 @@
         if (numExceptions == 1) {
             if (firstException instanceof BuildException) {
                 throw (BuildException) firstException;
-            } else {
-                throw new BuildException(firstException);
             }
-        } else if (numExceptions > 1) {
+            throw new BuildException(firstException);
+        }
+        if (numExceptions > 1) {
             if (firstExitStatus == null) {
                 throw new BuildException(exceptionMessage.toString(),
                                          firstLocation);
-            } else {
-                throw new ExitStatusException(exceptionMessage.toString(),
-                                              firstExitStatus, firstLocation);
             }
+            throw new ExitStatusException(exceptionMessage.toString(),
+                                          firstExitStatus, firstLocation);
         }
     }
 
@@ -453,6 +447,7 @@
          * Executes the task within a thread and takes care about
          * Exceptions raised within the task.
          */
+        @Override
         public void run() {
             try {
                 LocalProperties.get(getProject()).copy();
diff --git a/src/main/org/apache/tools/ant/taskdefs/Patch.java b/src/main/org/apache/tools/ant/taskdefs/Patch.java
index 96ab082..3d9d099 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Patch.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Patch.java
@@ -165,12 +165,13 @@
      * execute patch
      * @throws BuildException when it all goes a bit pear shaped
      */
+    @Override
     public void execute() throws BuildException {
         if (!havePatchfile) {
             throw new BuildException("patchfile argument is required",
                                      getLocation());
         }
-        Commandline toExecute = (Commandline) cmd.clone();
+        Commandline toExecute =  cmd.clone();
         toExecute.setExecutable(PATCH);
 
         if (originalFile != null) {
@@ -182,18 +183,14 @@
                                   null);
         exe.setCommandline(toExecute.getCommandline());
 
-        if (directory != null) {
-            if (directory.exists() && directory.isDirectory()) {
-                exe.setWorkingDirectory(directory);
-            } else if (!directory.isDirectory()) {
+        if (directory == null) {
+            exe.setWorkingDirectory(getProject().getBaseDir());
+        } else {
+            if (!directory.isDirectory()) {
                 throw new BuildException(directory + " is not a directory.",
                                          getLocation());
-            } else {
-                throw new BuildException("directory " + directory
-                                         + " doesn\'t exist", getLocation());
             }
-        } else {
-            exe.setWorkingDirectory(getProject().getBaseDir());
+            exe.setWorkingDirectory(directory);
         }
 
         log(toExecute.describeCommand(), Project.MSG_VERBOSE);
@@ -204,9 +201,8 @@
                     + returncode;
                 if (failOnError) {
                     throw new BuildException(msg);
-                } else {
-                    log(msg, Project.MSG_ERR);
                 }
+                log(msg, Project.MSG_ERR);
             }
         } catch (IOException e) {
             throw new BuildException(e, getLocation());
diff --git a/src/main/org/apache/tools/ant/taskdefs/PathConvert.java b/src/main/org/apache/tools/ant/taskdefs/PathConvert.java
index 0fc1f5b..fce5b5d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/PathConvert.java
+++ b/src/main/org/apache/tools/ant/taskdefs/PathConvert.java
@@ -19,7 +19,6 @@
 
 import java.io.File;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.StringTokenizer;
 import java.util.Vector;
@@ -81,7 +80,7 @@
     /**
      * Path prefix map
      */
-    private Vector prefixMap = new Vector();
+    private List<MapEntry> prefixMap = new Vector<>();
     /**
      * User override on path sep char
      */
@@ -97,12 +96,6 @@
     private boolean preserveDuplicates;
 
     /**
-     * Construct a new instance of the PathConvert task.
-     */
-    public PathConvert() {
-    }
-
-    /**
      * Helper class, holds the nested &lt;map&gt; values. Elements will look like
      * this: &lt;map from=&quot;d:&quot; to=&quot;/foo&quot;/&gt;
      *
@@ -142,8 +135,8 @@
          */
         public String apply(String elem) {
             if (from == null || to == null) {
-                throw new BuildException("Both 'from' and 'to' must be set "
-                     + "in a map entry");
+                throw new BuildException(
+                    "Both 'from' and 'to' must be set in a map entry");
             }
             // If we're on windows, then do the comparison ignoring case
             // and treat the two directory characters the same
@@ -213,7 +206,7 @@
      */
     public MapEntry createMap() {
         MapEntry entry = new MapEntry();
-        prefixMap.addElement(entry);
+        prefixMap.add(entry);
         return entry;
     }
 
@@ -251,7 +244,7 @@
         // validateSetup code, the same assumptions can be made as
         // with windows - that ; is the path separator
 
-        targetWindows = !targetOS.equals("unix") && !targetOS.equals("tandem");
+        targetWindows = !"unix".equals(targetOS) && !"tandem".equals(targetOS);
     }
 
     /**
@@ -293,7 +286,6 @@
         pathSep = sep;
     }
 
-
     /**
      * Set the default directory separator string;
      * defaults to current JVM {@link java.io.File#separator File.separator}.
@@ -344,8 +336,9 @@
             if (isReference()) {
                 Object o = refid.getReferencedObject(getProject());
                 if (!(o instanceof ResourceCollection)) {
-                    throw new BuildException("refid '" + refid.getRefId()
-                        + "' does not refer to a resource collection.");
+                    throw new BuildException(
+                        "refid '%s' does not refer to a resource collection.",
+                        refid.getRefId());
                 }
                 getPath().add((ResourceCollection) o);
             }
@@ -361,10 +354,10 @@
             // case-insensitive.
             String fromDirSep = onWindows ? "\\" : "/";
 
-            StringBuffer rslt = new StringBuffer();
+            StringBuilder rslt = new StringBuilder();
 
             ResourceCollection resources = isPreserveDuplicates() ? (ResourceCollection) path : new Union(path);
-            List ret = new ArrayList();
+            List<String> ret = new ArrayList<>();
             FileNameMapper mapperImpl = mapper == null ? new IdentityMapper() : mapper.getImplementation();
             for (Resource r : resources) {
                 String[] mapped = mapperImpl.mapFileName(String.valueOf(r));
@@ -373,8 +366,8 @@
                 }
             }
             boolean first = true;
-            for (Iterator mappedIter = ret.iterator(); mappedIter.hasNext();) {
-                String elem = mapElement((String) mappedIter.next()); // Apply the path prefix map
+            for (String string : ret) {
+                String elem = mapElement(string); // Apply the path prefix map
 
                 // Now convert the path and file separator characters from the
                 // current os to the target os.
@@ -418,25 +411,17 @@
      * @return String Updated element.
      */
     private String mapElement(String elem) {
+        // Iterate over the map entries and apply each one.
+        // Stop when one of the entries actually changes the element.
 
-        int size = prefixMap.size();
+        for (MapEntry entry : prefixMap) {
+            String newElem = entry.apply(elem);
 
-        if (size != 0) {
+            // Note I'm using "!=" to see if we got a new object back from
+            // the apply method.
 
-            // Iterate over the map entries and apply each one.
-            // Stop when one of the entries actually changes the element.
-
-            for (int i = 0; i < size; i++) {
-                MapEntry entry = (MapEntry) prefixMap.elementAt(i);
-                String newElem = entry.apply(elem);
-
-                // Note I'm using "!=" to see if we got a new object back from
-                // the apply method.
-
-                if (newElem != elem) {
-                    elem = newElem;
-                    break; // We applied one, so we're done
-                }
+            if (newElem != elem) {
+                return newElem;
             }
         }
         return elem;
@@ -503,9 +488,8 @@
      * @return BuildException.
      */
     private BuildException noChildrenAllowed() {
-        return new BuildException("You must not specify nested "
-             + "elements when using the refid attribute.");
+        return new BuildException(
+            "You must not specify nested elements when using the refid attribute.");
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/PreSetDef.java b/src/main/org/apache/tools/ant/taskdefs/PreSetDef.java
index fe57704..b343919 100644
--- a/src/main/org/apache/tools/ant/taskdefs/PreSetDef.java
+++ b/src/main/org/apache/tools/ant/taskdefs/PreSetDef.java
@@ -56,6 +56,7 @@
      * Add a nested task to predefine attributes and elements on.
      * @param nestedTask  Nested task/type to extend.
      */
+    @Override
     public void addTask(Task nestedTask) {
         if (this.nestedTask != null) {
             throw new BuildException("Only one nested element allowed");
@@ -71,6 +72,7 @@
     /**
      * Make a new definition.
      */
+    @Override
     public void execute() {
         if (nestedTask == null) {
             throw new BuildException("Missing nested element");
@@ -89,7 +91,7 @@
         AntTypeDefinition def = helper.getDefinition(componentName);
         if (def == null) {
             throw new BuildException(
-                "Unable to find typedef " + componentName);
+                "Unable to find typedef %s", componentName);
         }
         PreSetDefinition newDef = new PreSetDefinition(def, nestedTask);
 
@@ -129,7 +131,8 @@
          *
          * @param clazz a <code>Class</code> value.
          */
-        public void setClass(Class clazz) {
+        @Override
+        public void setClass(Class<?> clazz) {
             throw new BuildException("Not supported");
         }
 
@@ -138,6 +141,7 @@
          *
          * @param className a <code>String</code> value.
          */
+        @Override
         public void setClassName(String className) {
             throw new BuildException("Not supported");
         }
@@ -146,6 +150,7 @@
          * Get the classname of the definition.
          * @return the name of the class of this definition.
          */
+        @Override
         public String getClassName() {
             return parent.getClassName();
         }
@@ -155,7 +160,8 @@
          * NOT Supported
          * @param adapterClass the adapterClass.
          */
-        public void setAdapterClass(Class adapterClass) {
+        @Override
+        public void setAdapterClass(Class<?> adapterClass) {
             throw new BuildException("Not supported");
         }
 
@@ -164,7 +170,8 @@
          * NOT SUPPORTED
          * @param adaptToClass the assignable class.
          */
-        public void setAdaptToClass(Class adaptToClass) {
+        @Override
+        public void setAdaptToClass(Class<?> adaptToClass) {
             throw new BuildException("Not supported");
         }
 
@@ -174,6 +181,7 @@
          * NOT SUPPORTED
          * @param classLoader the classLoader.
          */
+        @Override
         public void setClassLoader(ClassLoader classLoader) {
             throw new BuildException("Not supported");
         }
@@ -182,6 +190,7 @@
          * Get the classloader for this definition.
          * @return the classloader for this definition.
          */
+        @Override
         public ClassLoader getClassLoader() {
             return parent.getClassLoader();
         }
@@ -191,7 +200,8 @@
          * @param project the current project.
          * @return the exposed class.
          */
-        public Class getExposedClass(Project project) {
+        @Override
+        public Class<?> getExposedClass(Project project) {
             return parent.getExposedClass(project);
         }
 
@@ -200,7 +210,8 @@
          * @param project the current project.
          * @return the type of the definition.
          */
-        public Class getTypeClass(Project project) {
+        @Override
+        public Class<?> getTypeClass(Project project) {
             return parent.getTypeClass(project);
         }
 
@@ -209,6 +220,7 @@
          * Check if the attributes are correct.
          * @param project the current project.
          */
+        @Override
         public void checkClass(Project project) {
             parent.checkClass(project);
         }
@@ -240,6 +252,7 @@
          * @param project the current project.
          * @return this object.
          */
+        @Override
         public Object create(Project project) {
             return this;
         }
@@ -251,6 +264,7 @@
          * @param project the current project.
          * @return true if the definitions are the same.
          */
+        @Override
         public boolean sameDefinition(AntTypeDefinition other, Project project) {
             return (other != null && other.getClass() == getClass() && parent != null
                 && parent.sameDefinition(((PreSetDefinition) other).parent, project)
@@ -264,6 +278,7 @@
          * @param project the current project.
          * @return true if the definitions are similar.
          */
+        @Override
         public boolean similarDefinition(
             AntTypeDefinition other, Project project) {
             return (other != null && other.getClass().getName().equals(
diff --git a/src/main/org/apache/tools/ant/taskdefs/ProcessDestroyer.java b/src/main/org/apache/tools/ant/taskdefs/ProcessDestroyer.java
index bc3ff49..acc69a0 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ProcessDestroyer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ProcessDestroyer.java
@@ -21,7 +21,7 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.HashSet;
-import java.util.Iterator;
+import java.util.Set;
 
 /**
  * Destroys all registered <code>Process</code>es when the VM exits.
@@ -30,7 +30,8 @@
  */
 class ProcessDestroyer implements Runnable {
     private static final int THREAD_DIE_TIMEOUT = 20000;
-    private HashSet processes = new HashSet();
+
+    private Set<Process> processes = new HashSet<>();
     // methods to register and unregister shutdown hooks
     private Method addShutdownHookMethod;
     private Method removeShutdownHookMethod;
@@ -49,6 +50,7 @@
         public ProcessDestroyerImpl() {
             super("ProcessDestroyer Shutdown Hook");
         }
+        @Override
         public void run() {
             if (shouldDestroy) {
                 ProcessDestroyer.this.run();
@@ -74,12 +76,11 @@
         try {
             // check to see if the shutdown hook methods exists
             // (support pre-JDK 1.3 and Non-Sun VMs)
-            Class[] paramTypes = {Thread.class};
             addShutdownHookMethod =
-                Runtime.class.getMethod("addShutdownHook", paramTypes);
+                Runtime.class.getMethod("addShutdownHook", Thread.class);
 
             removeShutdownHookMethod =
-                Runtime.class.getMethod("removeShutdownHook", paramTypes);
+                Runtime.class.getMethod("removeShutdownHook", Thread.class);
             // wait to add shutdown hook as needed
         } catch (NoSuchMethodException e) {
             // it just won't be added as a shutdown hook... :(
@@ -95,9 +96,8 @@
     private void addShutdownHook() {
         if (addShutdownHookMethod != null && !running) {
             destroyProcessThread = new ProcessDestroyerImpl();
-            Object[] args = {destroyProcessThread};
             try {
-                addShutdownHookMethod.invoke(Runtime.getRuntime(), args);
+                addShutdownHookMethod.invoke(Runtime.getRuntime(), destroyProcessThread);
                 added = true;
             } catch (IllegalAccessException e) {
                 e.printStackTrace(); //NOSONAR
@@ -119,13 +119,9 @@
      */
     private void removeShutdownHook() {
         if (removeShutdownHookMethod != null && added && !running) {
-            Object[] args = {destroyProcessThread};
             try {
-                Boolean removed =
-                    (Boolean) removeShutdownHookMethod.invoke(
-                        Runtime.getRuntime(),
-                        args);
-                if (!removed.booleanValue()) {
+                if (!Boolean.TRUE.equals(removeShutdownHookMethod
+                    .invoke(Runtime.getRuntime(), destroyProcessThread))) {
                     System.err.println("Could not remove shutdown hook");
                 }
             } catch (IllegalAccessException e) {
@@ -180,7 +176,7 @@
     public boolean add(Process process) {
         synchronized (processes) {
             // if this list is empty, register the shutdown hook
-            if (processes.size() == 0) {
+            if (processes.isEmpty()) {
                 addShutdownHook();
             }
             return processes.add(process);
@@ -198,7 +194,7 @@
     public boolean remove(Process process) {
         synchronized (processes) {
             boolean processRemoved = processes.remove(process);
-            if (processRemoved && processes.size() == 0) {
+            if (processRemoved && processes.isEmpty()) {
                 removeShutdownHook();
             }
             return processRemoved;
@@ -208,13 +204,11 @@
     /**
      * Invoked by the VM when it is exiting.
      */
+    @Override
     public void run() {
         synchronized (processes) {
             running = true;
-            Iterator e = processes.iterator();
-            while (e.hasNext()) {
-                ((Process) e.next()).destroy();
-            }
+            processes.forEach(Process::destroy);
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/ProjectHelperTask.java b/src/main/org/apache/tools/ant/taskdefs/ProjectHelperTask.java
index 8f348a7..726913f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ProjectHelperTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ProjectHelperTask.java
@@ -18,7 +18,6 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 import org.apache.tools.ant.BuildException;
@@ -33,7 +32,7 @@
  */
 public class ProjectHelperTask extends Task {
 
-    private List projectHelpers = new ArrayList();
+    private List<ProjectHelper> projectHelpers = new ArrayList<>();
 
     public synchronized void addConfigured(ProjectHelper projectHelper) {
         this.projectHelpers.add(projectHelper);
@@ -41,10 +40,7 @@
 
     @Override
     public void execute() throws BuildException {
-        ProjectHelperRepository repo = ProjectHelperRepository.getInstance();
-        for (Iterator it = projectHelpers.iterator(); it.hasNext();) {
-            ProjectHelper helper = (ProjectHelper) it.next();
-            repo.registerProjectHelper(helper.getClass());
-        }
+        projectHelpers.stream().map(ProjectHelper::getClass).forEach(
+            ProjectHelperRepository.getInstance()::registerProjectHelper);
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Property.java b/src/main/org/apache/tools/ant/taskdefs/Property.java
index 64a6376..6982064 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Property.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Property.java
@@ -18,12 +18,11 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.nio.file.Files;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Properties;
 
@@ -218,9 +217,8 @@
                 msg = currentValue + msg;
             }
             internalSetValue(msg);
-        } else if (msg.trim().length() > 0) {
-            throw new BuildException("can't combine nested text with value"
-                                     + " attribute");
+        } else if (!msg.trim().isEmpty()) {
+            throw new BuildException("can't combine nested text with value attribute");
         }
     }
 
@@ -464,27 +462,31 @@
 
         if (name != null) {
             if (untypedValue == null && ref == null) {
-                throw new BuildException("You must specify value, location or "
-                                         + "refid with the name attribute",
-                                         getLocation());
+                throw new BuildException(
+                    "You must specify value, location or refid with the name attribute",
+                    getLocation());
             }
         } else {
-            if (url == null && file == null && resource == null && env == null) {
-                throw new BuildException("You must specify url, file, resource or "
-                                         + "environment when not using the "
-                                         + "name attribute", getLocation());
+            if (url == null && file == null && resource == null
+                && env == null) {
+                throw new BuildException(
+                    "You must specify url, file, resource or environment when not using the name attribute",
+                    getLocation());
             }
         }
 
         if (url == null && file == null && resource == null && prefix != null) {
-            throw new BuildException("Prefix is only valid when loading from "
-                                     + "a url, file or resource", getLocation());
+            throw new BuildException(
+                "Prefix is only valid when loading from a url, file or resource",
+                getLocation());
         }
 
         if (name != null && untypedValue != null) {
             if (relative) {
                 try {
-                    File from = untypedValue instanceof File ? (File)untypedValue : new File(untypedValue.toString());
+                    File from =
+                        untypedValue instanceof File ? (File) untypedValue
+                            : new File(untypedValue.toString());
                     File to = basedir != null ? basedir : getProject().getBaseDir();
                     String relPath = FileUtils.getRelativePath(to, from);
                     relPath = relPath.replace('/', File.separatorChar);
@@ -537,13 +539,8 @@
         Properties props = new Properties();
         log("Loading " + url, Project.MSG_VERBOSE);
         try {
-            InputStream is = url.openStream();
-            try {
+            try (InputStream is = url.openStream()) {
                 loadProperties(props, is, url.getFile().endsWith(".xml"));
-            } finally {
-                if (is != null) {
-                    is.close();
-                }
             }
             addProperties(props);
         } catch (IOException ex) {
@@ -584,12 +581,8 @@
         log("Loading " + file.getAbsolutePath(), Project.MSG_VERBOSE);
         try {
             if (file.exists()) {
-                FileInputStream  fis = null;
-                try {
-                    fis = new FileInputStream(file);
+                try (InputStream fis = Files.newInputStream(file.toPath())) {
                     loadProperties(props, fis, file.getName().endsWith(".xml"));
-                } finally {
-                    FileUtils.close(fis);
                 }
                 addProperties(props);
             } else {
@@ -608,17 +601,16 @@
     protected void loadResource(String name) {
         Properties props = new Properties();
         log("Resource Loading " + name, Project.MSG_VERBOSE);
-        InputStream is = null;
         ClassLoader cL = null;
         boolean cleanup = false;
+        if (classpath != null) {
+            cleanup = true;
+            cL = getProject().createClassLoader(classpath);
+        } else {
+            cL = this.getClass().getClassLoader();
+        }
+        InputStream is = null;
         try {
-            if (classpath != null) {
-                cleanup = true;
-                cL = getProject().createClassLoader(classpath);
-            } else {
-                cL = this.getClass().getClassLoader();
-            }
-
             if (cL == null) {
                 is = ClassLoader.getSystemResourceAsStream(name);
             } else {
@@ -651,9 +643,8 @@
             prefix += ".";
         }
         log("Loading Environment " + prefix, Project.MSG_VERBOSE);
-        Map osEnv = Execute.getEnvironmentVariables();
-        for (Iterator e = osEnv.entrySet().iterator(); e.hasNext();) {
-            Map.Entry entry = (Map.Entry) e.next();
+        Map<String, String> osEnv = Execute.getEnvironmentVariables();
+        for (Map.Entry<String, String> entry : osEnv.entrySet()) {
             props.put(prefix + entry.getKey(), entry.getValue());
         }
         addProperties(props);
@@ -665,18 +656,17 @@
      * @param props the properties to iterate over
      */
     protected void addProperties(Properties props) {
-        HashMap m = new HashMap(props);
-        resolveAllProperties(m);
-        for (Iterator it = m.keySet().iterator(); it.hasNext();) {
-            Object k = it.next();
+        Map<String, Object> m = new HashMap<>();
+        props.forEach((k, v) -> {
             if (k instanceof String) {
-                String propertyName = (String) k;
-                if (prefix != null) {
-                    propertyName = prefix + propertyName;
-                }
-                addProperty(propertyName, m.get(k));
+                m.put((String) k, v);
             }
-        }
+        });
+        resolveAllProperties(m);
+        m.forEach((k, v) -> {
+            String propertyName = prefix == null ? k : prefix + k;
+            addProperty(propertyName, v);
+        });
     }
 
     /**
@@ -711,7 +701,7 @@
      * resolve properties inside a properties hashtable
      * @param props properties object to resolve
      */
-    private void resolveAllProperties(Map props) throws BuildException {
+    private void resolveAllProperties(Map<String, Object> props) throws BuildException {
         PropertyHelper propertyHelper
             = PropertyHelper.getPropertyHelper(getProject());
         new ResolvePropertyMap(
diff --git a/src/main/org/apache/tools/ant/taskdefs/PropertyHelperTask.java b/src/main/org/apache/tools/ant/taskdefs/PropertyHelperTask.java
index 5e8867a..5017fc3 100644
--- a/src/main/org/apache/tools/ant/taskdefs/PropertyHelperTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/PropertyHelperTask.java
@@ -18,7 +18,6 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 import org.apache.tools.ant.BuildException;
@@ -69,7 +68,7 @@
     }
 
     private PropertyHelper propertyHelper;
-    private List delegates;
+    private List<Object> delegates;
 
     /**
      * Add a new PropertyHelper to be set on the Project.
@@ -104,13 +103,14 @@
      * Execute the task.
      * @throws BuildException on error.
      */
+    @Override
     public void execute() throws BuildException {
         if (getProject() == null) {
             throw new BuildException("Project instance not set");
         }
         if (propertyHelper == null && delegates == null) {
-            throw new BuildException("Either a new PropertyHelper"
-                    + " or one or more PropertyHelper delegates are required");
+            throw new BuildException(
+                "Either a new PropertyHelper or one or more PropertyHelper delegates are required");
         }
         PropertyHelper ph = propertyHelper;
         if (ph == null) {
@@ -120,8 +120,7 @@
         }
         synchronized (ph) {
             if (delegates != null) {
-                for (Iterator iter = delegates.iterator(); iter.hasNext();) {
-                    Object o = iter.next();
+                for (Object o : delegates) {
                     PropertyHelper.Delegate delegate = o instanceof DelegateElement
                             ? ((DelegateElement) o).resolve() : (PropertyHelper.Delegate) o;
                     log("Adding PropertyHelper delegate " + delegate, Project.MSG_DEBUG);
@@ -136,9 +135,9 @@
         }
     }
 
-    private synchronized List getAddDelegateList() {
+    private synchronized List<Object> getAddDelegateList() {
         if (delegates == null) {
-            delegates = new ArrayList();
+            delegates = new ArrayList<>();
         }
         return delegates;
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/RecorderEntry.java b/src/main/org/apache/tools/ant/taskdefs/RecorderEntry.java
index adbb265..de9ac0f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/RecorderEntry.java
+++ b/src/main/org/apache/tools/ant/taskdefs/RecorderEntry.java
@@ -17,9 +17,9 @@
  */
 package org.apache.tools.ant.taskdefs;
 
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintStream;
+import java.nio.file.Paths;
 
 import org.apache.tools.ant.BuildEvent;
 import org.apache.tools.ant.BuildException;
@@ -27,6 +27,7 @@
 import org.apache.tools.ant.DefaultLogger;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.SubBuildListener;
+import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.StringUtils;
 
 /**
@@ -357,7 +358,7 @@
     private void openFileImpl(boolean append) throws BuildException {
         if (out == null) {
             try {
-                out = new PrintStream(new FileOutputStream(filename, append));
+                out = new PrintStream(FileUtils.newOutputStream(Paths.get(filename), append));
             } catch (IOException ioe) {
                 throw new BuildException("Problems opening file using a "
                                          + "recorder entry", ioe);
diff --git a/src/main/org/apache/tools/ant/taskdefs/Replace.java b/src/main/org/apache/tools/ant/taskdefs/Replace.java
index 6ea6f65..c8a178d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Replace.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Replace.java
@@ -21,8 +21,6 @@
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -30,11 +28,13 @@
 import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.io.Writer;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Objects;
 import java.util.Properties;
 
 import org.apache.tools.ant.BuildException;
@@ -70,7 +70,7 @@
     private Resource propertyResource = null;
     private Resource replaceFilterResource = null;
     private Properties properties = null;
-    private ArrayList replacefilters = new ArrayList();
+    private List<Replacefilter> replacefilters = new ArrayList<>();
 
     private File dir = null;
 
@@ -146,39 +146,34 @@
         public void validate() throws BuildException {
             //Validate mandatory attributes
             if (token == null) {
-                String message = "token is a mandatory for replacefilter.";
-                throw new BuildException(message);
+                throw new BuildException(
+                    "token is a mandatory for replacefilter.");
             }
 
             if ("".equals(token.getText())) {
-                String message = "The token must not be an empty "
-                    + "string.";
-                throw new BuildException(message);
+                throw new BuildException(
+                    "The token must not be an empty string.");
             }
 
             //value and property are mutually exclusive attributes
             if ((value != null) && (property != null)) {
-                String message = "Either value or property "
-                    + "can be specified, but a replacefilter "
-                    + "element cannot have both.";
-                throw new BuildException(message);
+                throw new BuildException(
+                    "Either value or property can be specified, but a replacefilter element cannot have both.");
             }
 
             if ((property != null)) {
                 //the property attribute must have access to a property file
                 if (propertyResource == null) {
-                    String message = "The replacefilter's property attribute "
-                        + "can only be used with the replacetask's "
-                        + "propertyFile/Resource attribute.";
-                    throw new BuildException(message);
+                    throw new BuildException(
+                        "The replacefilter's property attribute can only be used with the replacetask's propertyFile/Resource attribute.");
                 }
 
                 //Make sure property exists in property file
                 if (properties == null
                     || properties.getProperty(property) == null) {
-                    String message = "property \"" + property
-                        + "\" was not found in " + propertyResource.getName();
-                    throw new BuildException(message);
+                    throw new BuildException(
+                        "property \"%s\" was not found in %s", property,
+                        propertyResource.getName());
                 }
             }
 
@@ -192,14 +187,15 @@
         public String getReplaceValue() {
             if (property != null) {
                 return properties.getProperty(property);
-            } else if (value != null) {
-                return value.getText();
-            } else if (Replace.this.value != null) {
-                return Replace.this.value.getText();
-            } else {
-                //Default is empty string
-                return "";
             }
+            if (value != null) {
+                return value.getText();
+            }
+            if (Replace.this.value != null) {
+                return Replace.this.value.getText();
+            }
+            //Default is empty string
+            return "";
         }
 
         /**
@@ -355,12 +351,13 @@
      * a StringBuffer. Compatible with the Replacefilter.
      * @since 1.7
      */
-    private class FileInput /* JDK 5: implements Closeable */ {
+    private class FileInput implements AutoCloseable {
+        private static final int BUFF_SIZE = 4096;
+
         private StringBuffer outputBuffer;
         private final InputStream is;
         private Reader reader;
         private char[] buffer;
-        private static final int BUFF_SIZE = 4096;
 
         /**
          * Constructs the input component. Opens the file for reading.
@@ -370,9 +367,11 @@
         FileInput(File source) throws IOException {
             outputBuffer = new StringBuffer();
             buffer = new char[BUFF_SIZE];
-            is = new FileInputStream(source);
+            is = Files.newInputStream(source.toPath());
             try {
-                reader = new BufferedReader(encoding != null ? new InputStreamReader(is, encoding) : new InputStreamReader(is));
+                reader = new BufferedReader(
+                    encoding != null ? new InputStreamReader(is, encoding)
+                        : new InputStreamReader(is));
             } finally {
                 if (reader == null) {
                     is.close();
@@ -395,8 +394,7 @@
          * @throws IOException When the file cannot be read from.
          */
         boolean readChunk() throws IOException {
-            int bufferLength = 0;
-            bufferLength = reader.read(buffer);
+            int bufferLength = reader.read(buffer);
             if (bufferLength < 0) {
                 return false;
             }
@@ -408,6 +406,7 @@
          * Closes the file.
          * @throws IOException When the file cannot be closed.
          */
+        @Override
         public void close() throws IOException {
             is.close();
         }
@@ -419,7 +418,7 @@
      * Replacefilter.
      * @since 1.7
      */
-    private class FileOutput /* JDK 5: implements Closeable */ {
+    private class FileOutput implements AutoCloseable {
         private StringBuffer inputBuffer;
         private final OutputStream os;
         private Writer writer;
@@ -430,9 +429,11 @@
          * @throws IOException When the file cannot be read from.
          */
         FileOutput(File out) throws IOException {
-            os = new FileOutputStream(out);
+            os = Files.newOutputStream(out.toPath());
             try {
-                writer = new BufferedWriter(encoding != null ? new OutputStreamWriter(os, encoding) : new OutputStreamWriter(os));
+                writer = new BufferedWriter(
+                    encoding != null ? new OutputStreamWriter(os, encoding)
+                        : new OutputStreamWriter(os));
             } finally {
                 if (writer == null) {
                     os.close();
@@ -478,6 +479,7 @@
          * Closes the file.
          * @throws IOException When the file cannot be closed.
          */
+        @Override
         public void close() throws IOException {
             os.close();
         }
@@ -488,9 +490,9 @@
      * Do the execution.
      * @throws BuildException if we can't build
      */
+    @Override
     public void execute() throws BuildException {
-
-        ArrayList savedFilters = (ArrayList) replacefilters.clone();
+        List<Replacefilter> savedFilters = new ArrayList<>(replacefilters);
         Properties savedProperties =
             properties == null ? null : (Properties) properties.clone();
 
@@ -498,10 +500,10 @@
             // line separators in values and tokens are "\n"
             // in order to compare with the file contents, replace them
             // as needed
-            StringBuffer val = new StringBuffer(value.getText());
+            StringBuilder val = new StringBuilder(value.getText());
             stringReplace(val, "\r\n", "\n");
             stringReplace(val, "\n", StringUtils.LINE_SEP);
-            StringBuffer tok = new StringBuffer(token.getText());
+            StringBuilder tok = new StringBuilder(token.getText());
             stringReplace(tok, "\r\n", "\n");
             stringReplace(tok, "\n", StringUtils.LINE_SEP);
             Replacefilter firstFilter = createPrimaryfilter();
@@ -512,7 +514,7 @@
         try {
             if (replaceFilterResource != null) {
                 Properties props = getProperties(replaceFilterResource);
-                Iterator e = getOrderedIterator(props);
+                Iterator<Object> e = getOrderedIterator(props);
                 while (e.hasNext()) {
                     String tok = e.next().toString();
                     Replacefilter replaceFilter = createReplacefilter();
@@ -537,19 +539,15 @@
 
             if (dir != null) {
                 DirectoryScanner ds = super.getDirectoryScanner(dir);
-                String[] srcs = ds.getIncludedFiles();
-
-                for (int i = 0; i < srcs.length; i++) {
-                    File file = new File(dir, srcs[i]);
+                for (String src : ds.getIncludedFiles()) {
+                    File file = new File(dir, src);
                     processFile(file);
                 }
             }
 
             if (resources != null) {
                 for (Resource r : resources) {
-                    FileProvider fp =
-                    r.as(FileProvider.class);
-                    processFile(fp.getFile());
+                    processFile(r.as(FileProvider.class).getFile());
                 }
             }
 
@@ -575,23 +573,24 @@
      */
     public void validateAttributes() throws BuildException {
         if (sourceFile == null && dir == null && resources == null) {
-            String message = "Either the file or the dir attribute "
-                + "or nested resources must be specified";
-            throw new BuildException(message, getLocation());
+            throw new BuildException(
+                "Either the file or the dir attribute or nested resources must be specified",
+                getLocation());
         }
         if (propertyResource != null && !propertyResource.isExists()) {
-            String message = "Property file " + propertyResource.getName()
-                + " does not exist.";
-            throw new BuildException(message, getLocation());
+            throw new BuildException("Property file "
+                + propertyResource.getName() + " does not exist.",
+                getLocation());
         }
-        if (token == null && replacefilters.size() == 0) {
-            String message = "Either token or a nested replacefilter "
-                + "must be specified";
-            throw new BuildException(message, getLocation());
+        if (token == null && replacefilters.isEmpty()) {
+            throw new BuildException(
+                "Either token or a nested replacefilter must be specified",
+                getLocation());
         }
         if (token != null && "".equals(token.getText())) {
-            String message = "The token attribute must not be an empty string.";
-            throw new BuildException(message, getLocation());
+            throw new BuildException(
+                "The token attribute must not be an empty string.",
+                getLocation());
         }
     }
 
@@ -603,12 +602,7 @@
      */
     public void validateReplacefilters()
             throws BuildException {
-        final int size = replacefilters.size();
-        for (int i = 0; i < size; i++) {
-            Replacefilter element =
-                (Replacefilter) replacefilters.get(i);
-            element.validate();
-        }
+        replacefilters.forEach(Replacefilter::validate);
     }
 
     /**
@@ -632,18 +626,14 @@
         throws BuildException {
         Properties props = new Properties();
 
-        InputStream in = null;
-        try {
-            in = propertyResource.getInputStream();
+        try (
+            InputStream
+            in = propertyResource.getInputStream()){
             props.load(in);
         } catch (IOException e) {
-            String message = "Property resource (" + propertyResource.getName()
-                + ") cannot be loaded.";
-            throw new BuildException(message);
-        } finally {
-            FileUtils.close(in);
+            throw new BuildException("Property resource (%s) cannot be loaded.",
+                propertyResource.getName());
         }
-
         return props;
     }
 
@@ -668,26 +658,19 @@
             File temp = FILE_UTILS.createTempFile("rep", ".tmp",
                     src.getParentFile(), false, true);
             try {
-                FileInput in = new FileInput(src);
-                try {
-                    FileOutput out = new FileOutput(temp);
-                    try {
-                        out.setInputBuffer(buildFilterChain(in.getOutputBuffer()));
+                try (FileInput in = new FileInput(src);
+                     FileOutput out = new FileOutput(temp)) {
+                    out.setInputBuffer(buildFilterChain(in.getOutputBuffer()));
 
-                        while (in.readChunk()) {
-                            if (processFilterChain()) {
-                                out.process();
-                            }
+                    while (in.readChunk()) {
+                        if (processFilterChain()) {
+                            out.process();
                         }
-
-                        flushFilterChain();
-
-                        out.flush();
-                    } finally {
-                        out.close();
                     }
-                } finally {
-                    in.close();
+
+                    flushFilterChain();
+
+                    out.flush();
                 }
                 boolean changes = (replaceCount != repCountStart);
                 if (changes) {
@@ -714,11 +697,7 @@
      * Flushes all filters.
      */
     private void flushFilterChain() {
-        final int size = replacefilters.size();
-        for (int i = 0; i < size; i++) {
-            Replacefilter filter = (Replacefilter) replacefilters.get(i);
-            filter.flush();
-        }
+        replacefilters.forEach(Replacefilter::flush);
     }
 
     /**
@@ -726,14 +705,7 @@
      * @return true if the filter chain produced new output.
      */
     private boolean processFilterChain() {
-        final int size = replacefilters.size();
-        for (int i = 0; i < size; i++) {
-            Replacefilter filter = (Replacefilter) replacefilters.get(i);
-            if (!filter.process()) {
-                return false;
-            }
-        }
-        return true;
+        return replacefilters.stream().allMatch(Replacefilter::process);
     }
 
     /**
@@ -746,7 +718,7 @@
         StringBuffer buf = inputBuffer;
         final int size = replacefilters.size();
         for (int i = 0; i < size; i++) {
-            Replacefilter filter = (Replacefilter) replacefilters.get(i);
+            Replacefilter filter = replacefilters.get(i);
             filter.setInputBuffer(buf);
             buf = filter.getOutputBuffer();
         }
@@ -758,13 +730,14 @@
      * @param filename <code>String</code>.
      */
     private void logFilterChain(String filename) {
-        final int size = replacefilters.size();
-        for (int i = 0; i < size; i++) {
-            Replacefilter filter = (Replacefilter) replacefilters.get(i);
-            log("Replacing in " + filename + ": " + filter.getToken()
-                    + " --> " + filter.getReplaceValue(), Project.MSG_VERBOSE);
-        }
+        replacefilters
+            .forEach(
+                filter -> log(
+                    "Replacing in " + filename + ": " + filter.getToken()
+                        + " --> " + filter.getReplaceValue(),
+                    Project.MSG_VERBOSE));
     }
+
     /**
      * Set the source file; required unless <code>dir</code> is set.
      * @param file source <code>File</code>.
@@ -953,7 +926,7 @@
      * @param str1 String
      * @param str2 String
      */
-    private void stringReplace(StringBuffer str, String str1, String str2) {
+    private void stringReplace(StringBuilder str, String str1, String str2) {
         int found = str.indexOf(str1);
         final int str1Length = str1.length();
         final int str2Length = str2.length();
@@ -970,17 +943,9 @@
      * @param props Properties
      */
     private Iterator<Object> getOrderedIterator(Properties props) {
-        List<Object> keys = new ArrayList<Object>(props.keySet());
-        Collections.sort(keys, new Comparator<Object>() {
-                //Override annotation is not supported as long as we want to support building Ant on Java 1.5
-                public int compare(Object key1, Object key2) {
-                    return compare(key1.toString(), key2.toString());
-                }
-
-                private int compare(String key1, String key2) {
-                    return key2.length() - key1.length();
-                }
-            });
+        List<Object> keys = new ArrayList<>(props.keySet());
+        Collections.sort(keys, Comparator
+            .comparingInt(o -> Objects.toString(o, "").length()).reversed());
         return keys.iterator();
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/ResourceCount.java b/src/main/org/apache/tools/ant/taskdefs/ResourceCount.java
index b29b57b..68a630a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ResourceCount.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ResourceCount.java
@@ -61,8 +61,8 @@
     public void setRefid(Reference r) {
         Object o = r.getReferencedObject();
         if (!(o instanceof ResourceCollection)) {
-            throw new BuildException(r.getRefId()
-                + " doesn\'t denote a ResourceCollection");
+            throw new BuildException("%s doesn\'t denote a ResourceCollection",
+                r.getRefId());
         }
         add((ResourceCollection) o);
     }
@@ -70,6 +70,7 @@
     /**
      * Execute as a Task.
      */
+    @Override
     public void execute() {
         if (rc == null) {
             throw new BuildException(ONE_NESTED_MESSAGE);
@@ -86,6 +87,7 @@
      * @return true if the specified ResourceCollection satisfies the set criteria.
      * @throws BuildException if an error occurs.
      */
+    @Override
     public boolean eval() {
         if (rc == null) {
             throw new BuildException(ONE_NESTED_MESSAGE);
@@ -93,7 +95,7 @@
         if (count == null) {
             throw new BuildException(COUNT_REQUIRED);
         }
-        return when.evaluate(new Integer(rc.size()).compareTo(count));
+        return when.evaluate(Integer.valueOf(rc.size()).compareTo(count));
     }
 
     /**
@@ -101,7 +103,7 @@
      * @param c number of Resources as int.
      */
     public void setCount(int c) {
-        count = new Integer(c);
+        count = Integer.valueOf(c);
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/taskdefs/Retry.java b/src/main/org/apache/tools/ant/taskdefs/Retry.java
index bca5c15..564d80e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Retry.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Retry.java
@@ -48,11 +48,11 @@
      * set the task
      * @param t the task to retry.
      */
+    @Override
     public synchronized void addTask(Task t) {
         if (nestedTask != null) {
             throw new BuildException(
-                "The retry task container accepts a single nested task"
-                + " (which may be a sequential task container)");
+                "The retry task container accepts a single nested task (which may be a sequential task container)");
         }
         nestedTask = t;
     }
@@ -81,8 +81,9 @@
      * perform the work
      * @throws BuildException if there is an error.
      */
+    @Override
     public void execute() throws BuildException {
-        StringBuffer errorMessages = new StringBuffer();
+        StringBuilder errorMessages = new StringBuilder();
         for (int i = 0; i <= retryCount; i++) {
             try {
                 nestedTask.perform();
@@ -90,7 +91,7 @@
             } catch (Exception e) {
                 errorMessages.append(e.getMessage());
                 if (i >= retryCount) {
-                    StringBuffer exceptionMessage = new StringBuffer();
+                    StringBuilder exceptionMessage = new StringBuilder();
                     exceptionMessage.append("Task [").append(nestedTask.getTaskName());
                     exceptionMessage.append("] failed after [").append(retryCount);
                     exceptionMessage.append("] attempts; giving up.").append(StringUtils.LINE_SEP);
diff --git a/src/main/org/apache/tools/ant/taskdefs/Rmic.java b/src/main/org/apache/tools/ant/taskdefs/Rmic.java
index d72c39e..c42ad41 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Rmic.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Rmic.java
@@ -21,6 +21,7 @@
 import java.io.IOException;
 import java.rmi.Remote;
 import java.util.Vector;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.AntClassLoader;
 import org.apache.tools.ant.BuildException;
@@ -91,6 +92,23 @@
     public static final String ERROR_RMIC_FAILED
         = "Rmic failed; see the compiler error output for details.";
 
+    /** unable to verify message */
+    public static final String ERROR_UNABLE_TO_VERIFY_CLASS = "Unable to verify class ";
+    /** could not be found message */
+    public static final String ERROR_NOT_FOUND = ". It could not be found.";
+    /** not defined message */
+    public static final String ERROR_NOT_DEFINED = ". It is not defined.";
+    /** loaded error message */
+    public static final String ERROR_LOADING_CAUSED_EXCEPTION = ". Loading caused Exception: ";
+    /** base not exists message */
+    public static final String ERROR_NO_BASE_EXISTS = "base or destdir does not exist: ";
+    /** base not a directory message */
+    public static final String ERROR_NOT_A_DIR = "base or destdir is not a directory:";
+    /** base attribute not set message */
+    public static final String ERROR_BASE_NOT_SET = "base or destdir attribute must be set!";
+
+    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
     private File baseDir;
     private File destDir;
     private String classname;
@@ -109,28 +127,11 @@
     private boolean includeAntRuntime = true;
     private boolean includeJavaRuntime = false;
 
-    private Vector compileList = new Vector();
+    private Vector<String> compileList = new Vector<>();
 
     private AntClassLoader loader = null;
 
     private FacadeTaskHelper facade;
-    /** unable to verify message */
-    public static final String ERROR_UNABLE_TO_VERIFY_CLASS = "Unable to verify class ";
-    /** could not be found message */
-    public static final String ERROR_NOT_FOUND = ". It could not be found.";
-    /** not defined message */
-    public static final String ERROR_NOT_DEFINED = ". It is not defined.";
-    /** loaded error message */
-    public static final String ERROR_LOADING_CAUSED_EXCEPTION = ". Loading caused Exception: ";
-    /** base not exists message */
-    public static final String ERROR_NO_BASE_EXISTS = "base or destdir does not exist: ";
-    /** base not a directory message */
-    public static final String ERROR_NOT_A_DIR = "base or destdir is not a directory:";
-    /** base attribute not set message */
-    public static final String ERROR_BASE_NOT_SET = "base or destdir attribute must be set!";
-
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-
     private String executable = null;
 
     private boolean listFiles = false;
@@ -405,7 +406,7 @@
      * Gets file list to compile.
      * @return the list of files to compile.
      */
-    public Vector getFileList() {
+    public Vector<String> getFileList() {
         return compileList;
     }
 
@@ -484,7 +485,7 @@
     /**
      * @return the compile list.
      */
-    public Vector getCompileList() {
+    public Vector<String> getCompileList() {
         return compileList;
     }
 
@@ -496,7 +497,7 @@
      * @since Ant 1.5
      */
     public void setCompiler(String compiler) {
-        if (compiler.length() > 0) {
+        if (!compiler.isEmpty()) {
             facade.setImplementation(compiler);
         }
     }
@@ -651,9 +652,7 @@
                     + outputDir, Project.MSG_INFO);
 
                 if (listFiles) {
-                    for (int i = 0; i < fileCount; i++) {
-                        log(compileList.get(i).toString());
-                    }
+                    compileList.forEach(this::log);
                 }
 
                 // finally, lets execute the compiler!!
@@ -674,11 +673,8 @@
                     log("sourcebase attribute will be ignored.",
                         Project.MSG_WARN);
                 } else {
-                    for (int j = 0; j < fileCount; j++) {
-                        moveGeneratedFile(outputDir, sourceBase,
-                                          (String) compileList.elementAt(j),
-                                          adapter);
-                    }
+                    compileList.forEach(f -> moveGeneratedFile(outputDir,
+                        sourceBase, f, adapter));
                 }
             }
         } finally {
@@ -710,16 +706,14 @@
             + ".class";
         String[] generatedFiles = adapter.getMapper().mapFileName(classFileName);
 
-        for (int i = 0; i < generatedFiles.length; i++) {
-            final String generatedFile = generatedFiles[i];
+        for (String generatedFile : generatedFiles) {
             if (!generatedFile.endsWith(".class")) {
                 // don't know how to handle that - a IDL file doesn't
                 // have a corresponding Java source for example.
                 continue;
             }
-            String sourceFileName = StringUtils.removeSuffix(generatedFile,
-                                                             ".class")
-                + ".java";
+            String sourceFileName =
+                StringUtils.removeSuffix(generatedFile, ".class") + ".java";
 
             File oldFile = new File(baseDir, sourceFileName);
             if (!oldFile.exists()) {
@@ -738,10 +732,9 @@
                 }
                 oldFile.delete();
             } catch (IOException ioe) {
-                String msg = "Failed to copy " + oldFile + " to " + newFile
-                    + " due to "
-                    + ioe.getMessage();
-                throw new BuildException(msg, ioe, getLocation());
+                throw new BuildException("Failed to copy " + oldFile + " to "
+                    + newFile + " due to " + ioe.getMessage(), ioe,
+                    getLocation());
             }
         }
     }
@@ -765,11 +758,9 @@
             SourceFileScanner sfs = new SourceFileScanner(this);
             newFiles = sfs.restrict(files, baseDir, getOutputDir(), mapper);
         }
-        for (int i = 0; i < newFiles.length; i++) {
-            String name = newFiles[i].replace(File.separatorChar, '.');
-            name = name.substring(0, name.lastIndexOf(".class"));
-            compileList.addElement(name);
-        }
+        Stream.of(newFiles).map(s -> s.replace(File.separatorChar, '.'))
+            .map(s -> s.substring(0, s.lastIndexOf(".class")))
+            .forEach(compileList::add);
     }
 
     /**
@@ -779,7 +770,7 @@
      */
     public boolean isValidRmiRemote(String classname) {
         try {
-            Class testClass = loader.loadClass(classname);
+            Class<?> testClass = loader.loadClass(classname);
             // One cannot RMIC an interface for "classic" RMI (JRMP)
             if (testClass.isInterface() && !iiop && !idl) {
                 return false;
@@ -807,26 +798,17 @@
      * @return the topmost interface that extends Remote, or null if there
      *         is none.
      */
-    public Class getRemoteInterface(Class testClass) {
-        if (Remote.class.isAssignableFrom(testClass)) {
-            Class [] interfaces = testClass.getInterfaces();
-            if (interfaces != null) {
-                for (int i = 0; i < interfaces.length; i++) {
-                    if (Remote.class.isAssignableFrom(interfaces[i])) {
-                        return interfaces[i];
-                    }
-                }
-            }
-        }
-        return null;
+    public Class<?> getRemoteInterface(Class<?> testClass) {
+        return Stream.of(testClass.getInterfaces())
+            .filter(Remote.class::isAssignableFrom).findFirst().orElse(null);
     }
 
     /**
      * Check to see if the class or (super)interfaces implement
      * java.rmi.Remote.
      */
-    private boolean isValidRmiRemote (Class testClass) {
-        return getRemoteInterface(testClass) != null;
+    private boolean isValidRmiRemote(Class<?> testClass) {
+        return Remote.class.isAssignableFrom(testClass);
     }
 
     /**
@@ -843,7 +825,7 @@
      * implementation.
      */
     public class ImplementationSpecificArgument extends
-                                                    org.apache.tools.ant.util.facade.ImplementationSpecificArgument {
+        org.apache.tools.ant.util.facade.ImplementationSpecificArgument {
         /**
          * Only pass the specified argument if the
          * chosen compiler implementation matches the
diff --git a/src/main/org/apache/tools/ant/taskdefs/SQLExec.java b/src/main/org/apache/tools/ant/taskdefs/SQLExec.java
index e801ac0..83383c2 100644
--- a/src/main/org/apache/tools/ant/taskdefs/SQLExec.java
+++ b/src/main/org/apache/tools/ant/taskdefs/SQLExec.java
@@ -20,14 +20,13 @@
 import java.io.BufferedOutputStream;
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintStream;
 import java.io.Reader;
 import java.io.StringReader;
+import java.nio.charset.Charset;
 import java.sql.Blob;
 import java.sql.Connection;
 import java.sql.ResultSet;
@@ -36,7 +35,7 @@
 import java.sql.SQLWarning;
 import java.sql.Statement;
 import java.sql.Types;
-import java.util.Enumeration;
+import java.util.List;
 import java.util.Locale;
 import java.util.StringTokenizer;
 import java.util.Vector;
@@ -128,7 +127,7 @@
     /**
      * SQL transactions to perform
      */
-    private Vector transactions = new Vector();
+    private List<Transaction> transactions = new Vector<>();
 
     /**
      * SQL Statement delimiter
@@ -352,7 +351,7 @@
      */
     public Transaction createTransaction() {
         Transaction t = new Transaction();
-        transactions.addElement(t);
+        transactions.add(t);
         return t;
     }
 
@@ -562,8 +561,8 @@
      */
     public void setCsvQuoteCharacter(String s) {
         if (s != null && s.length() > 1) {
-            throw new BuildException("The quote character must be a single"
-                                     + " character.");
+            throw new BuildException(
+                "The quote character must be a single character.");
         }
         csvQuoteChar = s;
     }
@@ -614,17 +613,17 @@
      */
     @Override
     public void execute() throws BuildException {
-        Vector savedTransaction = (Vector) transactions.clone();
+        List<Transaction> savedTransaction = new Vector<>(transactions);
         String savedSqlCommand = sqlCommand;
 
         sqlCommand = sqlCommand.trim();
 
         try {
-            if (srcFile == null && sqlCommand.length() == 0 && resources == null) {
-                if (transactions.size() == 0) {
-                    throw new BuildException("Source file or resource collection, "
-                                             + "transactions or sql statement "
-                                             + "must be set!", getLocation());
+            if (srcFile == null && sqlCommand.isEmpty() && resources == null) {
+                if (transactions.isEmpty()) {
+                    throw new BuildException(
+                        "Source file or resource collection, transactions or sql statement must be set!",
+                        getLocation());
                 }
             }
 
@@ -661,7 +660,7 @@
                         FileProvider fp =
                             output.as(FileProvider.class);
                         if (fp != null) {
-                            os = new FileOutputStream(fp.getFile(), append);
+                            os = FileUtils.newOutputStream(fp.getFile().toPath(), append);
                         } else {
                             if (append) {
                                 Appendable a =
@@ -688,10 +687,8 @@
                     }
 
                     // Process all transactions
-                    for (Enumeration e = transactions.elements();
-                         e.hasMoreElements();) {
-
-                        ((Transaction) e.nextElement()).runTransaction(out);
+                    for (Transaction txn : transactions) {
+                        txn.runTransaction(out);
                         if (!isAutocommit()) {
                             log("Committing transaction", Project.MSG_VERBOSE);
                             getConnection().commit();
@@ -700,33 +697,19 @@
                 } finally {
                     FileUtils.close(out);
                 }
-            } catch (IOException e) {
+            } catch (IOException | SQLException e) {
                 closeQuietly();
                 setErrorProperty();
-                if (onError.equals("abort")) {
-                    throw new BuildException(e, getLocation());
-                }
-            } catch (SQLException e) {
-                closeQuietly();
-                setErrorProperty();
-                if (onError.equals("abort")) {
+                if ("abort".equals(onError)) {
                     throw new BuildException(e, getLocation());
                 }
             } finally {
                 try {
-                    if (getStatement() != null) {
-                        getStatement().close();
-                    }
+                    FileUtils.close(getStatement());
                 } catch (SQLException ex) {
                     // ignore
                 }
-                try {
-                    if (getConnection() != null) {
-                        getConnection().close();
-                    }
-                } catch (SQLException ex) {
-                    // ignore
-                }
+                FileUtils.close(getConnection());
             }
 
             log(goodSql + " of " + totalSql + " SQL statements executed successfully");
@@ -746,10 +729,10 @@
     protected void runStatements(Reader reader, PrintStream out)
         throws SQLException, IOException {
         StringBuffer sql = new StringBuffer();
-        String line;
 
         BufferedReader in = new BufferedReader(reader);
 
+        String line;
         while ((line = in.readLine()) != null) {
             if (!keepformat) {
                 line = line.trim();
@@ -801,7 +784,7 @@
      */
     protected void execSQL(String sql, PrintStream out) throws SQLException {
         // Check and ignore empty statements
-        if ("".equals(sql.trim())) {
+        if (sql.trim().isEmpty()) {
             return;
         }
 
@@ -849,20 +832,14 @@
         } catch (SQLException e) {
             log("Failed to execute: " + sql, Project.MSG_ERR);
             setErrorProperty();
-            if (!onError.equals("abort")) {
+            if (!"abort".equals(onError)) {
                 log(e.toString(), Project.MSG_ERR);
             }
-            if (!onError.equals("continue")) {
+            if (!"continue".equals(onError)) {
                 throw e;
             }
         } finally {
-            if (resultSet != null) {
-                try {
-                    resultSet.close();
-                } catch (SQLException e) {
-                    //ignore
-                }
-            }
+            FileUtils.close(resultSet);
         }
     }
 
@@ -876,13 +853,8 @@
      */
     @Deprecated
     protected void printResults(PrintStream out) throws SQLException {
-        ResultSet rs = getStatement().getResultSet();
-        try {
+        try (ResultSet rs = getStatement().getResultSet()) {
             printResults(rs, out);
-        } finally {
-            if (rs != null) {
-                rs.close();
-            }
         }
     }
 
@@ -937,7 +909,7 @@
         if (csvQuoteChar == null || s == null || (!forceCsvQuoteChar && s.indexOf(csvColumnSep) == -1 && s.indexOf(csvQuoteChar) == -1)) {
             return s;
         }
-        StringBuffer sb = new StringBuffer(csvQuoteChar);
+        StringBuilder sb = new StringBuilder(csvQuoteChar);
         int len = s.length();
         char q = csvQuoteChar.charAt(0);
         for (int i = 0; i < len; i++) {
@@ -956,7 +928,7 @@
      * @since Ant 1.7
      */
     private void closeQuietly() {
-        if (!isAutocommit() && getConnection() != null && onError.equals("abort")) {
+        if (!isAutocommit() && getConnection() != null && "abort".equals(onError)) {
             try {
                 getConnection().rollback();
             } catch (SQLException ex) {
@@ -965,7 +937,6 @@
         }
     }
 
-
     /**
      * Caches the connection returned by the base class's getConnection method.
      *
@@ -1005,7 +976,6 @@
             statement = getConnection().createStatement();
             statement.setEscapeProcessing(escapeProcessing);
         }
-
         return statement;
     }
 
@@ -1072,18 +1042,15 @@
          */
         public void addConfigured(ResourceCollection a) {
             if (a.size() != 1) {
-                throw new BuildException("only single argument resource "
-                                         + "collections are supported.");
+                throw new BuildException(
+                    "only single argument resource collections are supported.");
             }
             setSrcResource(a.iterator().next());
         }
 
-        /**
-         *
-         */
         private void runTransaction(PrintStream out)
             throws IOException, SQLException {
-            if (tSqlCommand.length() != 0) {
+            if (!tSqlCommand.isEmpty()) {
                 log("Executing commands", Project.MSG_INFO);
                 runStatements(new StringReader(tSqlCommand), out);
             }
@@ -1091,16 +1058,11 @@
             if (tSrcResource != null) {
                 log("Executing resource: " + tSrcResource.toString(),
                     Project.MSG_INFO);
-                InputStream is = null;
-                Reader reader = null;
-                try {
-                    is = tSrcResource.getInputStream();
-                    reader = (encoding == null) ? new InputStreamReader(is)
-                        : new InputStreamReader(is, encoding);
+                Charset charset = encoding == null ? Charset.defaultCharset()
+                    : Charset.forName(encoding);
+                try (Reader reader = new InputStreamReader(
+                    tSrcResource.getInputStream(), charset)) {
                     runStatements(reader, out);
-                } finally {
-                    FileUtils.close(is);
-                    FileUtils.close(reader);
                 }
             }
         }
@@ -1116,33 +1078,31 @@
             }
             // no match
             return -1;
-        } else {
-            String d = delimiter.trim().toLowerCase(Locale.ENGLISH);
-            if (delimiterType.equals(DelimiterType.NORMAL)) {
-                // still trying to avoid wasteful copying, see
-                // StringUtils.endsWith
-                int endIndex = delimiter.length() - 1;
-                int bufferIndex = buf.length() - 1;
-                while (bufferIndex >= 0 && Character.isWhitespace(buf.charAt(bufferIndex))) {
-                    --bufferIndex;
-                }
-                if (bufferIndex < endIndex) {
+        }
+        String d = delimiter.trim().toLowerCase(Locale.ENGLISH);
+        if (DelimiterType.NORMAL.equals(delimiterType)) {
+            // still trying to avoid wasteful copying, see
+            // StringUtils.endsWith
+            int endIndex = delimiter.length() - 1;
+            int bufferIndex = buf.length() - 1;
+            while (bufferIndex >= 0 && Character.isWhitespace(buf.charAt(bufferIndex))) {
+                --bufferIndex;
+            }
+            if (bufferIndex < endIndex) {
+                return -1;
+            }
+            while (endIndex >= 0) {
+                if (buf.substring(bufferIndex, bufferIndex + 1).toLowerCase(Locale.ENGLISH)
+                        .charAt(0) != d.charAt(endIndex)) {
                     return -1;
                 }
-                while (endIndex >= 0) {
-                    if (buf.substring(bufferIndex, bufferIndex + 1).toLowerCase(Locale.ENGLISH)
-                            .charAt(0) != d.charAt(endIndex)) {
-                        return -1;
-                    }
-                    bufferIndex--;
-                    endIndex--;
-                }
-                return bufferIndex + 1;
-            } else {
-                return currentLine.trim().toLowerCase(Locale.ENGLISH).equals(d)
-                    ? buf.length() - currentLine.length() : -1;
+                bufferIndex--;
+                endIndex--;
             }
+            return bufferIndex + 1;
         }
+        return currentLine.trim().toLowerCase(Locale.ENGLISH).equals(d)
+            ? buf.length() - currentLine.length() : -1;
     }
 
     private void printWarnings(SQLWarning warning, boolean force)
diff --git a/src/main/org/apache/tools/ant/taskdefs/Sequential.java b/src/main/org/apache/tools/ant/taskdefs/Sequential.java
index f2f88a9..5d309fd 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Sequential.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Sequential.java
@@ -17,7 +17,7 @@
  */
 package org.apache.tools.ant.taskdefs;
 
-import java.util.Iterator;
+import java.util.List;
 import java.util.Vector;
 
 import org.apache.tools.ant.BuildException;
@@ -41,15 +41,16 @@
 public class Sequential extends Task implements TaskContainer {
 
     /** Optional Vector holding the nested tasks */
-    private Vector nestedTasks = new Vector();
+    private List<Task> nestedTasks = new Vector<>();
 
     /**
      * Add a nested task to Sequential.
      *
      * @param nestedTask  Nested task to execute Sequential
      */
+    @Override
     public void addTask(Task nestedTask) {
-        nestedTasks.addElement(nestedTask);
+        nestedTasks.add(nestedTask);
     }
 
     /**
@@ -57,15 +58,13 @@
      *
      * @throws BuildException if one of the nested tasks fails.
      */
+    @Override
     public void execute() throws BuildException {
         LocalProperties localProperties
             = LocalProperties.get(getProject());
         localProperties.enterScope();
         try {
-            for (Iterator i = nestedTasks.iterator(); i.hasNext();) {
-                Task nestedTask = (Task) i.next();
-                nestedTask.perform();
-            }
+            nestedTasks.forEach(Task::perform);
         } finally {
             localProperties.exitScope();
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/SetPermissions.java b/src/main/org/apache/tools/ant/taskdefs/SetPermissions.java
new file mode 100644
index 0000000..cb468e0
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/SetPermissions.java
@@ -0,0 +1,230 @@
+/*
+ *  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.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.DosFileAttributeView;
+import java.nio.file.attribute.PosixFilePermission;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.Resources;
+import org.apache.tools.ant.util.PermissionUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Sets {@link PosixFilePermission}s for resources.
+ *
+ * <p>This task provides a subset of {@link Chmod}'s and {@link
+ * org.apache.tools.ant.taskdefs.optional.windows.Attrib}'s abilities
+ * in less platform dependent way.</p>
+ *
+ * <p>It requires a file system that supports PosixFilePermissions for
+ * its full potential. It can optionally fall back to
+ * DosFilePermissions (only changing the readonly state) on file
+ * systems that don't support POSIX permissions. See {@link
+ * SetPermissions.NonPosixMode}</p>
+ *
+ * @since Ant 1.10.0
+ */
+public class SetPermissions extends Task {
+    private final Set<PosixFilePermission> permissions =
+        EnumSet.noneOf(PosixFilePermission.class);
+    private Resources resources = null;
+    private boolean failonerror = true;
+    private NonPosixMode nonPosixMode = NonPosixMode.fail;
+
+    /**
+     * Options for dealing with file systems that don't support POSIX
+     * permissions.
+     */
+    public enum NonPosixMode {
+        /** Fail the build. */
+        fail,
+        /** Log an error and go on. */
+        pass,
+        /**
+         * Try DosFilePermissions - setting the read-only flag - and
+         * fail the build if that fails as well.
+         */
+        tryDosOrFail,
+        /**
+         * Try DosFilePermissions - setting the read-only flag - and
+         * log an error and go on if that fails as well.
+         */
+        tryDosOrPass
+    }
+
+    /**
+     * Adds permissions as a comma separated list.
+     * @param perms comma separated list of names of {@link PosixFilePermission}s.
+     */
+    public void setPermissions(String perms) {
+        if (perms != null) {
+            Arrays.stream(perms.split(",")) //NOSONAR
+                .map(String::trim)
+                .filter(s -> !s.isEmpty())
+                .map(s -> Enum.valueOf(PosixFilePermission.class, s))
+                .forEach(permissions::add);
+        }
+    }
+
+    /**
+     * A 3 digit octal string, specify the user, group and
+     * other modes in the standard Unix fashion;
+     * @param octalString a <code>String</code> value
+     */
+    public void setMode(String octalString) {
+        int mode = Integer.parseInt(octalString, 8);
+        permissions.addAll(PermissionUtils.permissionsFromMode(mode));
+    }
+
+    /**
+     * Set whether to fail when errors are encountered. If false, note errors
+     * to the output but keep going. Default is true.
+     * <p>Only applies to IO and SecurityExceptions, see {@link
+     * #setNonPosixMode} for ways to deal with file-systems that don't
+     * support PosixPermissions.</p>
+     * @param failonerror true or false.
+     */
+    public void setFailOnError(final boolean failonerror) {
+        this.failonerror = failonerror;
+    }
+
+    /**
+     * Set what to do if changing the permissions of a file is not
+     * possible because the file-system doesn't support POSIX file
+     * permissions.
+     * <p>The default is {@link NonPosixMode#fail}.</p>
+     * @param m what to do if changing the permissions of a file is not possible
+     */
+    public void setNonPosixMode(NonPosixMode m) {
+        this.nonPosixMode = m;
+    }
+
+    /**
+     * Adds a collection of resources to set permissions on.
+     * @param rc a resource collection
+     */
+    public void add(ResourceCollection rc) {
+        if (resources == null) {
+            resources = new Resources();
+        }
+        resources.add(rc);
+    }
+
+    @Override
+    public void execute() {
+        if (resources == null) {
+            throw new BuildException("At least one resource-collection is required");
+        }
+        Resource currentResource = null;
+        try {
+            for (Resource r : resources) {
+                currentResource = r;
+                try {
+                    PermissionUtils.setPermissions(r, permissions, this::posixPermissionsNotSupported);
+                } catch (IOException ioe) {
+                    maybeThrowException(ioe, "Failed to set permissions on '%s' due to %s", r, ioe.getMessage());
+                }
+            }
+        } catch (ClassCastException cce) {
+            maybeThrowException(null,
+                "some specified permissions are not of type PosixFilePermission: %s",
+                StringUtils.join(permissions, ", "));
+        } catch (SecurityException se) {
+            maybeThrowException(null,
+                "the SecurityManager denies role accessUserInformation or write access for SecurityManager.checkWrite for resource '%s'",
+                currentResource);
+        } catch (BuildException be) {
+            // maybe thrown by callback method this::posixPermissionsNotSupported.
+            maybeThrowException(be, be.getMessage());
+        }
+    }
+
+    private void maybeThrowException(Exception exc, String msgFormat, Object... msgArgs) {
+        String msg = String.format(msgFormat, msgArgs);
+        if (failonerror) {
+            if (exc instanceof BuildException) {
+                throw (BuildException) exc;
+            }
+            throw new BuildException(msg, exc);
+        }
+        log("Warning: " + msg, Project.MSG_ERR);
+    }
+
+    private void posixPermissionsNotSupported(Path p) {
+        String msg = String.format(
+            "the associated path '%s' does not support the PosixFileAttributeView",
+            p);
+        switch (nonPosixMode) {
+        case fail:
+            throw new BuildException(msg);
+        case pass:
+            log("Warning: " + msg, Project.MSG_ERR);
+            break;
+        case tryDosOrFail:
+            tryDos(p, true);
+            break;
+        case tryDosOrPass:
+            tryDos(p, false);
+            break;
+        }
+    }
+
+    private void tryDos(Path p, boolean failIfDosIsNotSupported) {
+        log("Falling back to DosFileAttributeView");
+        boolean readOnly = !isWritable();
+        DosFileAttributeView view = Files.getFileAttributeView(p, DosFileAttributeView.class);
+        if (view != null) {
+            try {
+                view.setReadOnly(readOnly);
+            } catch (IOException ioe) {
+                maybeThrowException(ioe, "Failed to set permissions on '%s' due to %s",
+                                    p, ioe.getMessage());
+            } catch (SecurityException uoe) {
+                maybeThrowException(null,
+                    "the SecurityManager denies role accessUserInformation or write access for SecurityManager.checkWrite for resource '%s'",
+                    p);
+            }
+        } else {
+            String msg = String.format(
+                "the associated path '%s' does not support the DosFileAttributeView",
+                p);
+            if (failIfDosIsNotSupported) {
+                throw new BuildException(msg);
+            }
+            log("Warning: " + msg, Project.MSG_ERR);
+        }
+    }
+
+    private boolean isWritable() {
+        return permissions.contains(PosixFilePermission.OWNER_WRITE)
+            || permissions.contains(PosixFilePermission.GROUP_WRITE)
+            || permissions.contains(PosixFilePermission.OTHERS_WRITE);
+    }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/SignJar.java b/src/main/org/apache/tools/ant/taskdefs/SignJar.java
index bb17174..16d6993 100644
--- a/src/main/org/apache/tools/ant/taskdefs/SignJar.java
+++ b/src/main/org/apache/tools/ant/taskdefs/SignJar.java
@@ -53,6 +53,38 @@
     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
 
     /**
+     * error string for unit test verification: {@value}
+     */
+    public static final String ERROR_TODIR_AND_SIGNEDJAR
+            = "'destdir' and 'signedjar' cannot both be set";
+    /**
+     * error string for unit test verification: {@value}
+     */
+    public static final String ERROR_TOO_MANY_MAPPERS = "Too many mappers";
+    /**
+     * error string for unit test verification {@value}
+     */
+    public static final String ERROR_SIGNEDJAR_AND_PATHS
+        = "You cannot specify the signed JAR when using paths or filesets";
+    /**
+     * error string for unit test verification: {@value}
+     */
+    public static final String ERROR_BAD_MAP = "Cannot map source file to anything sensible: ";
+    /**
+     * error string for unit test verification: {@value}
+     */
+    public static final String ERROR_MAPPER_WITHOUT_DEST
+        = "The destDir attribute is required if a mapper is set";
+    /**
+     * error string for unit test verification: {@value}
+     */
+    public static final String ERROR_NO_ALIAS = "alias attribute must be set";
+    /**
+     * error string for unit test verification: {@value}
+     */
+    public static final String ERROR_NO_STOREPASS = "storepass attribute must be set";
+
+    /**
      * name to a signature file
      */
     protected String sigfile;
@@ -129,36 +161,10 @@
     private String digestAlg;
 
     /**
-     * error string for unit test verification: {@value}
+     * tsa digest algorithm
      */
-    public static final String ERROR_TODIR_AND_SIGNEDJAR
-            = "'destdir' and 'signedjar' cannot both be set";
-    /**
-     * error string for unit test verification: {@value}
-     */
-    public static final String ERROR_TOO_MANY_MAPPERS = "Too many mappers";
-    /**
-     * error string for unit test verification {@value}
-     */
-    public static final String ERROR_SIGNEDJAR_AND_PATHS
-        = "You cannot specify the signed JAR when using paths or filesets";
-    /**
-     * error string for unit test verification: {@value}
-     */
-    public static final String ERROR_BAD_MAP = "Cannot map source file to anything sensible: ";
-    /**
-     * error string for unit test verification: {@value}
-     */
-    public static final String ERROR_MAPPER_WITHOUT_DEST
-        = "The destDir attribute is required if a mapper is set";
-    /**
-     * error string for unit test verification: {@value}
-     */
-    public static final String ERROR_NO_ALIAS = "alias attribute must be set";
-    /**
-     * error string for unit test verification: {@value}
-     */
-    public static final String ERROR_NO_STOREPASS = "storepass attribute must be set";
+    private String tsaDigestAlg;
+
     // CheckStyle:VisibilityModifier ON
 
     /**
@@ -369,6 +375,26 @@
     }
 
     /**
+     * TSA Digest Algorithm; optional
+     *
+     * @param digestAlg the tsa digest algorithm
+     * @since Ant 1.10.2
+     */
+    public void setTSADigestAlg(String digestAlg) {
+        this.tsaDigestAlg = digestAlg;
+    }
+
+    /**
+     * TSA Digest Algorithm; optional
+     *
+     * @return String
+     * @since Ant 1.10.2
+     */
+    public String getTSADigestAlg() {
+        return tsaDigestAlg;
+    }
+
+    /**
      * sign the jar(s)
      *
      * @throws BuildException on errors
@@ -424,14 +450,7 @@
 
             Path sources = createUnifiedSourcePath();
             //set up our mapping policy
-            FileNameMapper destMapper;
-            if (hasMapper) {
-                destMapper = mapper;
-            } else {
-                //no mapper? use the identity policy
-                destMapper = new IdentityMapper();
-            }
-
+            FileNameMapper destMapper = hasMapper ? mapper : new IdentityMapper();
 
             //at this point the paths are set up with lists of files,
             //and the mapper is ready to map from source dirs to dest files
@@ -570,6 +589,11 @@
                 addProxyFor(cmd, "http");
             }
         }
+
+        if (tsaDigestAlg != null) {
+            addValue(cmd, "-tsadigestalg");
+            addValue(cmd, tsaDigestAlg);
+        }
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/taskdefs/Sleep.java b/src/main/org/apache/tools/ant/taskdefs/Sleep.java
index 6468c39..5a59c19 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Sleep.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Sleep.java
@@ -64,15 +64,12 @@
      */
     private int milliseconds = 0;
 
-
-
     /**
      * Creates new instance
      */
     public Sleep() {
     }
 
-
     /**
      * seconds to add to the sleep time
      *
@@ -82,7 +79,6 @@
         this.seconds = seconds;
     }
 
-
     /**
      * hours to add to the sleep time.
      *
@@ -92,7 +88,6 @@
         this.hours = hours;
     }
 
-
     /**
      * minutes to add to the sleep time
      *
@@ -102,7 +97,6 @@
         this.minutes = minutes;
     }
 
-
     /**
      * milliseconds to add to the sleep time
      *
@@ -112,7 +106,6 @@
         this.milliseconds = milliseconds;
     }
 
-
     /**
      * sleep for a period of time
      *
@@ -126,7 +119,6 @@
         }
     }
 
-
     /**
      * flag controlling whether to break the build on an error.
      *
@@ -136,7 +128,6 @@
         this.failOnError = failOnError;
     }
 
-
     /**
      * return time to sleep
      *
@@ -150,7 +141,6 @@
         // CheckStyle:MagicNumber ON
     }
 
-
     /**
      * verify parameters
      *
@@ -159,12 +149,10 @@
     public void validate()
         throws BuildException {
         if (getSleepTime() < 0) {
-            throw new BuildException("Negative sleep periods are not "
-                                     + "supported");
+            throw new BuildException("Negative sleep periods are not supported");
         }
     }
 
-
     /**
      * Executes this build task. Throws org.apache.tools.ant.BuildException
      * if there is an error during task execution.
@@ -183,12 +171,9 @@
         } catch (Exception e) {
             if (failOnError) {
                 throw new BuildException(e);
-            } else {
-                String text = e.toString();
-                log(text, Project.MSG_ERR);
             }
+            log(e.toString(), Project.MSG_ERR);
         }
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java b/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java
index c7afc4d..1ad5058 100644
--- a/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java
+++ b/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java
@@ -58,7 +58,6 @@
         this(is, os, closeWhenExhausted, false);
     }
 
-
     /**
      * Create a new StreamPumper.
      * <p><b>Note:</b> If you set useAvailable to true, you must
@@ -114,6 +113,7 @@
      *
      * Terminates as soon as the input stream is closed or an error occurs.
      */
+    @Override
     public void run() {
         synchronized (this) {
             started = true;
diff --git a/src/main/org/apache/tools/ant/taskdefs/SubAnt.java b/src/main/org/apache/tools/ant/taskdefs/SubAnt.java
index f3207aa..cd8c8bd 100644
--- a/src/main/org/apache/tools/ant/taskdefs/SubAnt.java
+++ b/src/main/org/apache/tools/ant/taskdefs/SubAnt.java
@@ -19,7 +19,7 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.util.Enumeration;
+import java.util.List;
 import java.util.Vector;
 
 import org.apache.tools.ant.BuildException;
@@ -72,12 +72,12 @@
     private boolean failOnError = true;
     private String output  = null;
 
-    private Vector properties = new Vector();
-    private Vector references = new Vector();
-    private Vector propertySets = new Vector();
+    private List<Property> properties = new Vector<>();
+    private List<Ant.Reference> references = new Vector<>();
+    private List<PropertySet> propertySets = new Vector<>();
 
     /** the targets to call on the new project */
-    private Vector/*<TargetElement>*/ targets = new Vector();
+    private List<TargetElement> targets = new Vector<>();
 
     /**
      * Get the default build file name to use when launching the task.
@@ -297,11 +297,7 @@
         ant = createAntTask(directory);
         String antfilename = file.getAbsolutePath();
         ant.setAntfile(antfilename);
-        final int size = targets.size();
-        for (int i = 0; i < size; i++) {
-            TargetElement targetElement = (TargetElement) targets.get(i);
-            ant.addConfiguredTarget(targetElement);
-        }
+        targets.forEach(ant::addConfiguredTarget);
 
         try {
             if (verbose) {
@@ -332,13 +328,15 @@
     private boolean isHardError(Throwable t) {
         if (t instanceof BuildException) {
             return isHardError(t.getCause());
-        } else if (t instanceof OutOfMemoryError) {
-            return true;
-        } else if (t instanceof ThreadDeath) {
-            return true;
-        } else { // incl. t == null
-            return false;
         }
+        if (t instanceof OutOfMemoryError) {
+            return true;
+        }
+        if (t instanceof ThreadDeath) {
+            return true;
+        }
+        // incl. t == null
+        return false;
     }
 
     /**
@@ -393,8 +391,7 @@
      * @since Ant 1.7
      */
     public void addConfiguredTarget(TargetElement t) {
-        String name = t.getName();
-        if ("".equals(name)) {
+        if (t.getName().isEmpty()) {
             throw new BuildException("target name must not be empty");
         }
         targets.add(t);
@@ -446,7 +443,7 @@
      * @param  p the property to pass on explicitly to the sub-build.
      */
     public void addProperty(Property p) {
-        properties.addElement(p);
+        properties.add(p);
     }
 
     /**
@@ -456,7 +453,7 @@
      * @param  r the reference to pass on explicitly to the sub-build.
      */
     public void addReference(Ant.Reference r) {
-        references.addElement(r);
+        references.add(r);
     }
 
     /**
@@ -465,7 +462,7 @@
      * @param ps the propertyset
      */
     public void addPropertyset(PropertySet ps) {
-        propertySets.addElement(ps);
+        propertySets.add(ps);
     }
 
     /**
@@ -595,18 +592,14 @@
         }
 
         antTask.setInheritAll(inheritAll);
-        for (Enumeration i = properties.elements(); i.hasMoreElements();) {
-            copyProperty(antTask.createProperty(), (Property) i.nextElement());
-        }
 
-        for (Enumeration i = propertySets.elements(); i.hasMoreElements();) {
-            antTask.addPropertyset((PropertySet) i.nextElement());
-        }
+        properties.forEach(p -> copyProperty(antTask.createProperty(), p));
+
+        propertySets.forEach(antTask::addPropertyset);
 
         antTask.setInheritRefs(inheritRefs);
-        for (Enumeration i = references.elements(); i.hasMoreElements();) {
-            antTask.addReference((Ant.Reference) i.nextElement());
-        }
+
+        references.forEach(antTask::addReference);
 
         return antTask;
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Sync.java b/src/main/org/apache/tools/ant/taskdefs/Sync.java
index e99bafd..557644d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Sync.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Sync.java
@@ -19,12 +19,12 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
-import java.util.Enumeration;
+import java.util.Collections;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.DirectoryScanner;
@@ -105,7 +105,7 @@
         File toDir = myCopy.getToDir();
 
         // The complete list of files to copy
-        Set allFiles = myCopy.nonOrphans;
+        Set<String> allFiles = myCopy.nonOrphans;
 
         // If the destination directory didn't already exist,
         // or was empty, then no previous file removal is necessary!
@@ -124,7 +124,7 @@
         // will hold the directories matched by SyncTarget in reversed
         // lexicographic order (order is important, that's why we use
         // a LinkedHashSet
-        Set preservedDirectories = new LinkedHashSet();
+        Set<File> preservedDirectories = new LinkedHashSet<>();
 
         // Get rid of all files not listed in the source filesets.
         log("PASS#2: Removing orphan files from " + toDir, Project.MSG_DEBUG);
@@ -186,15 +186,15 @@
      * Position 0 of the array is the number of orphaned directories.
      * Position 1 of the array is the number or orphaned files.
      */
-    private int[] removeOrphanFiles(Set nonOrphans, File toDir,
-                                    Set preservedDirectories) {
+    private int[] removeOrphanFiles(Set<String> nonOrphans, File toDir,
+                                    Set<File> preservedDirectories) {
         int[] removedCount = new int[] {0, 0};
         String[] excls =
-            (String[]) nonOrphans.toArray(new String[nonOrphans.size() + 1]);
+            nonOrphans.toArray(new String[nonOrphans.size() + 1]);
         // want to keep toDir itself
         excls[nonOrphans.size()] = "";
 
-        DirectoryScanner ds = null;
+        DirectoryScanner ds;
         if (syncTarget != null) {
             FileSet fs = syncTarget.toFileSet(false);
             fs.setDir(toDir);
@@ -213,8 +213,8 @@
             FileSelector[] s = syncTarget.getSelectors(getProject());
             if (s.length > 0) {
                 NoneSelector ns = new NoneSelector();
-                for (int i = 0; i < s.length; i++) {
-                    ns.appendSelector(s[i]);
+                for (FileSelector element : s) {
+                    ns.appendSelector(element);
                 }
                 fs.appendSelector(ns);
             }
@@ -227,8 +227,8 @@
 
         ds.scan();
         String[] files = ds.getIncludedFiles();
-        for (int i = 0; i < files.length; i++) {
-            File f = new File(toDir, files[i]);
+        for (String file : files) {
+            File f = new File(toDir, file);
             log("Removing orphan file: " + f, Project.MSG_DEBUG);
             f.delete();
             ++removedCount[1];
@@ -282,7 +282,7 @@
      * @return the number of empty directories actually removed.
      */
     private int removeEmptyDirectories(File dir, boolean removeIfEmpty,
-                                       Set preservedEmptyDirectories) {
+                                       Set<File> preservedEmptyDirectories) {
         int removedCount = 0;
         if (dir.isDirectory()) {
             File[] children = dir.listFiles();
@@ -323,11 +323,9 @@
      *
      * @since Ant 1.8.0
      */
-    private int removeEmptyDirectories(Set preservedEmptyDirectories) {
+    private int removeEmptyDirectories(Set<File> preservedEmptyDirectories) {
         int removedCount = 0;
-        for (Iterator iter = preservedEmptyDirectories.iterator();
-             iter.hasNext();) {
-            File f = (File) iter.next();
+        for (File f : preservedEmptyDirectories) {
             String[] s = f.list();
             if (s == null || s.length == 0) {
                 log("Removing empty directory: " + f, Project.MSG_DEBUG);
@@ -434,8 +432,8 @@
      */
     public void addPreserveInTarget(SyncTarget s) {
         if (syncTarget != null) {
-            throw new BuildException("you must not specify multiple "
-                                     + "preserveintarget elements.");
+            throw new BuildException(
+                "you must not specify multiple preserveintarget elements.");
         }
         syncTarget = s;
     }
@@ -457,11 +455,7 @@
 
         // List of files that must be copied, irrelevant from the
         // fact that they are newer or not than the destination.
-        private Set nonOrphans = new HashSet();
-
-        /** Constructor for MyCopy. */
-        public MyCopy() {
-        }
+        private Set<String> nonOrphans = new HashSet<>();
 
         /**
          * @see Copy#scan(File, File, String[], String[])
@@ -474,12 +468,8 @@
 
             super.scan(fromDir, toDir, files, dirs);
 
-            for (int i = 0; i < files.length; ++i) {
-                nonOrphans.add(files[i]);
-            }
-            for (int i = 0; i < dirs.length; ++i) {
-                nonOrphans.add(dirs[i]);
-            }
+            Collections.addAll(nonOrphans, files);
+            Collections.addAll(nonOrphans, dirs);
         }
 
         /**
@@ -487,12 +477,11 @@
          * {@inheritDoc}
          */
         @Override
-        protected Map scan(Resource[] resources, File toDir) {
+        protected Map<Resource, String[]> scan(Resource[] resources, File toDir) {
             assertTrue("No mapper", mapperElement == null);
 
-            for (int i = 0; i < resources.length; i++) {
-                nonOrphans.add(resources[i].getName());
-            }
+            Stream.of(resources).map(Resource::getName).forEach(nonOrphans::add);
+
             return super.scan(resources, toDir);
         }
 
@@ -539,6 +528,7 @@
          * This just changes the default value of "defaultexcludes" from
          * true to false.
          */
+        // TODO does it? ^
         public SyncTarget() {
             super();
         }
@@ -551,8 +541,8 @@
          */
         @Override
         public void setDir(File dir) throws BuildException {
-            throw new BuildException("preserveintarget doesn't support the dir "
-                                     + "attribute");
+            throw new BuildException(
+                "preserveintarget doesn't support the dir attribute");
         }
 
         /**
@@ -588,8 +578,8 @@
                 PatternSet ps = mergePatterns(getProject());
                 fs.appendIncludes(ps.getIncludePatterns(getProject()));
                 fs.appendExcludes(ps.getExcludePatterns(getProject()));
-                for (Enumeration e = selectorElements(); e.hasMoreElements();) {
-                    fs.appendSelector((FileSelector) e.nextElement());
+                for (FileSelector sel : getSelectors(getProject())) {
+                    fs.appendSelector(sel);
                 }
                 fs.setDefaultexcludes(getDefaultexcludes());
             }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Tar.java b/src/main/org/apache/tools/ant/taskdefs/Tar.java
index 0d319d1..879c17c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Tar.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Tar.java
@@ -20,14 +20,15 @@
 
 import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.file.Files;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -109,10 +110,10 @@
     private TarLongFileMode longFileMode = new TarLongFileMode();
 
     // need to keep the package private version for backwards compatibility
-    Vector<TarFileSet> filesets = new Vector<TarFileSet>();
+    Vector<TarFileSet> filesets = new Vector<>();
     // we must keep two lists since other classes may modify the
     // filesets Vector (it is package private) without us noticing
-    private final Vector<ResourceCollection> resourceCollections = new Vector<ResourceCollection>();
+    private final List<ResourceCollection> resourceCollections = new Vector<>();
 
     // CheckStyle:VisibilityModifier ON
 
@@ -198,8 +199,7 @@
      */
     @Deprecated
     public void setLongfile(final String mode) {
-        log("DEPRECATED - The setLongfile(String) method has been deprecated."
-            + " Use setLongfile(Tar.TarLongFileMode) instead.");
+        log("DEPRECATED - The setLongfile(String) method has been deprecated. Use setLongfile(Tar.TarLongFileMode) instead.");
         this.longFileMode = new TarLongFileMode();
         longFileMode.setValue(mode);
     }
@@ -230,6 +230,7 @@
      * <li>  none - no compression
      * <li>  gzip - Gzip compression
      * <li>  bzip2 - Bzip2 compression
+     * <li>xz - XZ compression, requires XZ for Java
      * </ul>
      * @param mode the compression method.
      */
@@ -272,8 +273,7 @@
                                      getLocation());
         }
 
-        @SuppressWarnings("unchecked")
-        final Vector<TarFileSet> savedFileSets = (Vector<TarFileSet>) filesets.clone();
+        final Vector<TarFileSet> savedFileSets = new Vector<>(filesets);
         try {
             if (baseDir != null) {
                 if (!baseDir.exists()) {
@@ -287,20 +287,19 @@
                 filesets.addElement(mainFileSet);
             }
 
-            if (filesets.size() == 0 && resourceCollections.size() == 0) {
-                throw new BuildException("You must supply either a basedir "
-                                         + "attribute or some nested resource"
-                                         + " collections.",
-                                         getLocation());
+            if (filesets.isEmpty() && resourceCollections.isEmpty()) {
+                throw new BuildException(
+                    "You must supply either a basedir attribute or some nested resource collections.",
+                    getLocation());
             }
 
             // check if tar is out of date with respect to each
             // fileset
             boolean upToDate = true;
-            for(final TarFileSet tfs : filesets) {
+            for (final TarFileSet tfs : filesets) {
                 upToDate &= check(tfs);
             }
-            for(final ResourceCollection rcol : resourceCollections) {
+            for (final ResourceCollection rcol : resourceCollections) {
                 upToDate &= check(rcol);
             }
 
@@ -313,19 +312,17 @@
             final File parent = tarFile.getParentFile();
             if (parent != null && !parent.isDirectory()
                 && !(parent.mkdirs() || parent.isDirectory())) {
-                throw new BuildException("Failed to create missing parent"
-                                         + " directory for " + tarFile);
+                throw new BuildException(
+                    "Failed to create missing parent directory for %s",
+                    tarFile);
             }
 
             log("Building tar: " + tarFile.getAbsolutePath(), Project.MSG_INFO);
 
-            TarOutputStream tOut = null;
-            try {
-                tOut = new TarOutputStream(
-                    compression.compress(
-                        new BufferedOutputStream(
-                            new FileOutputStream(tarFile))),
-                    encoding);
+            try (TarOutputStream tOut = new TarOutputStream(
+                compression.compress(new BufferedOutputStream(
+                    Files.newOutputStream(tarFile.toPath()))),
+                encoding)) {
                 tOut.setDebug(true);
                 if (longFileMode.isTruncateMode()) {
                     tOut.setLongFileMode(TarOutputStream.LONGFILE_TRUNCATE);
@@ -349,8 +346,6 @@
             } catch (final IOException ioe) {
                 final String msg = "Problem creating TAR: " + ioe.getMessage();
                 throw new BuildException(msg, ioe, getLocation());
-            } finally {
-                FileUtils.close(tOut);
             }
         } finally {
             filesets = savedFileSets;
@@ -600,8 +595,8 @@
         } else if (!rc.isFilesystemOnly() && !supportsNonFileResources()) {
             throw new BuildException("only filesystem resources are supported");
         } else if (rc.isFilesystemOnly()) {
-            final Set<File> basedirs = new HashSet<File>();
-            final Map<File, List<String>> basedirToFilesMap = new HashMap<File, List<String>>();
+            final Set<File> basedirs = new HashSet<>();
+            final Map<File, List<String>> basedirToFilesMap = new HashMap<>();
             for (final Resource res : rc) {
                 final FileResource r = ResourceUtils
                     .asFileResource(res.as(FileProvider.class));
@@ -612,7 +607,7 @@
                 basedirs.add(base);
                 List<String> files = basedirToFilesMap.get(base);
                 if (files == null) {
-                    files = new Vector<String>();
+                    files = new Vector<>();
                     basedirToFilesMap.put(base, files);
                 }
                 if (base == Copy.NULL_FILE_PLACEHOLDER) {
@@ -627,9 +622,7 @@
                 upToDate &= check(tmpBase, files);
             }
         } else { // non-file resources
-            final Iterator<Resource> iter = rc.iterator();
-            while (upToDate && iter.hasNext()) {
-                final Resource r = iter.next();
+            for (Resource r : rc) {
                 upToDate = archiveIsUpToDate(r);
             }
         }
@@ -651,10 +644,10 @@
             upToDate = false;
         }
 
-        for (int i = 0; i < files.length; ++i) {
-            if (tarFile.equals(new File(basedir, files[i]))) {
-                throw new BuildException("A tar file cannot include "
-                                         + "itself", getLocation());
+        for (String file : files) {
+            if (tarFile.equals(new File(basedir, file))) {
+                throw new BuildException("A tar file cannot include itself",
+                    getLocation());
             }
         }
         return upToDate;
@@ -692,20 +685,17 @@
             afs = (ArchiveFileSet) rc;
         }
         if (afs != null && afs.size() > 1
-            && afs.getFullpath(this.getProject()).length() > 0) {
-            throw new BuildException("fullpath attribute may only "
-                                     + "be specified for "
-                                     + "filesets that specify a "
-                                     + "single file.");
+            && !afs.getFullpath(this.getProject()).isEmpty()) {
+            throw new BuildException(
+                "fullpath attribute may only be specified for filesets that specify a single file.");
         }
         final TarFileSet tfs = asTarFileSet(afs);
 
         if (isFileFileSet(rc)) {
             final FileSet fs = (FileSet) rc;
-            final String[] files = getFileNames(fs);
-            for (int i = 0; i < files.length; i++) {
-                final File f = new File(fs.getDir(getProject()), files[i]);
-                final String name = files[i].replace(File.separatorChar, '/');
+            for (String file : getFileNames(fs)) {
+                final File f = new File(fs.getDir(getProject()), file);
+                final String name = file.replace(File.separatorChar, '/');
                 tarFile(f, tOut, name, tfs);
             }
         } else if (rc.isFilesystemOnly()) {
@@ -742,7 +732,7 @@
         final DirectoryScanner ds = fs.getDirectoryScanner(fs.getProject());
         final String[] directories = ds.getIncludedDirectories();
         final String[] filesPerSe = ds.getIncludedFiles();
-        final String[] files = new String [directories.length + filesPerSe.length];
+        final String[] files = new String[directories.length + filesPerSe.length];
         System.arraycopy(directories, 0, files, 0, directories.length);
         System.arraycopy(filesPerSe, 0, files, directories.length,
                          filesPerSe.length);
@@ -759,7 +749,7 @@
      * @since Ant 1.7
      */
     protected TarFileSet asTarFileSet(final ArchiveFileSet archiveFileSet) {
-        TarFileSet tfs = null;
+        TarFileSet tfs;
         if (archiveFileSet != null && archiveFileSet instanceof TarFileSet) {
             tfs = (TarFileSet) archiveFileSet;
         } else {
@@ -837,7 +827,6 @@
             if (files == null) {
                 files = getFileNames(this);
             }
-
             return files;
         }
 
@@ -891,7 +880,7 @@
             POSIX = "posix",
             OMIT = "omit";
 
-        private final String[] validModes = {
+        private static final String[] VALID_MODES = {
             WARN, FAIL, TRUNCATE, GNU, POSIX, OMIT
         };
 
@@ -906,7 +895,7 @@
          */
         @Override
         public String[] getValues() {
-            return validModes;
+            return VALID_MODES;
         }
 
         /**
@@ -971,7 +960,11 @@
          *    BZIP2 compression
          */
         private static final String BZIP2 = "bzip2";
-
+        /**
+         *  XZ compression
+         * @since 1.10.1
+         */
+        private static final String XZ = "xz";
 
         /**
          * Default constructor
@@ -987,7 +980,7 @@
          */
         @Override
         public String[] getValues() {
-            return new String[] {NONE, GZIP, BZIP2};
+            return new String[] {NONE, GZIP, BZIP2, XZ};
         }
 
         /**
@@ -1003,14 +996,39 @@
             final String v = getValue();
             if (GZIP.equals(v)) {
                 return new GZIPOutputStream(ostream);
-            } else {
-                if (BZIP2.equals(v)) {
-                    ostream.write('B');
-                    ostream.write('Z');
-                    return new CBZip2OutputStream(ostream);
-                }
+            }
+            if (XZ.equals(v)) {
+                return newXZOutputStream(ostream);
+            }
+            if (BZIP2.equals(v)) {
+                ostream.write('B');
+                ostream.write('Z');
+                return new CBZip2OutputStream(ostream);
             }
             return ostream;
         }
+
+        private static OutputStream newXZOutputStream(OutputStream ostream)
+            throws BuildException {
+            try {
+                Class<?> fClazz = Class.forName("org.tukaani.xz.FilterOptions");
+                Class<?> oClazz = Class.forName("org.tukaani.xz.LZMA2Options");
+                Class<? extends OutputStream> sClazz =
+                    Class.forName("org.tukaani.xz.XZOutputStream")
+                    .asSubclass(OutputStream.class);
+                Constructor<? extends OutputStream> c =
+                    sClazz.getConstructor(OutputStream.class, fClazz);
+                return c.newInstance(ostream, oClazz.newInstance());
+            } catch (ClassNotFoundException ex) {
+                throw new BuildException("xz compression requires the XZ for Java library",
+                                         ex);
+            } catch (NoSuchMethodException
+                     | InstantiationException
+                     | IllegalAccessException
+                     | InvocationTargetException
+                     ex) {
+                throw new BuildException("failed to create XZOutputStream", ex);
+            }
+        }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Taskdef.java b/src/main/org/apache/tools/ant/taskdefs/Taskdef.java
index a7d0b71..159c443 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Taskdef.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Taskdef.java
@@ -43,7 +43,6 @@
      * This sets the adapter and the adaptto classes to
      * TaskAdapter and Task.
      */
-
     public Taskdef() {
         setAdapterClass(TaskAdapter.class);
         setAdaptToClass(Task.class);
diff --git a/src/main/org/apache/tools/ant/taskdefs/TempFile.java b/src/main/org/apache/tools/ant/taskdefs/TempFile.java
index 9756fbc..882bb47 100644
--- a/src/main/org/apache/tools/ant/taskdefs/TempFile.java
+++ b/src/main/org/apache/tools/ant/taskdefs/TempFile.java
@@ -80,7 +80,6 @@
         this.property = property;
     }
 
-
     /**
      * Sets the destination directory. If not set,
      * the basedir directory is used instead.
@@ -91,7 +90,6 @@
         this.destDir = destDir;
     }
 
-
     /**
      * Sets the optional prefix string for the temp file.
      *
@@ -101,7 +99,6 @@
         this.prefix = prefix;
     }
 
-
     /**
      * Sets the optional suffix string for the temp file.
      *
@@ -149,8 +146,9 @@
      *
      * @exception  BuildException  if something goes wrong with the build
      */
+    @Override
     public void execute() throws BuildException {
-        if (property == null || property.length() == 0) {
+        if (property == null || property.isEmpty()) {
             throw new BuildException("no property specified");
         }
         if (destDir == null) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/Touch.java b/src/main/org/apache/tools/ant/taskdefs/Touch.java
index 5b9722b..116eef3 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Touch.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Touch.java
@@ -23,7 +23,7 @@
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.Locale;
+import java.util.List;
 import java.util.Vector;
 
 import org.apache.tools.ant.BuildException;
@@ -67,9 +67,11 @@
     public static final DateFormatFactory DEFAULT_DF_FACTORY
         = new DateFormatFactory() {
 
+        @Override
         public DateFormat getPrimaryFormat() {
             return DateUtils.EN_US_DATE_FORMAT_MIN.get();
         }
+        @Override
         public DateFormat getFallbackFormat() {
             return DateUtils.EN_US_DATE_FORMAT_SEC.get();
         }
@@ -79,7 +81,7 @@
     private File file;
     private long millis = -1;
     private String dateTime;
-    private Vector filesets = new Vector();
+    private List<FileSet> filesets = new Vector<>();
     private Union resources;
     private boolean dateTimeConfigured;
     private boolean mkdirs;
@@ -88,12 +90,6 @@
     private DateFormatFactory dfFactory = DEFAULT_DF_FACTORY;
 
     /**
-     * Construct a new <code>Touch</code> task.
-     */
-    public Touch() {
-    }
-
-    /**
      * Sets a single source file to touch.  If the file does not exist
      * an empty file will be created.
      * @param file the <code>File</code> to touch.
@@ -153,9 +149,11 @@
      */
     public void setPattern(final String pattern) {
         dfFactory = new DateFormatFactory() {
+            @Override
             public DateFormat getPrimaryFormat() {
                 return new SimpleDateFormat(pattern);
             }
+            @Override
             public DateFormat getFallbackFormat() {
                 return null;
             }
@@ -179,8 +177,8 @@
      */
     public void add(FileNameMapper fileNameMapper) throws BuildException {
         if (this.fileNameMapper != null) {
-            throw new BuildException("Only one mapper may be added to the "
-                + getTaskName() + " task.");
+            throw new BuildException(
+                "Only one mapper may be added to the %s task.", getTaskName());
         }
         this.fileNameMapper = fileNameMapper;
     }
@@ -219,8 +217,8 @@
      */
     protected synchronized void checkConfiguration() throws BuildException {
         if (file == null && resources == null) {
-            throw new BuildException("Specify at least one source"
-                                   + "--a file or resource collection.");
+            throw new BuildException(
+                "Specify at least one source--a file or resource collection.");
         }
         if (file != null && file.exists() && file.isDirectory()) {
             throw new BuildException("Use a resource collection to touch directories.");
@@ -250,10 +248,9 @@
                     throw new BuildException(pe.getMessage(), pe, getLocation());
                 }
                 if (workmillis < 0) {
-                    throw new BuildException("Date of " + dateTime
-                            + " results in negative " + "milliseconds value "
-                            + "relative to epoch " + "(January 1, 1970, "
-                            + "00:00:00 GMT).");
+                    throw new BuildException(
+                        "Date of %s results in negative milliseconds value relative to epoch (January 1, 1970, 00:00:00 GMT).",
+                        dateTime);
                 }
             }
             log("Setting millis to " + workmillis + " from datetime attribute",
@@ -270,6 +267,7 @@
      * @throws BuildException
      *             if an error occurs.
      */
+    @Override
     public void execute() throws BuildException {
         checkConfiguration();
         touch();
@@ -301,16 +299,12 @@
         // deal with filesets in a special way since the task
         // originally also used the directories and Union won't return
         // them.
-        final int size = filesets.size();
-        for (int i = 0; i < size; i++) {
-            FileSet fs = (FileSet) filesets.elementAt(i);
+        for (FileSet fs : filesets) {
             DirectoryScanner ds = fs.getDirectoryScanner(getProject());
             File fromDir = fs.getDir(getProject());
 
-            String[] srcDirs = ds.getIncludedDirectories();
-
-            for (int j = 0; j < srcDirs.length; j++) {
-                touch(new FileResource(fromDir, srcDirs[j]), defaultTimestamp);
+            for (String srcDir : ds.getIncludedDirectories()) {
+                touch(new FileResource(fromDir, srcDir), defaultTimestamp);
             }
         }
     }
@@ -323,6 +317,7 @@
      * @throws BuildException on error
      * @deprecated since 1.6.x.
      */
+    @Deprecated
     protected void touch(File file) {
         touch(file, getTimestamp());
     }
@@ -366,8 +361,8 @@
             }
         }
         if (!file.canWrite()) {
-            throw new BuildException("Can not change modification date of "
-                                     + "read-only file " + file);
+            throw new BuildException(
+                "Can not change modification date of read-only file %s", file);
         }
         FILE_UTILS.setFileLastModified(file, modTime);
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Tstamp.java b/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
index aee2607..d31cb2d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
@@ -19,16 +19,20 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.text.SimpleDateFormat;
+import java.time.Instant;
 import java.util.Calendar;
 import java.util.Date;
-import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.NoSuchElementException;
+import java.util.Optional;
 import java.util.StringTokenizer;
 import java.util.TimeZone;
 import java.util.Vector;
+import java.util.function.BiFunction;
+import java.util.function.Function;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Location;
@@ -46,7 +50,7 @@
  */
 public class Tstamp extends Task {
 
-    private Vector customFormats = new Vector();
+    private List<CustomFormat> customFormats = new Vector<>();
     private String prefix = "";
 
     /**
@@ -67,15 +71,12 @@
      * the standard ones, to get their retaliation in early.
      * @throws BuildException on error.
      */
+    @Override
     public void execute() throws BuildException {
         try {
             Date d = getNow();
 
-            Enumeration i = customFormats.elements();
-            while (i.hasMoreElements()) {
-                CustomFormat cts = (CustomFormat) i.nextElement();
-                cts.execute(getProject(), d, getLocation());
-            }
+            customFormats.forEach(cts -> cts.execute(getProject(), d, getLocation()));
 
             SimpleDateFormat dstamp = new SimpleDateFormat("yyyyMMdd");
             setProperty("DSTAMP", dstamp.format(d));
@@ -98,7 +99,7 @@
      */
     public CustomFormat createFormat() {
         CustomFormat cts = new CustomFormat();
-        customFormats.addElement(cts);
+        customFormats.add(cts);
         return cts;
     }
 
@@ -116,16 +117,41 @@
      * @return Date
      */
     protected Date getNow() {
-        String magicNow = getProject().getProperty(MagicNames.TSTAMP_NOW);
-        if (magicNow != null && magicNow.length() > 0) {
+        Optional<Date> now = getNow(
+            MagicNames.TSTAMP_NOW_ISO,
+            s -> Date.from(Instant.parse(s)),
+            (k, v) -> "magic property " + k + " ignored as '" + v + "' is not in valid ISO pattern"
+        );
+        if (now.isPresent()) {
+            return now.get();
+        }
+
+        now = getNow(
+            MagicNames.TSTAMP_NOW,
+            s -> new Date(1000 * Long.parseLong(s)),
+            (k, v) -> "magic property " + k + " ignored as " + v + " is not a valid number"
+        );
+        return now.orElseGet(Date::new);
+    }
+
+    /**
+     * Checks and returns a Date if the specified property is set.
+     * @param propertyName name of the property to check
+     * @param map conversion of the property value as string to Date
+     * @param log supplier of the log message containing the property name and value if
+     *     the conversion fails
+     * @return Optional containing the Date or null
+     */
+    protected Optional<Date> getNow(String propertyName, Function<String, Date> map, BiFunction<String, String, String> log) {
+        String property = getProject().getProperty(propertyName);
+        if (property != null && property.length() > 0) {
             try {
-                return new Date(1000 * Long.parseLong(magicNow));
-            } catch (NumberFormatException ex) {
-                log("magic property " + MagicNames.TSTAMP_NOW + " ignored as "
-                    + magicNow + " is not a valid number");
+                return Optional.ofNullable(map.apply(property));
+            } catch (Exception e) {
+                log(log.apply(propertyName, property));
             }
         }
-        return new Date();
+        return Optional.empty();
     }
 
     /**
@@ -148,12 +174,6 @@
         private int field = Calendar.DATE;
 
         /**
-         * Create a format
-         */
-        public CustomFormat() {
-        }
-
-        /**
          *  The property to receive the date/time string in the given pattern
          * @param propertyName the name of the property.
          */
@@ -228,9 +248,9 @@
          *             encapsulate operations on the unit in its own
          *             class.
          */
+        @Deprecated
         public void setUnit(String unit) {
-            log("DEPRECATED - The setUnit(String) method has been deprecated."
-                + " Use setUnit(Tstamp.Unit) instead.");
+            log("DEPRECATED - The setUnit(String) method has been deprecated. Use setUnit(Tstamp.Unit) instead.");
             Unit u = new Unit();
             u.setValue(unit);
             field = u.getCalendarField();
@@ -317,19 +337,19 @@
                                                 YEAR
                                               };
 
-        private Map calendarFields = new HashMap();
+        private Map<String, Integer> calendarFields = new HashMap<>();
 
         /** Constructor for Unit enumerated type. */
         public Unit() {
             calendarFields.put(MILLISECOND,
-                               new Integer(Calendar.MILLISECOND));
-            calendarFields.put(SECOND, new Integer(Calendar.SECOND));
-            calendarFields.put(MINUTE, new Integer(Calendar.MINUTE));
-            calendarFields.put(HOUR, new Integer(Calendar.HOUR_OF_DAY));
-            calendarFields.put(DAY, new Integer(Calendar.DATE));
-            calendarFields.put(WEEK, new Integer(Calendar.WEEK_OF_YEAR));
-            calendarFields.put(MONTH, new Integer(Calendar.MONTH));
-            calendarFields.put(YEAR, new Integer(Calendar.YEAR));
+                               Integer.valueOf(Calendar.MILLISECOND));
+            calendarFields.put(SECOND, Integer.valueOf(Calendar.SECOND));
+            calendarFields.put(MINUTE, Integer.valueOf(Calendar.MINUTE));
+            calendarFields.put(HOUR, Integer.valueOf(Calendar.HOUR_OF_DAY));
+            calendarFields.put(DAY, Integer.valueOf(Calendar.DATE));
+            calendarFields.put(WEEK, Integer.valueOf(Calendar.WEEK_OF_YEAR));
+            calendarFields.put(MONTH, Integer.valueOf(Calendar.MONTH));
+            calendarFields.put(YEAR, Integer.valueOf(Calendar.YEAR));
         }
 
         /**
@@ -338,14 +358,14 @@
          */
         public int getCalendarField() {
             String key = getValue().toLowerCase(Locale.ENGLISH);
-            Integer i = (Integer) calendarFields.get(key);
-            return i.intValue();
+            return calendarFields.get(key).intValue();
         }
 
         /**
          * Get the valid values.
          * @return the value values.
          */
+        @Override
         public String[] getValues() {
             return UNITS;
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Typedef.java b/src/main/org/apache/tools/ant/taskdefs/Typedef.java
index 87276e2..069cf53 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Typedef.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Typedef.java
@@ -18,8 +18,6 @@
 
 package org.apache.tools.ant.taskdefs;
 
-
-
 /**
  *
  * Adds a data type definition to the current project.
diff --git a/src/main/org/apache/tools/ant/taskdefs/Unpack.java b/src/main/org/apache/tools/ant/taskdefs/Unpack.java
index ccc4577..88ecb8c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Unpack.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Unpack.java
@@ -50,6 +50,7 @@
      * @ant.attribute ignore="true"
      * @param src a <code>String</code> value
      */
+    @Deprecated
     public void setSrc(String src) {
         log("DEPRECATED - The setSrc(String) method has been deprecated."
             + " Use setSrc(File) instead.");
@@ -65,6 +66,7 @@
      * @ant.attribute ignore="true"
      * @param dest a <code>String</code> value
      */
+    @Deprecated
     public void setDest(String dest) {
         log("DEPRECATED - The setDest(String) method has been deprecated."
             + " Use setDest(File) instead.");
@@ -85,22 +87,20 @@
      */
     public void setSrcResource(Resource src) {
         if (!src.isExists()) {
-            throw new BuildException(
-                "the archive " + src.getName() + " doesn't exist");
+            throw new BuildException("the archive %s doesn't exist",
+                src.getName());
         }
         if (src.isDirectory()) {
-            throw new BuildException(
-                "the archive " + src.getName() + " can't be a directory");
+            throw new BuildException("the archive %s can't be a directory",
+                src.getName());
         }
         FileProvider fp = src.as(FileProvider.class);
         if (fp != null) {
             source = fp.getFile();
         } else if (!supportsNonFileResources()) {
             throw new BuildException(
-                "The source " + src.getName()
-                + " is not a FileSystem "
-                + "Only FileSystem resources are"
-                + " supported.");
+                "The source %s is not a FileSystem Only FileSystem resources are supported.",
+                src.getName());
         }
         srcResource = src;
     }
@@ -111,8 +111,8 @@
      */
     public void addConfigured(ResourceCollection a) {
         if (a.size() != 1) {
-            throw new BuildException("only single argument resource collections"
-                                     + " are supported as archives");
+            throw new BuildException(
+                "only single argument resource collections are supported as archives");
         }
         setSrcResource(a.iterator().next());
     }
@@ -163,6 +163,7 @@
      * Execute the task.
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         File savedDest = dest; // may be altered in validate
         try {
@@ -199,7 +200,7 @@
 
     private String getLastNamePart(Resource r) {
         String n = r.getName();
-        int idx = n.lastIndexOf("/");
+        int idx = n.lastIndexOf('/');
         return idx < 0 ? n : n.substring(idx + 1);
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/Untar.java b/src/main/org/apache/tools/ant/taskdefs/Untar.java
index 53b8239..ef8aacf 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Untar.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Untar.java
@@ -20,9 +20,11 @@
 
 import java.io.BufferedInputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.file.Files;
 import java.util.zip.GZIPInputStream;
 
 import org.apache.tools.ant.BuildException;
@@ -35,8 +37,6 @@
 import org.apache.tools.tar.TarEntry;
 import org.apache.tools.tar.TarInputStream;
 
-
-
 /**
  * Untar a file.
  * <p>PatternSets are used to select files to extract
@@ -70,6 +70,7 @@
      *   <li>none - no compression
      *   <li>gzip - Gzip compression
      *   <li>bzip2 - Bzip2 compression
+     *   <li>xz - XZ compression, requires XZ for Java
      * </ul>
      *
      * @param method compression method
@@ -83,33 +84,32 @@
      *
      * @since Ant 1.8.0
      */
+    @Override
     public void setScanForUnicodeExtraFields(boolean b) {
-        throw new BuildException("The " + getTaskName()
-                                 + " task doesn't support the encoding"
-                                 + " attribute", getLocation());
+        throw new BuildException(
+            "The " + getTaskName()
+                + " task doesn't support the encoding attribute",
+            getLocation());
     }
 
     /**
      * @see Expand#expandFile(FileUtils, File, File)
      * {@inheritDoc}
      */
+    @Override
     protected void expandFile(FileUtils fileUtils, File srcF, File dir) {
-        FileInputStream fis = null;
         if (!srcF.exists()) {
             throw new BuildException("Unable to untar "
                     + srcF
                     + " as the file does not exist",
                     getLocation());
         }
-        try {
-            fis = new FileInputStream(srcF);
+        try (InputStream fis = Files.newInputStream(srcF.toPath())) {
             expandStream(srcF.getPath(), fis, dir);
         } catch (IOException ioe) {
             throw new BuildException("Error while expanding " + srcF.getPath()
                                      + "\n" + ioe.toString(),
                                      ioe, getLocation());
-        } finally {
-            FileUtils.close(fis);
         }
     }
 
@@ -120,6 +120,7 @@
      * @param dir       the destination directory
      * @since Ant 1.7
      */
+    @Override
     protected void expandResource(Resource srcR, File dir) {
         if (!srcR.isExists()) {
             throw new BuildException("Unable to untar "
@@ -128,15 +129,11 @@
                                      getLocation());
         }
 
-        InputStream i = null;
-        try {
-            i = srcR.getInputStream();
+        try (InputStream i = srcR.getInputStream()) {
             expandStream(srcR.getName(), i, dir);
         } catch (IOException ioe) {
             throw new BuildException("Error while expanding " + srcR.getName(),
                                      ioe, getLocation());
-        } finally {
-            FileUtils.close(i);
         }
     }
 
@@ -145,16 +142,13 @@
      */
     private void expandStream(String name, InputStream stream, File dir)
         throws IOException {
-        TarInputStream tis = null;
-        try {
-            tis =
-                new TarInputStream(compression.decompress(name,
-                                                          new BufferedInputStream(stream)),
-                                   getEncoding());
+        try (TarInputStream tis = new TarInputStream(
+            compression.decompress(name, new BufferedInputStream(stream)),
+            getEncoding())) {
             log("Expanding: " + name + " into " + dir, Project.MSG_INFO);
-            TarEntry te = null;
             boolean empty = true;
             FileNameMapper mapper = getMapper();
+            TarEntry te;
             while ((te = tis.getNextEntry()) != null) {
                 empty = false;
                 extractFile(FileUtils.getFileUtils(), null, dir, tis,
@@ -162,11 +156,9 @@
                             te.isDirectory(), mapper);
             }
             if (empty && getFailOnEmptyArchive()) {
-                throw new BuildException("archive '" + name + "' is empty");
+                throw new BuildException("archive '%s' is empty", name);
             }
             log("expand complete", Project.MSG_VERBOSE);
-        } finally {
-            FileUtils.close(tis);
         }
     }
 
@@ -190,6 +182,11 @@
          *  BZIP2 compression
          */
         private static final String BZIP2 = "bzip2";
+        /**
+         *  XZ compression
+         * @since 1.10.1
+         */
+        private static final String XZ = "xz";
 
 
         /**
@@ -205,8 +202,9 @@
          *
          * @return valid values
          */
+        @Override
         public String[] getValues() {
-            return new String[] {NONE, GZIP, BZIP2};
+            return new String[] {NONE, GZIP, BZIP2, XZ};
         }
 
         /**
@@ -226,18 +224,41 @@
             final String v = getValue();
             if (GZIP.equals(v)) {
                 return new GZIPInputStream(istream);
-            } else {
-                if (BZIP2.equals(v)) {
-                    final char[] magic = new char[] {'B', 'Z'};
-                    for (int i = 0; i < magic.length; i++) {
-                        if (istream.read() != magic[i]) {
-                            throw new BuildException("Invalid bz2 file." + name);
-                        }
+            }
+            if (XZ.equals(v)) {
+                return newXZInputStream(istream);
+            }
+            if (BZIP2.equals(v)) {
+                final char[] magic = new char[] { 'B', 'Z' };
+                for (int i = 0; i < magic.length; i++) {
+                    if (istream.read() != magic[i]) {
+                        throw new BuildException("Invalid bz2 file." + name);
                     }
-                    return new CBZip2InputStream(istream);
                 }
+                return new CBZip2InputStream(istream);
             }
             return istream;
         }
+
+        private static InputStream newXZInputStream(InputStream istream)
+            throws BuildException {
+            try {
+                Class<? extends InputStream> clazz =
+                    Class.forName("org.tukaani.xz.XZInputStream")
+                    .asSubclass(InputStream.class);
+                Constructor<? extends InputStream> c =
+                    clazz.getConstructor(InputStream.class);
+                return c.newInstance(istream);
+            } catch (ClassNotFoundException ex) {
+                throw new BuildException("xz decompression requires the XZ for Java library",
+                                         ex);
+            } catch (NoSuchMethodException
+                     | InstantiationException
+                     | IllegalAccessException
+                     | InvocationTargetException
+                     ex) {
+                throw new BuildException("failed to create XZInputStream", ex);
+            }
+        }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/UpToDate.java b/src/main/org/apache/tools/ant/taskdefs/UpToDate.java
index e5c85ce..03babd9 100644
--- a/src/main/org/apache/tools/ant/taskdefs/UpToDate.java
+++ b/src/main/org/apache/tools/ant/taskdefs/UpToDate.java
@@ -19,7 +19,8 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
-import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Vector;
 
 import org.apache.tools.ant.BuildException;
@@ -51,7 +52,7 @@
     private String value;
     private File sourceFile;
     private File targetFile;
-    private Vector sourceFileSets = new Vector();
+    private List<FileSet> sourceFileSets = new Vector<>();
     private Union sourceResources = new Union();
 
     // CheckStyle:VisibilityModifier OFF - bc
@@ -110,7 +111,7 @@
      * @param fs the source files
      */
     public void addSrcfiles(final FileSet fs) {
-        sourceFileSets.addElement(fs);
+        sourceFileSets.add(fs);
     }
 
     /**
@@ -150,24 +151,23 @@
      * see if the target(s) is/are up-to-date.
      * @return true if the target(s) is/are up-to-date
      */
+    @Override
     public boolean eval() {
-        if (sourceFileSets.size() == 0 && sourceResources.size() == 0
+        if (sourceFileSets.isEmpty() && sourceResources.isEmpty()
             && sourceFile == null) {
-            throw new BuildException("At least one srcfile or a nested "
-                                     + "<srcfiles> or <srcresources> element "
-                                     + "must be set.");
+            throw new BuildException(
+                "At least one srcfile or a nested <srcfiles> or <srcresources> element must be set.");
         }
 
-        if ((sourceFileSets.size() > 0 || sourceResources.size() > 0)
+        if (!(sourceFileSets.isEmpty() && sourceResources.isEmpty())
             && sourceFile != null) {
-            throw new BuildException("Cannot specify both the srcfile "
-                                     + "attribute and a nested <srcfiles> "
-                                     + "or <srcresources> element.");
+            throw new BuildException(
+                "Cannot specify both the srcfile attribute and a nested <srcfiles> or <srcresources> element.");
         }
 
         if (targetFile == null && mapperElement == null) {
-            throw new BuildException("The targetfile attribute or a nested "
-                                     + "mapper element must be set.");
+            throw new BuildException(
+                "The targetfile attribute or a nested mapper element must be set.");
         }
 
         // if the target file is not there, then it can't be up-to-date
@@ -179,8 +179,8 @@
 
         // if the source file isn't there, throw an exception
         if (sourceFile != null && !sourceFile.exists()) {
-            throw new BuildException(sourceFile.getAbsolutePath()
-                                     + " not found.");
+            throw new BuildException("%s not found.",
+                sourceFile.getAbsolutePath());
         }
 
         boolean upToDate = true;
@@ -204,12 +204,12 @@
         // reasons.  If we use the code for union below, we'll always
         // scan all filesets, even if we know the target is out of
         // date after the first test.
-        Enumeration e = sourceFileSets.elements();
-        while (upToDate && e.hasMoreElements()) {
-            FileSet fs = (FileSet) e.nextElement();
+
+        Iterator<FileSet> iter = sourceFileSets.iterator();
+        while (upToDate && iter.hasNext()) {
+            FileSet fs = iter.next();
             DirectoryScanner ds = fs.getDirectoryScanner(getProject());
-            upToDate = scanDir(fs.getDir(getProject()),
-                                           ds.getIncludedFiles());
+            upToDate = scanDir(fs.getDir(getProject()), ds.getIncludedFiles());
         }
 
         if (upToDate) {
@@ -223,12 +223,12 @@
         return upToDate;
     }
 
-
     /**
      * Sets property to true if target file(s) have a more recent timestamp
      * than (each of) the corresponding source file(s).
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         if (property == null) {
             throw new BuildException("property attribute is required.",
@@ -264,14 +264,11 @@
     }
 
     private FileNameMapper getMapper() {
-        FileNameMapper mapper = null;
         if (mapperElement == null) {
             MergingMapper mm = new MergingMapper();
             mm.setTo(targetFile.getAbsolutePath());
-            mapper = mm;
-        } else {
-            mapper = mapperElement.getImplementation();
+            return mm;
         }
-        return mapper;
+        return mapperElement.getImplementation();
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/VerifyJar.java b/src/main/org/apache/tools/ant/taskdefs/VerifyJar.java
index 4ab2142..5f9c8f3 100644
--- a/src/main/org/apache/tools/ant/taskdefs/VerifyJar.java
+++ b/src/main/org/apache/tools/ant/taskdefs/VerifyJar.java
@@ -45,6 +45,9 @@
      */
     public static final String ERROR_NO_FILE = "Not found :";
 
+    /** Error output if there is a failure to verify the jar. */
+    public static final String ERROR_NO_VERIFY = "Failed to verify ";
+
     /**
      * The string we look for in the text to indicate direct verification
      */
@@ -55,8 +58,6 @@
      */
     private boolean certificates = false;
     private BufferingOutputFilter outputCache = new BufferingOutputFilter();
-    /** Error output if there is a failure to verify the jar. */
-    public static final String ERROR_NO_VERIFY = "Failed to verify ";
 
     /**
      * Ask for certificate information to be printed
@@ -70,6 +71,7 @@
      * verify our jar files
      * @throws BuildException on error.
      */
+    @Override
     public void execute() throws BuildException {
         //validation logic
         final boolean hasJar = jar != null;
@@ -92,11 +94,9 @@
                 FileProvider fr = r.as(FileProvider.class);
                 verifyOneJar(fr.getFile());
             }
-
         } finally {
             endExecution();
         }
-
     }
 
     /**
@@ -135,8 +135,8 @@
         //deal with jdk1.4.2 bug:
         if (ex != null) {
             if (results.indexOf("zip file closed") >= 0) {
-                log("You are running " + JARSIGNER_COMMAND + " against a JVM with"
-                    + " a known bug that manifests as an IllegalStateException.",
+                log("You are running " + JARSIGNER_COMMAND
+                    + " against a JVM with a known bug that manifests as an IllegalStateException.",
                     Project.MSG_WARN);
             } else {
                 throw ex;
@@ -154,11 +154,13 @@
 
         private BufferingOutputFilterReader buffer;
 
+        @Override
         public Reader chain(Reader rdr) {
             buffer = new BufferingOutputFilterReader(rdr);
             return buffer;
         }
 
+        @Override
         public String toString() {
             return buffer.toString();
         }
@@ -183,6 +185,7 @@
             this.next = next;
         }
 
+        @Override
         public int read(char[] cbuf, int off, int len) throws IOException {
             //hand down
             int result = next.read(cbuf, off, len);
@@ -192,10 +195,12 @@
             return result;
         }
 
+        @Override
         public void close() throws IOException {
             next.close();
         }
 
+        @Override
         public String toString() {
             return buffer.toString();
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/WaitFor.java b/src/main/org/apache/tools/ant/taskdefs/WaitFor.java
index 3f94d6f..179b97a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/WaitFor.java
+++ b/src/main/org/apache/tools/ant/taskdefs/WaitFor.java
@@ -89,7 +89,6 @@
         super("waitfor");
     }
 
-
     /**
      * Constructor that takes the name of the task in the task name.
      *
@@ -108,7 +107,6 @@
         maxWait = time;
     }
 
-
     /**
      * Set the max wait time unit
      * @param unit an enumerated <code>Unit</code> value
@@ -117,8 +115,6 @@
         maxWaitMultiplier = unit.getMultiplier();
     }
 
-
-
     /**
      * Set the time between each check
      * @param time a <code>long</code> value
@@ -150,15 +146,15 @@
      */
     public void execute() throws BuildException {
         if (countConditions() > 1) {
-            throw new BuildException("You must not nest more than one "
-                                     + "condition into "
-                                     + getTaskName());
+            throw new BuildException(
+                "You must not nest more than one condition into %s",
+                getTaskName());
         }
         if (countConditions() < 1) {
-            throw new BuildException("You must nest a condition into "
-                                     + getTaskName());
+            throw new BuildException("You must nest a condition into %s",
+                getTaskName());
         }
-        Condition c = (Condition) getConditions().nextElement();
+        Condition c = getConditions().nextElement();
         try {
             long maxWaitMillis = calculateMaxWaitMillis();
             long checkEveryMillis = calculateCheckEveryMillis();
@@ -244,16 +240,16 @@
             MILLISECOND, SECOND, MINUTE, HOUR, DAY, WEEK
         };
 
-        private Map timeTable = new HashMap();
+        private Map<String, Long> timeTable = new HashMap<>();
 
         /** Constructor the Unit enumerated type. */
         public Unit() {
-            timeTable.put(MILLISECOND, new Long(1L));
-            timeTable.put(SECOND,      new Long(ONE_SECOND));
-            timeTable.put(MINUTE,      new Long(ONE_MINUTE));
-            timeTable.put(HOUR,        new Long(ONE_HOUR));
-            timeTable.put(DAY,         new Long(ONE_DAY));
-            timeTable.put(WEEK,        new Long(ONE_WEEK));
+            timeTable.put(MILLISECOND, Long.valueOf(1L));
+            timeTable.put(SECOND,      Long.valueOf(ONE_SECOND));
+            timeTable.put(MINUTE,      Long.valueOf(ONE_MINUTE));
+            timeTable.put(HOUR,        Long.valueOf(ONE_HOUR));
+            timeTable.put(DAY,         Long.valueOf(ONE_DAY));
+            timeTable.put(WEEK,        Long.valueOf(ONE_WEEK));
         }
 
         /**
@@ -262,14 +258,14 @@
          */
         public long getMultiplier() {
             String key = getValue().toLowerCase(Locale.ENGLISH);
-            Long l = (Long) timeTable.get(key);
-            return l.longValue();
+            return timeTable.get(key).longValue();
         }
 
         /**
          * @see EnumeratedAttribute#getValues()
          * {@inheritDoc}
          */
+        @Override
         public String[] getValues() {
             return UNITS;
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/War.java b/src/main/org/apache/tools/ant/taskdefs/War.java
index 7daf08e..146d325 100644
--- a/src/main/org/apache/tools/ant/taskdefs/War.java
+++ b/src/main/org/apache/tools/ant/taskdefs/War.java
@@ -27,7 +27,6 @@
 import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.zip.ZipOutputStream;
 
-
 /**
  * <p>An extension of &lt;jar&gt; to create a WAR archive.
  * Contains special treatment for files that should end up in the
@@ -49,6 +48,10 @@
  */
 public class War extends Jar {
 
+    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+    /** path to web.xml file */
+    private static final String XML_DESCRIPTOR_PATH = "WEB-INF/web.xml";
+
     /**
      * our web.xml deployment descriptor
      */
@@ -60,10 +63,6 @@
     private boolean needxmlfile = true;
     private File addedWebXmlFile;
 
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-    /** path to web.xml file */
-    private static final String XML_DESCRIPTOR_PATH = "WEB-INF/web.xml";
-
     /** Constructor for the War Task. */
     public War() {
         super();
@@ -92,9 +91,8 @@
     public void setWebxml(File descr) {
         deploymentDescriptor = descr;
         if (!deploymentDescriptor.exists()) {
-            throw new BuildException("Deployment descriptor: "
-                                     + deploymentDescriptor
-                                     + " does not exist.");
+            throw new BuildException("Deployment descriptor:  does not exist.",
+                deploymentDescriptor);
         }
 
         // Create a ZipFileSet for this file, and pass it up.
@@ -104,7 +102,6 @@
         super.addFileset(fs);
     }
 
-
     /**
      * Set the policy on the web.xml file, that is, whether or not it is needed
      * @param needxmlfile whether a web.xml file is needed. Default: true
@@ -117,7 +114,6 @@
      * add files under WEB-INF/lib/
      * @param fs the zip file set to add
      */
-
     public void addLib(ZipFileSet fs) {
         // We just set the prefix for this fileset, and pass it up.
         fs.setPrefix("WEB-INF/lib/");
@@ -190,13 +186,10 @@
                 //check to see if we warn or not
                 if (!FILE_UTILS.fileNameEquals(addedWebXmlFile, file)) {
                     logWhenWriting("Warning: selected " + archiveType
-                                   + " files include a second "
-                                   + XML_DESCRIPTOR_PATH
-                                   + " which will be ignored.\n"
-                                   + "The duplicate entry is at " + file + '\n'
-                                   + "The file that will be used is "
-                                   + addedWebXmlFile,
-                                   Project.MSG_WARN);
+                        + " files include a second " + XML_DESCRIPTOR_PATH
+                        + " which will be ignored.\nThe duplicate entry is at "
+                        + file + "\nThe file that will be used is "
+                        + addedWebXmlFile, Project.MSG_WARN);
                 }
             } else {
                 //no added file, yet
@@ -212,7 +205,6 @@
         }
     }
 
-
     /**
      * Make sure we don't think we already have a web.xml next time this task
      * gets executed.
@@ -224,8 +216,8 @@
             && needxmlfile
             && !isInUpdateMode()
             && hasUpdatedFile()) {
-            throw new BuildException("No WEB-INF/web.xml file was added.\n"
-                    + "If this is your intent, set needxmlfile='false' ");
+            throw new BuildException(
+                "No WEB-INF/web.xml file was added.\nIf this is your intent, set needxmlfile='false' ");
         }
         addedWebXmlFile = null;
         super.cleanUp();
diff --git a/src/main/org/apache/tools/ant/taskdefs/WhichResource.java b/src/main/org/apache/tools/ant/taskdefs/WhichResource.java
index 3f315a8..73ad779 100644
--- a/src/main/org/apache/tools/ant/taskdefs/WhichResource.java
+++ b/src/main/org/apache/tools/ant/taskdefs/WhichResource.java
@@ -105,14 +105,11 @@
             setcount++;
         }
 
-
         if (setcount == 0) {
-            throw new BuildException("One of classname or resource must"
-                                     + " be specified");
+            throw new BuildException("One of classname or resource must be specified");
         }
         if (setcount > 1) {
-            throw new BuildException("Only one of classname or resource can"
-                                     + " be specified");
+            throw new BuildException("Only one of classname or resource can be specified");
         }
         if (property == null) {
             throw new BuildException("No property defined");
@@ -123,6 +120,7 @@
      * execute it
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         validate();
         if (classpath != null) {
@@ -135,11 +133,10 @@
             getProject().log("using system classpath: " + classpath,
                              Project.MSG_DEBUG);
         }
-        AntClassLoader loader = null;
-        try {
-            loader = AntClassLoader.newAntClassLoader(getProject().getCoreLoader(),
-                                                      getProject(),
-                                                      classpath, false);
+        try (AntClassLoader loader =
+             AntClassLoader.newAntClassLoader(getProject().getCoreLoader(),
+                                              getProject(),
+                                              classpath, false)) {
             String loc = null;
             if (classname != null) {
                 //convert a class name into a resource
@@ -155,17 +152,12 @@
             }
 
             log("Searching for " + resource, Project.MSG_VERBOSE);
-            URL url;
-            url = loader.getResource(resource);
+            URL url = loader.getResource(resource);
             if (url != null) {
                 //set the property
                 loc = url.toExternalForm();
                 getProject().setNewProperty(property, loc);
             }
-        } finally {
-            if (loader != null) {
-                loader.cleanup();
-            }
         }
     }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java b/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java
index 8394314..c341dc8 100644
--- a/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java
+++ b/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java
@@ -18,6 +18,7 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.EnumMap;
@@ -32,7 +33,6 @@
 import javax.xml.xpath.XPathExpression;
 import javax.xml.xpath.XPathExpressionException;
 import javax.xml.xpath.XPathFactory;
-import javax.xml.xpath.XPathVariableResolver;
 
 import org.apache.tools.ant.AntClassLoader;
 import org.apache.tools.ant.BuildException;
@@ -71,6 +71,15 @@
  */
 
 public class XSLTProcess extends MatchingTask implements XSLTLogger {
+    /**
+     * The default processor is trax
+     * @since Ant 1.7
+     */
+    public static final String PROCESSOR_TRAX = "trax";
+
+    /** Utilities used for file operations */
+    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
     /** destination directory */
     private File destDir = null;
 
@@ -93,7 +102,7 @@
     private String fileDirParameter = null;
 
     /** additional parameters to be passed to the stylesheets */
-    private final List<Param> params = new ArrayList<Param>();
+    private final List<Param> params = new ArrayList<>();
 
     /** Input XML document to be used */
     private File inFile = null;
@@ -119,14 +128,11 @@
     private boolean force = false;
 
     /** XSL output properties to be used */
-    private final Vector outputProperties = new Vector();
+    private final List<OutputProperty> outputProperties = new Vector<>();
 
     /** for resolving entities such as dtds */
     private final XMLCatalog xmlCatalog = new XMLCatalog();
 
-    /** Utilities used for file operations */
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-
     /**
      * Whether to style all files in the included directories as well.
      *
@@ -180,12 +186,6 @@
     private boolean useImplicitFileset = true;
 
     /**
-     * The default processor is trax
-     * @since Ant 1.7
-     */
-    public static final String PROCESSOR_TRAX = "trax";
-
-    /**
      * whether to suppress warnings.
      *
      * @since Ant 1.8.0
@@ -243,12 +243,6 @@
     private TraceConfiguration traceConfiguration;
 
     /**
-     * Creates a new XSLTProcess Task.
-     */
-    public XSLTProcess() {
-    } //-- XSLTProcess
-
-    /**
      * Whether to style all files in the included directories as well;
      * optional, default is true.
      *
@@ -303,8 +297,8 @@
      */
     public void addConfiguredStyle(final Resources rc) {
         if (rc.size() != 1) {
-            handleError("The style element must be specified with exactly one"
-                        + " nested resource.");
+            handleError(
+                "The style element must be specified with exactly one nested resource.");
         } else {
             setXslResource(rc.iterator().next());
         }
@@ -345,13 +339,8 @@
         }
         final File savedBaseDir = baseDir;
 
-        DirectoryScanner scanner;
-        String[]         list;
-        String[]         dirs;
-
         final String baseMessage =
-            "specify the stylesheet either as a filename in style attribute "
-            + "or as a nested resource";
+            "specify the stylesheet either as a filename in style attribute or as a nested resource";
 
         if (xslResource == null && xslFile == null) {
             handleError(baseMessage);
@@ -395,8 +384,7 @@
                      * the wrong version has been used.
                      */
                     if (alternative.exists()) {
-                        log("DEPRECATED - the 'style' attribute should be "
-                            + "relative to the project's");
+                        log("DEPRECATED - the 'style' attribute should be relative to the project's");
                         log("             basedir, not the tasks's basedir.");
                         stylesheet = alternative;
                     }
@@ -427,33 +415,30 @@
             //-- make sure destination directory exists...
             checkDest();
 
+
             if (useImplicitFileset) {
-                scanner = getDirectoryScanner(baseDir);
+                DirectoryScanner scanner = getDirectoryScanner(baseDir);
                 log("Transforming into " + destDir, Project.MSG_INFO);
 
                 // Process all the files marked for styling
-                list = scanner.getIncludedFiles();
-                for (int i = 0; i < list.length; ++i) {
-                    process(baseDir, list[i], destDir, styleResource);
+                for (String element : scanner.getIncludedFiles()) {
+                    process(baseDir, element, destDir, styleResource);
                 }
                 if (performDirectoryScan) {
                     // Process all the directories marked for styling
-                    dirs = scanner.getIncludedDirectories();
-                    for (int j = 0; j < dirs.length; ++j) {
-                        list = new File(baseDir, dirs[j]).list();
-                        for (int i = 0; i < list.length; ++i) {
-                            process(baseDir, dirs[j] + File.separator + list[i], destDir,
+                    for (String dir : scanner.getIncludedDirectories()) {
+                        for (String element : new File(baseDir, dir).list()) {
+                            process(baseDir, dir + File.separator + element, destDir,
                                     styleResource);
                         }
                     }
                 }
-            } else { // only resource collections, there better be some
-                if (resources.size() == 0) {
-                    if (failOnNoResources) {
-                        handleError("no resources specified");
-                    }
-                    return;
+            } else if (resources.isEmpty()) {
+                // only resource collections, there better be some
+                if (failOnNoResources) {
+                    handleError("no resources specified");
                 }
+                return;
             }
             processResources(styleResource);
         } finally {
@@ -686,8 +671,7 @@
      */
     public TraceConfiguration createTrace() {
         if (traceConfiguration != null) {
-            throw new BuildException("can't have more than one trace"
-                                     + " configuration");
+            throw new BuildException("can't have more than one trace configuration");
         }
         traceConfiguration = new TraceConfiguration();
         return traceConfiguration;
@@ -712,12 +696,12 @@
      * @exception Exception if the processor cannot be loaded.
      */
     private void resolveProcessor(final String proc) throws Exception {
-        if (proc.equals(PROCESSOR_TRAX)) {
+        if (PROCESSOR_TRAX.equals(proc)) {
             liaison = new org.apache.tools.ant.taskdefs.optional.TraXLiaison();
         } else {
             //anything else is a classname
-            final Class clazz = loadClass(proc);
-            liaison = (XSLTLiaison) clazz.newInstance();
+            final Class<? extends XSLTLiaison> clazz = loadClass(proc).asSubclass(XSLTLiaison.class);
+            liaison = clazz.newInstance();
         }
     }
 
@@ -729,7 +713,7 @@
      * @param classname the name of the class to load.
      * @return the requested class.
      */
-    private Class loadClass(final String classname) throws ClassNotFoundException {
+    private Class<?> loadClass(final String classname) throws ClassNotFoundException {
         setupLoader();
         if (loader == null) {
             return Class.forName(classname);
@@ -819,29 +803,25 @@
             throws BuildException {
 
         File   outF = null;
-        File   inF = null;
 
         try {
             final long styleSheetLastModified = stylesheet.getLastModified();
-            inF = new File(baseDir, xmlFile);
+            File inF = new File(baseDir, xmlFile);
 
             if (inF.isDirectory()) {
                 log("Skipping " + inF + " it is a directory.", Project.MSG_VERBOSE);
                 return;
             }
-            FileNameMapper mapper = null;
-            if (mapperElement != null) {
-                mapper = mapperElement.getImplementation();
-            } else {
-                mapper = new StyleMapper();
-            }
+            FileNameMapper mapper = mapperElement == null ? new StyleMapper()
+                : mapperElement.getImplementation();
 
             final String[] outFileName = mapper.mapFileName(xmlFile);
             if (outFileName == null || outFileName.length == 0) {
                 log("Skipping " + inFile + " it cannot get mapped to output.", Project.MSG_VERBOSE);
                 return;
-            } else if (outFileName.length > 1) {
-                log("Skipping " + inFile + " its mapping is ambiguos.", Project.MSG_VERBOSE);
+            }
+            if (outFileName.length > 1) {
+                log("Skipping " + inFile + " its mapping is ambiguous.", Project.MSG_VERBOSE);
                 return;
             }
             outF = new File(destDir, outFileName[0]);
@@ -939,8 +919,8 @@
      * Get an enumeration on the outputproperties.
      * @return the outputproperties
      */
-    public Enumeration getOutputProperties() {
-        return outputProperties.elements();
+    public Enumeration<OutputProperty> getOutputProperties() {
+        return Collections.enumeration(outputProperties);
     }
 
     /**
@@ -1185,7 +1165,7 @@
      */
     public OutputProperty createOutputProperty() {
         final OutputProperty p = new OutputProperty();
-        outputProperties.addElement(p);
+        outputProperties.add(p);
         return p;
     }
 
@@ -1246,11 +1226,8 @@
 
         xpathFactory = XPathFactory.newInstance();
         xpath = xpathFactory.newXPath();
-        xpath.setXPathVariableResolver(new XPathVariableResolver() {
-            public Object resolveVariable(final QName variableName) {
-                return getProject().getProperty(variableName.toString());
-            }
-        });
+        xpath.setXPathVariableResolver(
+            variableName -> getProject().getProperty(variableName.toString()));
     }
 
     /**
@@ -1310,16 +1287,15 @@
                 if (p.shouldUse()) {
                     final Object evaluatedParam = evaluateParam(p);
                     if (liaison instanceof XSLTLiaison4) {
-                        ((XSLTLiaison4) liaison).addParam(p.getName(), evaluatedParam);
+                        ((XSLTLiaison4) liaison).addParam(p.getName(),
+                            evaluatedParam);
+                    } else if (evaluatedParam == null || evaluatedParam instanceof String) {
+                        liaison.addParam(p.getName(), (String) evaluatedParam);
                     } else {
-                        if (evaluatedParam == null || evaluatedParam instanceof String) {
-                            liaison.addParam(p.getName(), (String) evaluatedParam);
-                        } else {
-                            log("XSLTLiaison '" + liaison.getClass().getName()
-                                    + "' supports only String parameters. Converting parameter '" + p.getName()
-                                    + "' to its String value '" + evaluatedParam, Project.MSG_WARN);
-                            liaison.addParam(p.getName(), String.valueOf(evaluatedParam));
-                        }
+                        log("XSLTLiaison '" + liaison.getClass().getName()
+                                + "' supports only String parameters. Converting parameter '" + p.getName()
+                                + "' to its String value '" + evaluatedParam, Project.MSG_WARN);
+                        liaison.addParam(p.getName(), String.valueOf(evaluatedParam));
                     }
                 }
             }
@@ -1346,7 +1322,7 @@
 
         ParamType type;
 
-        if (typeName == null || "".equals(typeName)) {
+        if (typeName == null || typeName.isEmpty()) {
             type = ParamType.STRING; // String is default
         } else {
             try {
@@ -1371,11 +1347,10 @@
                 final QName xpathType = ParamType.XPATH_TYPES.get(type);
                 if (xpathType == null) {
                     throw new IllegalArgumentException("Invalid XSLT parameter type: " + typeName);
-                } else {
-                    final XPathExpression xpe = xpath.compile(expression);
-                    // null = evaluate XPath on empty XML document
-                    return xpe.evaluate((Object) null, xpathType);
                 }
+                final XPathExpression xpe = xpath.compile(expression);
+                // null = evaluate XPath on empty XML document
+                return xpe.evaluate((Object) null, xpathType);
         }
     }
 
@@ -1444,9 +1419,8 @@
     protected void handleError(final Throwable ex) {
         if (failOnError) {
             throw new BuildException(ex);
-        } else {
-            log("Caught an exception: " + ex, Project.MSG_WARN);
         }
+        log("Caught an exception: " + ex, Project.MSG_WARN);
     }
 
     /**
@@ -1460,10 +1434,9 @@
     protected void handleTransformationError(final Exception ex) {
         if (failOnError && failOnTransformationError) {
             throw new BuildException(ex);
-        } else {
-            log("Caught an error during transformation: " + ex,
-                Project.MSG_WARN);
         }
+        log("Caught an error during transformation: " + ex,
+            Project.MSG_WARN);
     }
 
     /**
@@ -1478,12 +1451,12 @@
         /**
          * the list of factory attributes to use for TraXLiaison
          */
-        private final List<Attribute> attributes = new ArrayList<Attribute>();
+        private final List<Attribute> attributes = new ArrayList<>();
 
         /**
          * the list of factory features to use for TraXLiaison
          */
-        private final List<Feature> features = new ArrayList<Feature>();
+        private final List<Feature> features = new ArrayList<>();
 
         /**
          * @return the name of the factory.
@@ -1512,7 +1485,7 @@
          * return the attribute elements.
          * @return the enumeration of attributes
          */
-        public Enumeration getAttributes() {
+        public Enumeration<Attribute> getAttributes() {
             return Collections.enumeration(attributes);
         }
 
@@ -1543,8 +1516,7 @@
          *  <li>http://xml.apache.org/xalan/features/incremental (true|false) </li>
          * </ul>
          */
-        public static class Attribute
-            extends ProjectComponent
+        public static class Attribute extends ProjectComponent
             implements DynamicConfigurator {
 
             /** attribute name, mostly processor specific */
@@ -1573,6 +1545,7 @@
              * @return null
              * @throws BuildException never
              */
+            @Override
             public Object createDynamicElement(final String name) throws BuildException {
                 return null;
             }
@@ -1584,6 +1557,7 @@
              * @param value the value of the attribute
              * @throws BuildException on error
              */
+            @Override
             public void setDynamicAttribute(final String name, final String value) throws BuildException {
                 // only 'name' and 'value' exist.
                 if ("name".equalsIgnoreCase(name)) {
@@ -1597,7 +1571,7 @@
                         this.value = Boolean.FALSE;
                     } else {
                         try {
-                            this.value = new Integer(value);
+                            this.value = Integer.valueOf(value);
                         } catch (final NumberFormatException e) {
                             this.value = value;
                         }
@@ -1610,7 +1584,7 @@
                                                              new Reference(getProject(),
                                                                            value));
                 } else {
-                    throw new BuildException("Unsupported attribute: " + name);
+                    throw new BuildException("Unsupported attribute: %s", name);
                 }
             }
         } // -- class Attribute
@@ -1623,7 +1597,9 @@
             private String name;
             private boolean value;
 
-            public Feature() { }
+            public Feature() {
+            }
+
             public Feature(String name, boolean value) {
                 this.name = name;
                 this.value = value;
@@ -1669,10 +1645,15 @@
      * @since Ant 1.6.2
      */
     private class StyleMapper implements FileNameMapper {
+        @Override
         public void setFrom(final String from) {
         }
+
+        @Override
         public void setTo(final String to) {
         }
+
+        @Override
         public String[] mapFileName(String xmlFile) {
             final int dotPos = xmlFile.lastIndexOf('.');
             if (dotPos > 0) {
@@ -1795,7 +1776,7 @@
          *
          * @return OutputStream
          */
-        public java.io.OutputStream getOutputStream() {
+        public OutputStream getOutputStream() {
             return new LogOutputStream(XSLTProcess.this);
         }
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/XmlProperty.java b/src/main/org/apache/tools/ant/taskdefs/XmlProperty.java
index 6f64a88..e73a221 100644
--- a/src/main/org/apache/tools/ant/taskdefs/XmlProperty.java
+++ b/src/main/org/apache/tools/ant/taskdefs/XmlProperty.java
@@ -19,7 +19,9 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Hashtable;
+import java.util.Map;
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -175,19 +177,6 @@
  * @ant.task name="xmlproperty" category="xml"
  */
 public class XmlProperty extends org.apache.tools.ant.Task {
-
-    private Resource src;
-    private String prefix = "";
-    private boolean keepRoot = true;
-    private boolean validate = false;
-    private boolean collapseAttributes = false;
-    private boolean semanticAttributes = false;
-    private boolean includeSemanticAttribute = false;
-    private File rootDirectory = null;
-    private Hashtable addedAttributes = new Hashtable();
-    private XMLCatalog xmlCatalog = new XMLCatalog();
-    private String delimiter = ",";
-
     private static final String ID = "id";
     private static final String REF_ID = "refid";
     private static final String LOCATION = "location";
@@ -200,17 +189,22 @@
 
     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
 
-    /**
-     * Constructor.
-     */
-    public XmlProperty() {
-        super();
-    }
+    private Resource src;
+    private String prefix = "";
+    private boolean keepRoot = true;
+    private boolean validate = false;
+    private boolean collapseAttributes = false;
+    private boolean semanticAttributes = false;
+    private boolean includeSemanticAttribute = false;
+    private File rootDirectory = null;
+    private Map<String, String> addedAttributes = new Hashtable<>();
+    private XMLCatalog xmlCatalog = new XMLCatalog();
+    private String delimiter = ",";
 
     /**
      * Initializes the task.
      */
-
+    @Override
     public void init() {
         super.init();
         xmlCatalog.setProject(getProject());
@@ -229,6 +223,7 @@
      * @todo validate the source file is valid before opening, print a better error message
      * @todo add a verbose level log message listing the name of the file being loaded
      */
+    @Override
     public void execute() throws BuildException {
         Resource r = getResource();
 
@@ -245,7 +240,7 @@
               factory.setNamespaceAware(false);
               DocumentBuilder builder = factory.newDocumentBuilder();
               builder.setEntityResolver(getEntityResolver());
-              Document document = null;
+              Document document;
               FileProvider fp = src.as(FileProvider.class);
               if (fp != null) {
                   document = builder.parse(fp.getFile());
@@ -258,7 +253,7 @@
               // This task is allow to override its own properties
               // but not other properties.  So we need to keep track
               // of which properties we've added.
-              addedAttributes = new Hashtable();
+              addedAttributes = new Hashtable<>();
 
               if (keepRoot) {
                   addNodeRecursively(topElement, prefix, null);
@@ -377,23 +372,23 @@
                      * semantic meaning) then deal with it
                      * appropriately.
                      */
-                    if (nodeName.equals(ID)) {
+                    if (ID.equals(nodeName)) {
                         // ID has already been found above.
                         continue;
                     }
-                    if (containingPath != null && nodeName.equals(PATH)) {
+                    if (containingPath != null && PATH.equals(nodeName)) {
                         // A "path" attribute for a node within a Path object.
                         containingPath.setPath(attributeValue);
                     } else if (containingPath != null
-                               && container instanceof Path && nodeName.equals(REF_ID)) {
+                               && container instanceof Path && REF_ID.equals(nodeName)) {
                         // A "refid" attribute for a node within a Path object.
                         containingPath.setPath(attributeValue);
                     } else if (containingPath != null && container instanceof Path
-                               && nodeName.equals(LOCATION)) {
+                               && LOCATION.equals(nodeName)) {
                         // A "location" attribute for a node within a
                         // Path object.
                         containingPath.setLocation(resolveFile(attributeValue));
-                    } else if (nodeName.equals(PATHID)) {
+                    } else if (PATHID.equals(nodeName)) {
                         // A node identifying a new path
                         if (container != null) {
                             throw new BuildException("XmlProperty does not support nested paths");
@@ -429,7 +424,7 @@
                 && node.getFirstChild().getNodeType() == Node.CDATA_SECTION_NODE) {
 
             nodeText = node.getFirstChild().getNodeValue();
-            if ("".equals(nodeText) && !semanticEmptyOverride) {
+            if (nodeText.isEmpty() && !semanticEmptyOverride) {
                 emptyNode = true;
             }
         } else if (node.getNodeType() == Node.ELEMENT_NODE
@@ -440,7 +435,7 @@
         } else if (node.getNodeType() == Node.ELEMENT_NODE
                && node.getChildNodes().getLength() == 1
                && node.getFirstChild().getNodeType() == Node.TEXT_NODE
-               && "".equals(node.getFirstChild().getNodeValue())
+               && node.getFirstChild().getNodeValue().isEmpty()
                && !semanticEmptyOverride) {
             nodeText = "";
             emptyNode = true;
@@ -450,7 +445,7 @@
             if (semanticAttributes && id == null && container instanceof String) {
                 id = (String) container;
             }
-            if (nodeText.trim().length() != 0 || emptyNode) {
+            if (!nodeText.trim().isEmpty() || emptyNode) {
                 addProperty(prefix, nodeText, id);
             }
         }
@@ -458,7 +453,7 @@
         // children to reference if needed.  Path objects are
         // definitely used by child path elements, and ID may be used
         // for a child text node.
-        return (addedPath != null ? addedPath : id);
+        return addedPath != null ? addedPath : id;
     }
 
     /**
@@ -481,7 +476,7 @@
             // when we read them, though (instead of keeping them
             // outside of the project and batch adding them at the end)
             // to allow other properties to reference them.
-            value = (String) addedAttributes.get(name) + getDelimiter() + value;
+            value = addedAttributes.get(name) + getDelimiter() + value;
             getProject().setProperty(name, value);
             addedAttributes.put(name, value);
         } else if (getProject().getProperty(name) == null) {
@@ -508,7 +503,7 @@
         if (semanticAttributes) {
             // Never include the "refid" attribute as part of the
             // attribute name.
-            if (attributeName.equals(REF_ID)) {
+            if (REF_ID.equals(attributeName)) {
                 return "";
             }
             // Otherwise, return it appended unless property to hide it is set.
@@ -524,12 +519,7 @@
      * Return whether the provided attribute name is recognized or not.
      */
     private static boolean isSemanticAttribute(String attributeName) {
-        for (int i = 0; i < ATTRIBUTES.length; i++) {
-            if (attributeName.equals(ATTRIBUTES[i])) {
-                return true;
-            }
-        }
-        return false;
+        return Arrays.asList(ATTRIBUTES).contains(attributeName);
     }
 
     /**
@@ -549,11 +539,11 @@
         if (semanticAttributes) {
             String attributeName = attributeNode.getNodeName();
             nodeValue = getProject().replaceProperties(nodeValue);
-            if (attributeName.equals(LOCATION)) {
+            if (LOCATION.equals(attributeName)) {
                 File f = resolveFile(nodeValue);
                 return f.getPath();
             }
-            if (attributeName.equals(REF_ID)) {
+            if (REF_ID.equals(attributeName)) {
                 Object ref = getProject().getReference(nodeValue);
                 if (ref != null) {
                     return ref.toString();
diff --git a/src/main/org/apache/tools/ant/taskdefs/Zip.java b/src/main/org/apache/tools/ant/taskdefs/Zip.java
index 5bcbe73..1673278 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Zip.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Zip.java
@@ -19,22 +19,22 @@
 
 import java.io.BufferedInputStream;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.file.Files;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Map;
 import java.util.Stack;
 import java.util.Vector;
+import java.util.stream.Stream;
 import java.util.zip.CRC32;
 
 import org.apache.tools.ant.BuildException;
@@ -44,7 +44,6 @@
 import org.apache.tools.ant.types.ArchiveFileSet;
 import org.apache.tools.ant.types.EnumeratedAttribute;
 import org.apache.tools.ant.types.FileSet;
-import org.apache.tools.ant.types.PatternSet;
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.types.ResourceCollection;
 import org.apache.tools.ant.types.ZipFileSet;
@@ -86,13 +85,24 @@
     private static final int ROUNDUP_MILLIS = ZIP_FILE_TIMESTAMP_GRANULARITY - 1;
     // CheckStyle:VisibilityModifier OFF - bc
 
+    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+    // For directories:
+    private static final long EMPTY_CRC = new CRC32().getValue();
+
+    private static final ResourceSelector MISSING_SELECTOR =
+            target -> !target.isExists();
+
+    private static final ResourceUtils.ResourceSelectorProvider
+        MISSING_DIR_PROVIDER = sr -> MISSING_SELECTOR;
+
     protected File zipFile;
     // use to scan own archive
     private ZipScanner zs;
     private File baseDir;
-    protected Hashtable<String, String> entries = new Hashtable<String, String>();
-    private final Vector<FileSet> groupfilesets = new Vector<FileSet>();
-    private final Vector<ZipFileSet> filesetsFromGroupfilesets = new Vector<ZipFileSet>();
+    protected Hashtable<String, String> entries = new Hashtable<>();
+    private final List<FileSet> groupfilesets = new Vector<>();
+    private final List<ZipFileSet> filesetsFromGroupfilesets = new Vector<>();
     protected String duplicate = "add";
     private boolean doCompress = true;
     private boolean doUpdate = false;
@@ -101,27 +111,10 @@
     private boolean doFilesonly = false;
     protected String archiveType = "zip";
 
-    // For directories:
-    private static final long EMPTY_CRC = new CRC32().getValue();
     protected String emptyBehavior = "skip";
-    private final Vector<ResourceCollection> resources = new Vector<ResourceCollection>();
-    protected Hashtable<String, String> addedDirs = new Hashtable<String, String>();
-    private final Vector<String> addedFiles = new Vector<String>();
-
-    private static final ResourceSelector MISSING_SELECTOR =
-        new ResourceSelector() {
-            public boolean isSelected(final Resource target) {
-                return !target.isExists();
-            }
-        };
-
-    private static final ResourceUtils.ResourceSelectorProvider
-        MISSING_DIR_PROVIDER = new ResourceUtils.ResourceSelectorProvider() {
-                public ResourceSelector
-                    getTargetSelectorForSource(final Resource sr) {
-                    return MISSING_SELECTOR;
-                }
-            };
+    private final List<ResourceCollection> resources = new Vector<>();
+    protected Hashtable<String, String> addedDirs = new Hashtable<>();
+    private final List<String> addedFiles = new Vector<>();
 
     private String fixedModTime = null; // User-provided.
     private long modTimeMillis = 0; // Calculated.
@@ -157,8 +150,6 @@
         return !doubleFilePass || skipWriting;
     }
 
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-
     // CheckStyle:VisibilityModifier ON
 
     // This boolean is set if the task detects that the
@@ -368,7 +359,7 @@
      * @param set the group (a fileset) to add
      */
     public void addZipGroupFileset(final FileSet set) {
-        groupfilesets.addElement(set);
+        groupfilesets.add(set);
     }
 
     /**
@@ -606,7 +597,7 @@
      *        that you must choose one of a or b, and [c] indicates that you
      *        may use or omit c. &plusmn;ZZZZ is the timezone offset, and may be
      *        literally "Z" to mean GMT.
-     * @since Ant 1.9.10
+     * @since Ant 1.10.2
      */
     public void setModificationtime(String time) {
         fixedModTime = time;
@@ -616,7 +607,7 @@
      * The file modification time previously provided to
      * {@link #setModificationtime(String)} or {@code null} if unset.
      * @return String
-     * @since Ant 1.9.10
+     * @since Ant 1.10.2
      */
     public String getModificationtime() {
         return fixedModTime;
@@ -666,20 +657,17 @@
         processGroupFilesets();
 
         // collect filesets to pass them to getResourcesToAdd
-        final Vector<ResourceCollection> vfss = new Vector<ResourceCollection>();
+        final List<ResourceCollection> vfss = new ArrayList<>();
         if (baseDir != null) {
-            final FileSet fs = (FileSet) getImplicitFileSet().clone();
+            final FileSet fs = getImplicitFileSet().clone();
             fs.setDir(baseDir);
-            vfss.addElement(fs);
+            vfss.add(fs);
         }
-        final int size = resources.size();
-        for (int i = 0; i < size; i++) {
-            final ResourceCollection rc = resources.elementAt(i);
-            vfss.addElement(rc);
-        }
+        vfss.addAll(resources);
 
-        final ResourceCollection[] fss = new ResourceCollection[vfss.size()];
-        vfss.copyInto(fss);
+        final ResourceCollection[] fss =
+            vfss.toArray(new ResourceCollection[vfss.size()]);
+
         boolean success = false;
         try {
             // can also handle empty archives
@@ -693,8 +681,9 @@
             final File parent = zipFile.getParentFile();
             if (parent != null && !parent.isDirectory()
                 && !(parent.mkdirs() || parent.isDirectory())) {
-                throw new BuildException("Failed to create missing parent"
-                                         + " directory for " + zipFile);
+                throw new BuildException(
+                    "Failed to create missing parent directory for %s",
+                    zipFile);
             }
 
             updatedFile = true;
@@ -745,32 +734,25 @@
                     oldFiles.setSrc(renamedFile);
                     oldFiles.setDefaultexcludes(false);
 
-                    final int addSize = addedFiles.size();
-                    for (int i = 0; i < addSize; i++) {
-                        final PatternSet.NameEntry ne = oldFiles.createExclude();
-                        ne.setName(addedFiles.elementAt(i));
+                    for (String addedFile : addedFiles) {
+                        oldFiles.createExclude().setName(addedFile);
                     }
                     final DirectoryScanner ds =
                         oldFiles.getDirectoryScanner(getProject());
                     ((ZipScanner) ds).setEncoding(encoding);
 
-                    final String[] f = ds.getIncludedFiles();
-                    Resource[] r = new Resource[f.length];
-                    for (int i = 0; i < f.length; i++) {
-                        r[i] = ds.getResource(f[i]);
-                    }
+                    Stream<String> includedResourceNames =
+                        Stream.of(ds.getIncludedFiles());
 
                     if (!doFilesonly) {
-                        final String[] d = ds.getIncludedDirectories();
-                        final Resource[] dr = new Resource[d.length];
-                        for (int i = 0; i < d.length; i++) {
-                            dr[i] = ds.getResource(d[i]);
-                        }
-                        final Resource[] tmp = r;
-                        r = new Resource[tmp.length + dr.length];
-                        System.arraycopy(dr, 0, r, 0, dr.length);
-                        System.arraycopy(tmp, 0, r, dr.length, tmp.length);
+                        includedResourceNames =
+                            Stream.concat(includedResourceNames,
+                                Stream.of(ds.getIncludedDirectories()));
                     }
+
+                    Resource[] r = includedResourceNames.map(ds::getResource)
+                        .toArray(Resource[]::new);
+
                     addResources(oldFiles, r, zOut);
                 }
                 if (zOut != null) {
@@ -822,16 +804,10 @@
             "zip", ".tmp", zipFile.getParentFile(), true, false);
         try {
             FILE_UTILS.rename(zipFile, renamedFile);
-        } catch (final SecurityException e) {
+        } catch (final SecurityException | IOException e) {
             throw new BuildException(
-                "Not allowed to rename old file ("
-                + zipFile.getAbsolutePath()
-                + ") to temporary file");
-        } catch (final IOException e) {
-            throw new BuildException(
-                "Unable to rename old file ("
-                + zipFile.getAbsolutePath()
-                + ") to temporary file");
+                "Unable to rename old file (%s) to temporary file",
+                zipFile.getAbsolutePath());
         }
         return renamedFile;
     }
@@ -862,23 +838,22 @@
 
     /** Check the attributes and elements */
     private void checkAttributesAndElements() {
-        if (baseDir == null && resources.size() == 0
-            && groupfilesets.size() == 0 && "zip".equals(archiveType)) {
-            throw new BuildException("basedir attribute must be set, "
-                                     + "or at least one "
-                                     + "resource collection must be given!");
+        if (baseDir == null && resources.isEmpty() && groupfilesets.isEmpty()
+            && "zip".equals(archiveType)) {
+            throw new BuildException(
+                "basedir attribute must be set, or at least one resource collection must be given!");
         }
 
         if (zipFile == null) {
-            throw new BuildException("You must specify the "
-                                     + archiveType + " file to create!");
+            throw new BuildException("You must specify the %s file to create!",
+                archiveType);
         }
 
         if (fixedModTime != null) {
             try {
                 modTimeMillis = DateUtils.parseLenientDateTime(fixedModTime).getTime();
             } catch (ParseException pe) {
-                throw new BuildException("Failed to parse date string " + fixedModTime + ".");
+                throw new BuildException("Failed to parse date string %s.", fixedModTime);
             }
             if (roundUp) {
                 modTimeMillis += ROUNDUP_MILLIS;
@@ -886,11 +861,11 @@
         }
 
         if (zipFile.exists() && !zipFile.isFile()) {
-            throw new BuildException(zipFile + " is not a file.");
+            throw new BuildException("%s is not a file.", zipFile);
         }
 
         if (zipFile.exists() && !zipFile.canWrite()) {
-            throw new BuildException(zipFile + " is read-only.");
+            throw new BuildException("%s is read-only.", zipFile);
         }
     }
 
@@ -908,23 +883,18 @@
     /** Process groupfilesets */
     private void processGroupFilesets() {
         // Add the files found in groupfileset to fileset
-        final int size = groupfilesets.size();
-        for (int i = 0; i < size; i++) {
-
+        for (FileSet fs : groupfilesets) {
             logWhenWriting("Processing groupfileset ", Project.MSG_VERBOSE);
-            final FileSet fs = groupfilesets.elementAt(i);
             final FileScanner scanner = fs.getDirectoryScanner(getProject());
-            final String[] files = scanner.getIncludedFiles();
             final File basedir = scanner.getBasedir();
-            for (int j = 0; j < files.length; j++) {
-
-                logWhenWriting("Adding file " + files[j] + " to fileset",
+            for (String file : scanner.getIncludedFiles()) {
+                logWhenWriting("Adding file " + file + " to fileset",
                                Project.MSG_VERBOSE);
                 final ZipFileSet zf = new ZipFileSet();
                 zf.setProject(getProject());
-                zf.setSrc(new File(basedir, files[j]));
+                zf.setSrc(new File(basedir, file));
                 add(zf);
-                filesetsFromGroupfilesets.addElement(zf);
+                filesetsFromGroupfilesets.add(zf);
             }
         }
     }
@@ -968,17 +938,16 @@
         }
 
         if (prefix.length() > 0 && fullpath.length() > 0) {
-            throw new BuildException("Both prefix and fullpath attributes must"
-                                     + " not be set on the same fileset.");
+            throw new BuildException(
+                "Both prefix and fullpath attributes must not be set on the same fileset.");
         }
 
         if (resources.length != 1 && fullpath.length() > 0) {
-            throw new BuildException("fullpath attribute may only be specified"
-                                     + " for filesets that specify a single"
-                                     + " file.");
+            throw new BuildException(
+                "fullpath attribute may only be specified for filesets that specify a single file.");
         }
 
-        if (prefix.length() > 0) {
+        if (!prefix.isEmpty()) {
             if (!prefix.endsWith("/") && !prefix.endsWith("\\")) {
                 prefix += "/";
             }
@@ -997,26 +966,26 @@
                 zf = new ZipFile(zfs.getSrc(getProject()), encoding);
             }
 
-            for (int i = 0; i < resources.length; i++) {
-                String name = null;
-                if (fullpath.length() > 0) {
-                    name = fullpath;
+            for (Resource resource : resources) {
+                String name;
+                if (fullpath.isEmpty()) {
+                    name = resource.getName();
                 } else {
-                    name = resources[i].getName();
+                    name = fullpath;
                 }
                 name = name.replace(File.separatorChar, '/');
 
-                if ("".equals(name)) {
+                if (name.isEmpty()) {
                     continue;
                 }
 
-                if (resources[i].isDirectory()) {
+                if (resource.isDirectory()) {
                     if (doFilesonly) {
                         continue;
                     }
                     final int thisDirMode = zfs != null && zfs.hasDirModeBeenSet()
-                        ? dirMode : getUnixMode(resources[i], zf, dirMode);
-                    addDirectoryResource(resources[i], name, prefix,
+                        ? dirMode : getUnixMode(resource, zf, dirMode);
+                    addDirectoryResource(resource, name, prefix,
                                          base, zOut,
                                          dirMode, thisDirMode);
 
@@ -1026,14 +995,14 @@
 
                     if (dealingWithFiles) {
                         final File f = FILE_UTILS.resolveFile(base,
-                                                        resources[i].getName());
+                                                        resource.getName());
                         zipFile(f, zOut, prefix + name, fileMode);
                     } else {
                         final int thisFileMode =
                             zfs != null && zfs.hasFileModeBeenSet()
-                            ? fileMode : getUnixMode(resources[i], zf,
+                            ? fileMode : getUnixMode(resource, zf,
                                                      fileMode);
-                        addResource(resources[i], name, prefix,
+                        addResource(resource, name, prefix,
                                     zOut, thisFileMode, zf,
                                     zfs == null
                                     ? null : zfs.getSrc(getProject()));
@@ -1061,7 +1030,7 @@
             name = name + "/";
         }
 
-        final int nextToLastSlash = name.lastIndexOf("/", name.length() - 2);
+        final int nextToLastSlash = name.lastIndexOf('/', name.length() - 2);
         if (nextToLastSlash != -1) {
             addParentDirs(base, name.substring(0, nextToLastSlash + 1),
                           zOut, prefix, defaultDirMode);
@@ -1107,25 +1076,18 @@
                 if (keepCompression) {
                     doCompress = (ze.getMethod() == ZipEntry.DEFLATED);
                 }
-                InputStream is = null;
-                try {
-                    is = new BufferedInputStream(zf.getInputStream(ze));
+                try (final BufferedInputStream is = new BufferedInputStream(zf.getInputStream(ze))) {
                     zipFile(is, zOut, prefix + name, ze.getTime(),
                             fromArchive, mode, ze.getExtraFields(true));
                 } finally {
                     doCompress = oldCompress;
-                    FileUtils.close(is);
                 }
             }
         } else {
-            InputStream is = null;
-            try {
-                is = new BufferedInputStream(r.getInputStream());
+            try (final BufferedInputStream is = new BufferedInputStream(r.getInputStream())) {
                 zipFile(is, zOut, prefix + name, r.getLastModified(),
                         fromArchive, mode, r instanceof ZipResource
                         ? ((ZipResource) r).getExtraFields() : null);
-            } finally {
-                FileUtils.close(is);
             }
         }
     }
@@ -1149,15 +1111,14 @@
             addResources((FileSet) rc, resources, zOut);
             return;
         }
-        for (int i = 0; i < resources.length; i++) {
-            final Resource resource = resources[i];
+        for (final Resource resource : resources) {
             String name = resource.getName();
             if (name == null) {
                 continue;
             }
             name = name.replace(File.separatorChar, '/');
 
-            if ("".equals(name)) {
+            if (name.isEmpty()) {
                 continue;
             }
             if (resource.isDirectory() && doFilesonly) {
@@ -1224,9 +1185,7 @@
             log("Note: creating empty " + archiveType + " archive " + zipFile,
                 Project.MSG_INFO);
         }
-        OutputStream os = null;
-        try {
-            os = new FileOutputStream(zipFile);
+        try (OutputStream os = Files.newOutputStream(zipFile.toPath())) {
             // CheckStyle:MagicNumber OFF
             // Cf. PKZIP specification.
             final byte[] empty = new byte[22];
@@ -1241,8 +1200,6 @@
             throw new BuildException("Could not create empty ZIP archive "
                                      + "(" + ioe.getMessage() + ")", ioe,
                                      getLocation());
-        } finally {
-            FileUtils.close(os);
         }
         return true;
     }
@@ -1291,13 +1248,13 @@
                                              final File zipFile,
                                              final boolean needsUpdate)
         throws BuildException {
-        final ArrayList<ResourceCollection> filesets = new ArrayList<ResourceCollection>();
-        final ArrayList<ResourceCollection> rest = new ArrayList<ResourceCollection>();
-        for (int i = 0; i < rcs.length; i++) {
-            if (rcs[i] instanceof FileSet) {
-                filesets.add(rcs[i]);
+        final List<ResourceCollection> filesets = new ArrayList<>();
+        final List<ResourceCollection> rest = new ArrayList<>();
+        for (ResourceCollection rc : rcs) {
+            if (rc instanceof FileSet) {
+                filesets.add(rc);
             } else {
-                rest.add(rcs[i]);
+                rest.add(rc);
             }
         }
         final ResourceCollection[] rc =
@@ -1399,7 +1356,7 @@
                     return new ArchiveState(true, initialResources);
                 }
 
-                if (emptyBehavior.equals("skip")) {
+                if ("skip".equals(emptyBehavior)) {
                     if (doUpdate) {
                         logWhenWriting(archiveType + " archive " + zipFile
                                        + " not updated because no new files were"
@@ -1410,7 +1367,7 @@
                                        + " because no files were included.",
                                        Project.MSG_WARN);
                     }
-                } else if (emptyBehavior.equals("fail")) {
+                } else if ("fail".equals(emptyBehavior)) {
                     throw new BuildException("Cannot create " + archiveType
                                              + " archive " + zipFile
                                              + ": no files were included.",
@@ -1571,8 +1528,8 @@
                 final FileProvider fp =
                     initialResources[i][j].as(FileProvider.class);
                 if (fp != null && zipFile.equals(fp.getFile())) {
-                    throw new BuildException("A zip file cannot include "
-                                             + "itself", getLocation());
+                    throw new BuildException("A zip file cannot include itself",
+                        getLocation());
                 }
             }
 
@@ -1609,8 +1566,8 @@
                 ResourceUtils.selectSources(this, u, mapper,
                                             getZipScanner(),
                                             MISSING_DIR_PROVIDER);
-            if (rc.size() > 0) {
-                final ArrayList<Resource> newer = new ArrayList<Resource>();
+            if (!rc.isEmpty()) {
+                final List<Resource> newer = new ArrayList<>();
                 newer.addAll(Arrays.asList(((Union) rc).listResources()));
                 newer.addAll(Arrays.asList(result));
                 result = newer.toArray(result);
@@ -1633,32 +1590,28 @@
             boolean skipEmptyNames = true;
             if (filesets[i] instanceof ZipFileSet) {
                 final ZipFileSet zfs = (ZipFileSet) filesets[i];
-                skipEmptyNames = zfs.getPrefix(getProject()).equals("")
-                    && zfs.getFullpath(getProject()).equals("");
+                skipEmptyNames = zfs.getPrefix(getProject()).isEmpty()
+                    && zfs.getFullpath(getProject()).isEmpty();
             }
             final DirectoryScanner rs =
                 filesets[i].getDirectoryScanner(getProject());
             if (rs instanceof ZipScanner) {
                 ((ZipScanner) rs).setEncoding(encoding);
             }
-            final Vector<Resource> resources = new Vector<Resource>();
+            final List<Resource> resources = new Vector<>();
             if (!doFilesonly) {
-                final String[] directories = rs.getIncludedDirectories();
-                for (int j = 0; j < directories.length; j++) {
-                    if (!"".equals(directories[j]) || !skipEmptyNames) {
-                        resources.addElement(rs.getResource(directories[j]));
+                for (String d : rs.getIncludedDirectories()) {
+                    if (!(d.isEmpty() && skipEmptyNames)) {
+                        resources.add(rs.getResource(d));
                     }
                 }
             }
-            final String[] files = rs.getIncludedFiles();
-            for (int j = 0; j < files.length; j++) {
-                if (!"".equals(files[j]) || !skipEmptyNames) {
-                    resources.addElement(rs.getResource(files[j]));
+            for (String f : rs.getIncludedFiles()) {
+                if (!(f.isEmpty() && skipEmptyNames)) {
+                    resources.add(rs.getResource(f));
                 }
             }
-
-            result[i] = new Resource[resources.size()];
-            resources.copyInto(result[i]);
+            result[i] = resources.toArray(new Resource[resources.size()]);
         }
         return result;
     }
@@ -1674,25 +1627,19 @@
     protected Resource[][] grabNonFileSetResources(final ResourceCollection[] rcs) {
         final Resource[][] result = new Resource[rcs.length][];
         for (int i = 0; i < rcs.length; i++) {
-            final ArrayList<Resource> dirs = new ArrayList<Resource>();
-            final ArrayList<Resource> files = new ArrayList<Resource>();
+            final List<Resource> dirs = new ArrayList<>();
+            final List<Resource> files = new ArrayList<>();
             for (final Resource r : rcs[i]) {
-                if (r.isExists()) {
-                    if (r.isDirectory()) {
-                        dirs.add(r);
-                    } else {
-                        files.add(r);
-                    }
+                if (r.isDirectory()) {
+                    dirs.add(r);
+                } else if (r.isExists()) {
+                    files.add(r);
                 }
             }
             // make sure directories are in alpha-order - this also
             // ensures parents come before their children
-            Collections.sort(dirs, new Comparator<Resource>() {
-                    public int compare(final Resource r1, final Resource r2) {
-                        return r1.getName().compareTo(r2.getName());
-                    }
-                });
-            final ArrayList<Resource> rs = new ArrayList<Resource>(dirs);
+            Collections.sort(dirs, Comparator.comparing(Resource::getName));
+            final List<Resource> rs = new ArrayList<>(dirs);
             rs.addAll(files);
             result[i] = rs.toArray(new Resource[rs.size()]);
         }
@@ -1727,8 +1674,8 @@
     protected void zipDir(final File dir, final ZipOutputStream zOut, final String vPath,
                           final int mode, final ZipExtraField[] extra)
         throws IOException {
-        zipDir(dir == null ? (Resource) null : new FileResource(dir),
-               zOut, vPath, mode, extra);
+        zipDir(dir == null ? null : new FileResource(dir), zOut, vPath, mode,
+            extra);
     }
 
     /**
@@ -1791,7 +1738,7 @@
      * support a new parameter (extra fields to preserve) without
      * breaking subclasses that override the old method signature.
      */
-    private static final ThreadLocal<ZipExtraField[]> CURRENT_ZIP_EXTRA = new ThreadLocal<ZipExtraField[]>();
+    private static final ThreadLocal<ZipExtraField[]> CURRENT_ZIP_EXTRA = new ThreadLocal<>();
 
     /**
      * Provides the extra fields for the zip entry currently being
@@ -1835,19 +1782,19 @@
 
         if (entries.containsKey(vPath)) {
 
-            if (duplicate.equals("preserve")) {
+            if ("preserve".equals(duplicate)) {
                 logWhenWriting(vPath + " already added, skipping",
                                Project.MSG_INFO);
                 return;
-            } else if (duplicate.equals("fail")) {
-                throw new BuildException("Duplicate file " + vPath
-                                         + " was found and the duplicate "
-                                         + "attribute is 'fail'.");
-            } else {
-                // duplicate equal to add, so we continue
-                logWhenWriting("duplicate file " + vPath
-                               + " found, adding.", Project.MSG_VERBOSE);
             }
+            if ("fail".equals(duplicate)) {
+                throw new BuildException(
+                    "Duplicate file %s was found and the duplicate attribute is 'fail'.",
+                    vPath);
+            }
+            // duplicate equal to add, so we continue
+            logWhenWriting("duplicate file " + vPath
+                           + " found, adding.", Project.MSG_VERBOSE);
         } else {
             logWhenWriting("adding entry " + vPath, Project.MSG_VERBOSE);
         }
@@ -1904,7 +1851,7 @@
                 count = markableInputStream.read(buffer, 0, buffer.length);
             } while (count != -1);
         }
-        addedFiles.addElement(vPath);
+        addedFiles.add(vPath);
     }
 
     /**
@@ -1957,14 +1904,11 @@
                                      getLocation());
         }
 
-        final BufferedInputStream bIn = new BufferedInputStream(new FileInputStream(file));
-        try {
+        try (final BufferedInputStream bIn = new BufferedInputStream(Files.newInputStream(file.toPath()))) {
             // ZIPs store time with a granularity of 2 seconds, round up
             zipFile(bIn, zOut, vPath,
                     file.lastModified() + (roundUp ? ROUNDUP_MILLIS : 0),
                     null, mode);
-        } finally {
-            bIn.close();
         }
     }
 
@@ -1983,7 +1927,7 @@
                                        final int dirMode)
         throws IOException {
         if (!doFilesonly) {
-            final Stack<String> directories = new Stack<String>();
+            final Stack<String> directories = new Stack<>();
             int slashPos = entry.length();
 
             while ((slashPos = entry.lastIndexOf('/', slashPos - 1)) != -1) {
@@ -1996,7 +1940,7 @@
 
             while (!directories.isEmpty()) {
                 final String dir = directories.pop();
-                File f = null;
+                File f;
                 if (baseDir != null) {
                     f = new File(baseDir, dir);
                 } else {
@@ -2023,16 +1967,12 @@
      */
     protected void cleanUp() {
         addedDirs.clear();
-        addedFiles.removeAllElements();
+        addedFiles.clear();
         entries.clear();
         addingNewFiles = false;
         doUpdate = savedDoUpdate;
-        final Enumeration<ZipFileSet> e = filesetsFromGroupfilesets.elements();
-        while (e.hasMoreElements()) {
-            final ZipFileSet zf = e.nextElement();
-            resources.removeElement(zf);
-        }
-        filesetsFromGroupfilesets.removeAllElements();
+        resources.removeAll(filesetsFromGroupfilesets);
+        filesetsFromGroupfilesets.clear();
         HAVE_NON_FILE_SET_RESOURCES_TO_ADD.set(Boolean.FALSE);
     }
 
@@ -2045,10 +1985,10 @@
      * @see #cleanUp
      */
     public void reset() {
-        resources.removeAllElements();
+        resources.clear();
         zipFile = null;
         baseDir = null;
-        groupfilesets.removeAllElements();
+        groupfilesets.clear();
         duplicate = "add";
         archiveType = "zip";
         doCompress = true;
@@ -2066,8 +2006,8 @@
      * @since Ant 1.5.2
      */
     protected static final boolean isEmpty(final Resource[][] r) {
-        for (int i = 0; i < r.length; i++) {
-            if (r[i].length > 0) {
+        for (Resource[] element : r) {
+            if (element.length > 0) {
                 return false;
             }
         }
@@ -2082,19 +2022,18 @@
      */
     protected Resource[] selectFileResources(final Resource[] orig) {
         return selectResources(orig,
-                               new ResourceSelector() {
-                                   public boolean isSelected(final Resource r) {
-                                       if (!r.isDirectory()) {
-                                           return true;
-                                       } else if (doFilesonly) {
-                                           logWhenWriting("Ignoring directory "
-                                                          + r.getName()
-                                                          + " as only files will"
-                                                          + " be added.",
-                                                          Project.MSG_VERBOSE);
-                                       }
-                                       return false;
+                               r -> {
+                                   if (!r.isDirectory()) {
+                                       return true;
                                    }
+                                   if (doFilesonly) {
+                                       logWhenWriting("Ignoring directory "
+                                                      + r.getName()
+                                                      + " as only files will"
+                                                      + " be added.",
+                                                      Project.MSG_VERBOSE);
+                                   }
+                                   return false;
                                });
     }
 
@@ -2105,12 +2044,7 @@
      * @since Ant 1.8.0
      */
     protected Resource[] selectDirectoryResources(final Resource[] orig) {
-        return selectResources(orig,
-                               new ResourceSelector() {
-                                   public boolean isSelected(final Resource r) {
-                                       return r.isDirectory();
-                                   }
-                               });
+        return selectResources(orig, Resource::isDirectory);
     }
 
     /**
@@ -2125,18 +2059,9 @@
         if (orig.length == 0) {
             return orig;
         }
-
-        final ArrayList<Resource> v = new ArrayList<Resource>(orig.length);
-        for (int i = 0; i < orig.length; i++) {
-            if (selector.isSelected(orig[i])) {
-                v.add(orig[i]);
-            }
-        }
-
-        if (v.size() != orig.length) {
-            return v.toArray(new Resource[v.size()]);
-        }
-        return orig;
+        Resource[] result = Stream.of(orig).filter(selector::isSelected)
+            .toArray(Resource[]::new);
+        return result.length == orig.length ? orig : result;
     }
 
     /**
@@ -2207,11 +2132,9 @@
             if (resourcesToAdd == null)  {
                 return true;
             }
-            for (int counter = 0; counter < resourcesToAdd.length; counter++) {
-                if (resourcesToAdd[counter] != null) {
-                    if (resourcesToAdd[counter].length > 0) {
-                        return false;
-                    }
+            for (Resource[] element : resourcesToAdd) {
+                if (element != null && element.length > 0) {
+                    return false;
                 }
             }
             return true;
@@ -2225,7 +2148,7 @@
      * @since Ant 1.8.0
      */
     public static final class UnicodeExtraField extends EnumeratedAttribute {
-        private static final Map<String, UnicodeExtraFieldPolicy> POLICIES = new HashMap<String, UnicodeExtraFieldPolicy>();
+        private static final Map<String, UnicodeExtraFieldPolicy> POLICIES = new HashMap<>();
         private static final String NEVER_KEY = "never";
         private static final String ALWAYS_KEY = "always";
         private static final String N_E_KEY = "not-encodeable";
@@ -2259,7 +2182,6 @@
         }
     }
 
-
     /**
      * The choices for Zip64 extensions.
      *
@@ -2287,7 +2209,7 @@
      * @since Ant 1.9.1
      */
     public static final class Zip64ModeAttribute extends EnumeratedAttribute {
-        private static final Map<String, Zip64Mode> MODES = new HashMap<String, Zip64Mode>();
+        private static final Map<String, Zip64Mode> MODES = new HashMap<>();
 
         private static final String NEVER_KEY = "never";
         private static final String ALWAYS_KEY = "always";
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/AptCompilerAdapter.java b/src/main/org/apache/tools/ant/taskdefs/compilers/AptCompilerAdapter.java
deleted file mode 100644
index 9503ac0..0000000
--- a/src/main/org/apache/tools/ant/taskdefs/compilers/AptCompilerAdapter.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- *  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.
- *
- */
-
-package org.apache.tools.ant.taskdefs.compilers;
-
-import java.io.File;
-import java.lang.reflect.Method;
-import java.util.Enumeration;
-import java.util.Vector;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.Apt;
-import org.apache.tools.ant.types.Commandline;
-import org.apache.tools.ant.types.Path;
-
-
-/**
- * <p>The implementation of the apt compiler for JDK 1.5.</p>
- *
- * <p>As usual, the low level entry points for Java tools are neither documented or
- * stable; this entry point may change from that of 1.5.0_01-b08 without any
- * warning at all. The IDE decompile of the tool entry points is as follows:</p>
- * <pre>
- * public class Main {
- * public Main() ;
- *
- * public static transient void main(String... strings);
- *
- * public static transient int process(String... strings);
- *
- * public static transient int process(PrintWriter printWriter,
- *      String... strings);
- * public static transient int process(
- *      AnnotationProcessorFactory annotationProcessorFactory,
- *      String... strings);
- *
- * public static transient int process(
- *      AnnotationProcessorFactory annotationProcessorFactory,
- *      PrintWriter printWriter,
- *      String... strings);
- * private static transient int processing(
- *      AnnotationProcessorFactory annotationProcessorFactory,
- *      PrintWriter printWriter,
- *      String... strings) ;
- * }
- * </pre>
- *
- * This Adapter is designed to run Apt in-JVM, an option that is not actually
- * exposed to end-users, because it was too brittle during beta testing; classpath
- * problems being the core issue.
- *
- * @since Ant 1.7
- */
-public class AptCompilerAdapter extends DefaultCompilerAdapter {
-
-    /**
-     * Integer returned by the Apt compiler to indicate success.
-     */
-    private static final int APT_COMPILER_SUCCESS = 0;
-    /**
-     * class in tools.jar that implements APT
-     */
-    public static final String APT_ENTRY_POINT = "com.sun.tools.apt.Main";
-
-    /**
-     * method used to compile.
-     */
-    public static final String APT_METHOD_NAME = "process";
-
-    /**
-     * Get the facade task that fronts this adapter
-     *
-     * @return task instance
-     * @see DefaultCompilerAdapter#getJavac()
-     */
-    protected Apt getApt() {
-        return (Apt) getJavac();
-    }
-
-    /**
-     * Using the front end arguments, set up the command line to run Apt
-     *
-     * @param apt task
-     * @param cmd command that is set up with the various switches from the task
-     *            options
-     */
-    static void setAptCommandlineSwitches(final Apt apt, final Commandline cmd) {
-
-        if (!apt.isCompile()) {
-            cmd.createArgument().setValue("-nocompile");
-        }
-
-        // Process the factory class
-        final String factory = apt.getFactory();
-        if (factory != null) {
-            cmd.createArgument().setValue("-factory");
-            cmd.createArgument().setValue(factory);
-        }
-
-        // Process the factory path
-        final Path factoryPath = apt.getFactoryPath();
-        if (factoryPath != null) {
-            cmd.createArgument().setValue("-factorypath");
-            cmd.createArgument().setPath(factoryPath);
-        }
-
-        final File preprocessDir = apt.getPreprocessDir();
-        if (preprocessDir != null) {
-            cmd.createArgument().setValue("-s");
-            cmd.createArgument().setFile(preprocessDir);
-        }
-
-        // Process the processor options
-        final Vector options = apt.getOptions();
-        final Enumeration elements = options.elements();
-        Apt.Option opt;
-        StringBuffer arg = null;
-        while (elements.hasMoreElements()) {
-            opt = (Apt.Option) elements.nextElement();
-            arg = new StringBuffer();
-            arg.append("-A").append(opt.getName());
-            if (opt.getValue() != null) {
-                arg.append("=").append(opt.getValue());
-            }
-            cmd.createArgument().setValue(arg.toString());
-        }
-    }
-
-    /**
-     * using our front end task, set up the command line switches
-     *
-     * @param cmd command line to set up
-     */
-    protected void setAptCommandlineSwitches(final Commandline cmd) {
-        final Apt apt = getApt();
-        setAptCommandlineSwitches(apt, cmd);
-    }
-
-    /**
-     * Run the compilation.
-     * @return true on success.
-     * @throws BuildException if the compilation has problems.
-     */
-    public boolean execute() throws BuildException {
-        attributes.log("Using apt compiler", Project.MSG_VERBOSE);
-        //set up the javac options
-        final Commandline cmd = setupModernJavacCommand();
-        //then add the Apt options
-        setAptCommandlineSwitches(cmd);
-
-        //finally invoke APT
-        // Use reflection to be able to build on all JDKs:
-        try {
-            final Class c = Class.forName(APT_ENTRY_POINT);
-            final Object compiler = c.newInstance();
-            final Method compile = c.getMethod(APT_METHOD_NAME,
-                    new Class[]{(new String[]{}).getClass()});
-            final int result = ((Integer) compile.invoke
-                    (compiler, new Object[]{cmd.getArguments()}))
-                    .intValue();
-            return (result == APT_COMPILER_SUCCESS);
-        } catch (final BuildException be) {
-            //rethrow build exceptions
-            throw be;
-        } catch (final Exception ex) {
-            //cast everything else to a build exception
-            throw new BuildException("Error starting apt compiler",
-                    ex, location);
-        }
-    }
-}
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/AptExternalCompilerAdapter.java b/src/main/org/apache/tools/ant/taskdefs/compilers/AptExternalCompilerAdapter.java
deleted file mode 100644
index dadb55b..0000000
--- a/src/main/org/apache/tools/ant/taskdefs/compilers/AptExternalCompilerAdapter.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *  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.
- *
- */
-
-package org.apache.tools.ant.taskdefs.compilers;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.Apt;
-import org.apache.tools.ant.types.Commandline;
-
-/**
- * The implementation of the apt compiler for JDK 1.5 using an external process
- *
- * @since Ant 1.7
- */
-public class AptExternalCompilerAdapter extends DefaultCompilerAdapter {
-
-
-    /**
-     * Get the facade task that fronts this adapter
-     *
-     * @return task instance
-     * @see DefaultCompilerAdapter#getJavac()
-     */
-    protected Apt getApt() {
-        return (Apt) getJavac();
-    }
-
-    /**
-     * Performs a compile using the Javac externally.
-     * @return true  the compilation was successful.
-     * @throws BuildException if there is a problem.
-     */
-    public boolean execute() throws BuildException {
-        attributes.log("Using external apt compiler", Project.MSG_VERBOSE);
-
-
-        // Setup the apt executable
-        Apt apt = getApt();
-        Commandline cmd = new Commandline();
-        cmd.setExecutable(apt.getAptExecutable());
-        setupModernJavacCommandlineSwitches(cmd);
-        AptCompilerAdapter.setAptCommandlineSwitches(apt, cmd);
-        int firstFileName = cmd.size();
-        //add the files
-        logAndAddFilesToCompile(cmd);
-
-        //run
-        return 0 == executeExternalCompile(cmd.getCommandline(),
-                firstFileName,
-                true);
-
-    }
-
-}
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java b/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java
index 48d93ad..9cda7a4 100644
--- a/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java
@@ -96,70 +96,60 @@
      * @since Ant 1.8.0
      */
     public static CompilerAdapter getCompiler(String compilerType, Task task,
-                                              Path classpath)
-        throws BuildException {
-            if (compilerType.equalsIgnoreCase("jikes")) {
-                return new Jikes();
-            }
-            if (compilerType.equalsIgnoreCase("extjavac")) {
-                return new JavacExternal();
-            }
-            if (compilerType.equalsIgnoreCase("classic")
-                || compilerType.equalsIgnoreCase("javac1.1")
-                || compilerType.equalsIgnoreCase("javac1.2")) {
-                task.log("This version of java does "
-                                         + "not support the classic "
-                                         + "compiler; upgrading to modern",
-                                         Project.MSG_WARN);
-                compilerType = "modern";
-            }
-            //on java<=1.3 the modern falls back to classic if it is not found
-            //but on java>=1.4 we just bail out early
-            if (compilerType.equalsIgnoreCase("modern")
-                || compilerType.equalsIgnoreCase("javac1.3")
-                || compilerType.equalsIgnoreCase("javac1.4")
-                || compilerType.equalsIgnoreCase("javac1.5")
-                || compilerType.equalsIgnoreCase("javac1.6")
-                || compilerType.equalsIgnoreCase("javac1.7")
-                || compilerType.equalsIgnoreCase("javac1.8")
-                || compilerType.equalsIgnoreCase("javac1.9")
-                || compilerType.equalsIgnoreCase("javac9")
-                || compilerType.equalsIgnoreCase("javac10+")) {
-                // does the modern compiler exist?
-                if (doesModernCompilerExist()) {
-                    return new Javac13();
-                } else {
-                    throw new BuildException("Unable to find a javac "
-                                             + "compiler;\n"
-                                             + MODERN_COMPILER
-                                             + " is not on the "
-                                             + "classpath.\n"
-                                             + "Perhaps JAVA_HOME does not"
-                                             + " point to the JDK.\n"
-                            + "It is currently set to \""
-                            + JavaEnvUtils.getJavaHome()
-                            + "\"");
-                }
-            }
-
-            if (compilerType.equalsIgnoreCase("jvc")
-                || compilerType.equalsIgnoreCase("microsoft")) {
-                return new Jvc();
-            }
-            if (compilerType.equalsIgnoreCase("kjc")) {
-                return new Kjc();
-            }
-            if (compilerType.equalsIgnoreCase("gcj")) {
-                return new Gcj();
-            }
-            if (compilerType.equalsIgnoreCase("sj")
-                || compilerType.equalsIgnoreCase("symantec")) {
-                return new Sj();
-            }
-            return resolveClassName(compilerType,
-                                    // Memory-Leak in line below
-                                task.getProject().createClassLoader(classpath));
+        Path classpath) throws BuildException {
+        if ("jikes".equalsIgnoreCase(compilerType)) {
+            return new Jikes();
         }
+        if ("extjavac".equalsIgnoreCase(compilerType)) {
+            return new JavacExternal();
+        }
+        if ("classic".equalsIgnoreCase(compilerType)
+            || "javac1.1".equalsIgnoreCase(compilerType)
+            || "javac1.2".equalsIgnoreCase(compilerType)) {
+            task.log(
+                "This version of java does not support the classic compiler; upgrading to modern",
+                Project.MSG_WARN);
+            compilerType = "modern";
+        }
+        //on java<=1.3 the modern falls back to classic if it is not found
+        //but on java>=1.4 we just bail out early
+        if ("modern".equalsIgnoreCase(compilerType)
+            || "javac1.3".equalsIgnoreCase(compilerType)
+            || "javac1.4".equalsIgnoreCase(compilerType)
+            || "javac1.5".equalsIgnoreCase(compilerType)
+            || "javac1.6".equalsIgnoreCase(compilerType)
+            || "javac1.7".equalsIgnoreCase(compilerType)
+            || "javac1.8".equalsIgnoreCase(compilerType)
+            || "javac1.9".equalsIgnoreCase(compilerType)
+            || "javac9".equalsIgnoreCase(compilerType)
+            || "javac10+".equalsIgnoreCase(compilerType)) {
+            // does the modern compiler exist?
+            if (doesModernCompilerExist()) {
+                return new Javac13();
+            }
+            throw new BuildException(
+                "Unable to find a javac compiler;\n%s is not on the classpath.\nPerhaps JAVA_HOME does not point to the JDK.\nIt is currently set to \"%s\"",
+                MODERN_COMPILER, JavaEnvUtils.getJavaHome());
+        }
+
+        if ("jvc".equalsIgnoreCase(compilerType)
+            || "microsoft".equalsIgnoreCase(compilerType)) {
+            return new Jvc();
+        }
+        if ("kjc".equalsIgnoreCase(compilerType)) {
+            return new Kjc();
+        }
+        if ("gcj".equalsIgnoreCase(compilerType)) {
+            return new Gcj();
+        }
+        if ("sj".equalsIgnoreCase(compilerType)
+            || "symantec".equalsIgnoreCase(compilerType)) {
+            return new Sj();
+        }
+        return resolveClassName(compilerType,
+            // Memory-Leak in line below
+            task.getProject().createClassLoader(classpath));
+    }
 
     /**
      * query for the Modern compiler existing
@@ -195,7 +185,7 @@
     private static CompilerAdapter resolveClassName(String className,
                                                     ClassLoader loader)
         throws BuildException {
-        return (CompilerAdapter) ClasspathUtils.newInstance(className,
+        return ClasspathUtils.newInstance(className,
                 loader != null ? loader :
                 CompilerAdapterFactory.class.getClassLoader(),
                 CompilerAdapter.class);
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java b/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java
index 1cd5e62..e6efc2c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java
@@ -18,13 +18,13 @@
 
 package org.apache.tools.ant.taskdefs.compilers;
 
-//Java5 style
-//import static org.apache.tools.ant.util.StringUtils.LINE_SEP;
-
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Location;
@@ -61,6 +61,10 @@
 
     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
 
+    //must keep for subclass BC, though unused:
+    // CheckStyle:ConstantNameCheck OFF - bc
+    protected static final String lSep = StringUtils.LINE_SEP;
+
     protected Path src;
     protected File destDir;
     protected String encoding;
@@ -88,10 +92,6 @@
     protected File[] compileList;
     protected Javac attributes;
 
-    //must keep for subclass BC, though unused:
-    // CheckStyle:ConstantNameCheck OFF - bc
-    protected static final String lSep = StringUtils.LINE_SEP;
-
     // CheckStyle:ConstantNameCheck ON
     // CheckStyle:VisibilityModifier ON
 
@@ -101,6 +101,7 @@
      *
      * @param attributes a configured Javac task.
      */
+    @Override
     public void setJavac(final Javac attributes) {
         this.attributes = attributes;
         src = attributes.getSrcdir();
@@ -147,6 +148,7 @@
      * but specialized compilers can recognize multiple kinds
      * of files.
      */
+    @Override
     public String[] getSupportedFileExtensions() {
         return new String[] {"java"};
     }
@@ -254,7 +256,7 @@
         final Path classpath = getCompileClasspath();
         // For -sourcepath, use the "sourcepath" value if present.
         // Otherwise default to the "srcdir" value.
-        Path sourcepath = null;
+        Path sourcepath;
         if (compileSourcepath != null) {
             sourcepath = compileSourcepath;
         } else {
@@ -264,9 +266,9 @@
         final String memoryParameterPrefix = assumeJava11() ? "-J-" : "-J-X";
         if (memoryInitialSize != null) {
             if (!attributes.isForkedJavac()) {
-                attributes.log("Since fork is false, ignoring "
-                               + "memoryInitialSize setting.",
-                               Project.MSG_WARN);
+                attributes.log(
+                    "Since fork is false, ignoring memoryInitialSize setting.",
+                    Project.MSG_WARN);
             } else {
                 cmd.createArgument().setValue(memoryParameterPrefix
                                               + "ms" + memoryInitialSize);
@@ -275,9 +277,9 @@
 
         if (memoryMaximumSize != null) {
             if (!attributes.isForkedJavac()) {
-                attributes.log("Since fork is false, ignoring "
-                               + "memoryMaximumSize setting.",
-                               Project.MSG_WARN);
+                attributes.log(
+                    "Since fork is false, ignoring memoryMaximumSize setting.",
+                    Project.MSG_WARN);
             } else {
                 cmd.createArgument().setValue(memoryParameterPrefix
                                               + "mx" + memoryMaximumSize);
@@ -303,11 +305,7 @@
         // as well as "bootclasspath" and "extdirs"
         if (assumeJava11()) {
             final Path cp = new Path(project);
-
-            final Path bp = getBootClassPath();
-            if (bp.size() > 0) {
-                cp.append(bp);
-            }
+            Optional.ofNullable(getBootClassPath()).ifPresent(cp::append);
 
             if (extdirs != null) {
                 cp.addExtdirs(extdirs);
@@ -330,13 +328,13 @@
                 }
 
                 final Path bp = getBootClassPath();
-                if (bp.size() > 0) {
+                if (!bp.isEmpty()) {
                     cmd.createArgument().setValue("-bootclasspath");
                     cmd.createArgument().setPath(bp);
                 }
             }
 
-            if (extdirs != null && extdirs.size() > 0) {
+            if (!(extdirs == null || extdirs.isEmpty())) {
                 cmd.createArgument().setValue("-extdirs");
                 cmd.createArgument().setPath(extdirs);
             }
@@ -370,8 +368,9 @@
             } else if (assumeJava12()) {
                 cmd.createArgument().setValue("-Xdepend");
             } else {
-                attributes.log("depend attribute is not supported by the "
-                               + "modern compiler", Project.MSG_WARN);
+                attributes.log(
+                    "depend attribute is not supported by the modern compiler",
+                    Project.MSG_WARN);
             }
         }
 
@@ -397,8 +396,8 @@
             final String s = attributes.getSource();
             if (release == null || !assumeJava9Plus()) {
                 if (release != null) {
-                    attributes.log("Support for javac --release has been added"
-                                   + " in Java9 ignoring it");
+                    attributes.log(
+                        "Support for javac --release has been added in Java9 ignoring it");
                 }
                 if (s != null) {
                     cmd.createArgument().setValue("-source");
@@ -409,34 +408,34 @@
                 }
             } else { // Java 9+ and release has been set
                 if (t != null || s != null || getBootClassPath().size() > 0) {
-                    attributes.log("Ignoring source, target and bootclasspath"
-                                   + " as release has been set",
-                                   Project.MSG_WARN);
+                    attributes.log(
+                        "Ignoring source, target and bootclasspath as release has been set",
+                        Project.MSG_WARN);
                 }
                 cmd.createArgument().setValue("--release");
                 cmd.createArgument().setValue(release);
             }
         }
         final Path msp = getModulesourcepath();
-        if (msp.size() > 0) {
+        if (!msp.isEmpty()) {
             cmd.createArgument().setValue("--module-source-path");
             cmd.createArgument().setPath(msp);
         }
         final Path mp = getModulepath();
-        if (mp.size() > 0) {
+        if (!mp.isEmpty()) {
             cmd.createArgument().setValue("--module-path");
             cmd.createArgument().setPath(mp);
         }
         final Path ump = getUpgrademodulepath();
-        if (ump.size() > 0) {
+        if (!ump.isEmpty()) {
             cmd.createArgument().setValue("--upgrade-module-path");
             cmd.createArgument().setPath(ump);
         }
         if (attributes.getNativeHeaderDir() != null) {
             if (assumeJava13() || assumeJava14() || assumeJava15() || assumeJava16()
                     || assumeJava17()) {
-                attributes.log("Support for javac -h has been added in Java8,"
-                               + " ignoring it");
+                attributes.log(
+                    "Support for javac -h has been added in Java8, ignoring it");
             } else {
                 cmd.createArgument().setValue("-h");
                 cmd.createArgument().setFile(attributes.getNativeHeaderDir());
@@ -487,23 +486,13 @@
     protected void logAndAddFilesToCompile(final Commandline cmd) {
         attributes.log("Compilation " + cmd.describeArguments(), Project.MSG_VERBOSE);
 
-        final StringBuffer niceSourceList = new StringBuffer("File");
-        if (compileList.length != 1) {
-            niceSourceList.append("s");
-        }
-        niceSourceList.append(" to be compiled:");
+        attributes.log(String.format("%s to be compiled:",
+                compileList.length == 1 ? "File" : "Files"), Project.MSG_VERBOSE);
 
-        niceSourceList.append(StringUtils.LINE_SEP);
-
-        for (int i = 0; i < compileList.length; i++) {
-            final String arg = compileList[i].getAbsolutePath();
-            cmd.createArgument().setValue(arg);
-            niceSourceList.append("    ");
-            niceSourceList.append(arg);
-            niceSourceList.append(StringUtils.LINE_SEP);
-        }
-
-        attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE);
+        attributes.log(Stream.of(compileList).map(File::getAbsolutePath)
+                        .peek(arg -> cmd.createArgument().setValue(arg))
+                        .map(arg -> "    " + arg)
+                        .collect(Collectors.joining(StringUtils.LINE_SEP)), Project.MSG_VERBOSE);
     }
 
     /**
@@ -553,29 +542,30 @@
              */
             if (Commandline.toString(args).length() > COMMAND_LINE_LIMIT
                 && firstFileName >= 0) {
-                BufferedWriter out = null;
                 try {
                     tmpFile = FILE_UTILS.createTempFile(
                         "files", "", getJavac().getTempdir(), true, true);
-                    out = new BufferedWriter(new FileWriter(tmpFile));
-                    for (int i = firstFileName; i < args.length; i++) {
-                        if (quoteFiles && args[i].indexOf(" ") > -1) {
-                            args[i] = args[i].replace(File.separatorChar, '/');
-                            out.write("\"" + args[i] + "\"");
-                        } else {
-                            out.write(args[i]);
+                    try (BufferedWriter out =
+                        new BufferedWriter(new FileWriter(tmpFile))) {
+                        for (int i = firstFileName; i < args.length; i++) {
+                            if (quoteFiles && args[i].indexOf(' ') > -1) {
+                                args[i] =
+                                    args[i].replace(File.separatorChar, '/');
+                                out.write("\"" + args[i] + "\"");
+                            } else {
+                                out.write(args[i]);
+                            }
+                            out.newLine();
                         }
-                        out.newLine();
+                        out.flush();
+                        commandArray = new String[firstFileName + 1];
+                        System.arraycopy(args, 0, commandArray, 0,
+                            firstFileName);
+                        commandArray[firstFileName] = "@" + tmpFile;
                     }
-                    out.flush();
-                    commandArray = new String[firstFileName + 1];
-                    System.arraycopy(args, 0, commandArray, 0, firstFileName);
-                    commandArray[firstFileName] = "@" + tmpFile;
                 } catch (final IOException e) {
                     throw new BuildException("Error creating temporary file",
                                              e, location);
-                } finally {
-                    FileUtils.close(out);
                 }
             } else {
                 commandArray = args;
@@ -704,6 +694,7 @@
      * @since Ant 1.9.4
      * @deprecated use #assumeJava9 instead
      */
+    @Deprecated
     protected boolean assumeJava19() {
         return assumeJavaXY("javac1.9", JavaEnvUtils.JAVA_9)
             || assumeJavaXY("javac9", JavaEnvUtils.JAVA_9);
@@ -721,7 +712,7 @@
     /**
      * Shall we assume JDK 9+ command line switches?
      * @return true if JDK 9+
-     * @since Ant 1.9.10
+     * @since Ant 1.10.2
      */
     protected boolean assumeJava9Plus() {
         return "javac1.9".equals(attributes.getCompilerVersion())
@@ -828,23 +819,21 @@
         if (t.startsWith("1.")) {
             t = t.substring(2);
         }
-        return t.equals("1") || t.equals("2") || t.equals("3") || t.equals("4")
-            || ((t.equals("5") || t.equals("6")) && !assumeJava15() && !assumeJava16())
-            || (t.equals("7") && !assumeJava17())
-            || (t.equals("8") && !assumeJava18())
-            || (t.equals("9") && !assumeJava9Plus());
+        return "1".equals(t) || "2".equals(t) || "3".equals(t) || "4".equals(t)
+                || (("5".equals(t) || "6".equals(t)) && !assumeJava15() && !assumeJava16())
+                || ("7".equals(t) && !assumeJava17())
+                || ("8".equals(t) && !assumeJava18())
+                || ("9".equals(t) && !assumeJava9Plus());
     }
 
-
     /**
-     * Turn the task's attribute for -source into soemthing that is
+     * Turn the task's attribute for -source into something that is
      * understood by all javac's after 1.4.
      *
      * <p>support for -source 1.1 and -source 1.2 has been added with
      * JDK 1.4.2 but isn't present in 1.5.0+</p>
      */
     private String adjustSourceValue(final String source) {
-        return (source.equals("1.1") || source.equals("1.2")) ? "1.3" : source;
+        return "1.1".equals(source) || "1.2".equals(source) ? "1.3" : source;
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/Gcj.java b/src/main/org/apache/tools/ant/taskdefs/compilers/Gcj.java
index a665e47..9b0eb30 100644
--- a/src/main/org/apache/tools/ant/taskdefs/compilers/Gcj.java
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/Gcj.java
@@ -31,16 +31,17 @@
  * @since Ant 1.4
  */
 public class Gcj extends DefaultCompilerAdapter {
+    private static final String[] CONFLICT_WITH_DASH_C = {"-o", "--main=", "-D", "-fjni", "-L"};
 
     /**
      * Performs a compile using the gcj compiler.
      * @return true if the compilation succeeded
      * @throws BuildException on error
      */
+    @Override
     public boolean execute() throws BuildException {
-        Commandline cmd;
         attributes.log("Using gcj compiler", Project.MSG_VERBOSE);
-        cmd = setupGCJCommand();
+        Commandline cmd = setupGCJCommand();
 
         int firstFileName = cmd.size();
         logAndAddFilesToCompile(cmd);
@@ -60,7 +61,7 @@
         // gcj doesn't support bootclasspath dir (-bootclasspath)
         // so we'll emulate it for compatibility and convenience.
         Path p = getBootClassPath();
-        if (p.size() > 0) {
+        if (!p.isEmpty()) {
             classpath.append(p);
         }
 
@@ -89,8 +90,8 @@
 
             if (!destDir.exists()
                 && !(destDir.mkdirs() || destDir.isDirectory())) {
-                throw new BuildException("Can't make output directories. "
-                                         + "Maybe permission is wrong. ");
+                throw new BuildException(
+                    "Can't make output directories. Maybe permission is wrong.");
             }
         }
 
@@ -152,6 +153,4 @@
         return nativeBuild;
     }
 
-    private static final String[] CONFLICT_WITH_DASH_C = {"-o", "--main=", "-D", "-fjni", "-L"};
-
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java b/src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java
index 6ca04c5..e66d10e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java
@@ -44,27 +44,25 @@
      * @return true if the compiler ran with a zero exit result (ok)
      * @exception BuildException if the compilation has problems.
      */
+    @Override
     public boolean execute() throws BuildException {
         attributes.log("Using modern compiler", Project.MSG_VERBOSE);
         Commandline cmd = setupModernJavacCommand();
 
         // Use reflection to be able to build on all JDKs >= 1.1:
         try {
-            Class c = Class.forName("com.sun.tools.javac.Main");
-            Object compiler = c.newInstance ();
-            Method compile = c.getMethod ("compile",
-                new Class [] {(new String [] {}).getClass ()});
-            int result = ((Integer) compile.invoke
-                          (compiler, new Object[] {cmd.getArguments()}))
-                .intValue ();
-            return (result == MODERN_COMPILER_SUCCESS);
+            Class<?> c = Class.forName("com.sun.tools.javac.Main");
+            Object compiler = c.newInstance();
+            Method compile = c.getMethod("compile", String[].class);
+            int result = ((Integer) compile.invoke(compiler,
+                (Object) cmd.getArguments())).intValue();
+            return result == MODERN_COMPILER_SUCCESS;
         } catch (Exception ex) {
             if (ex instanceof BuildException) {
                 throw (BuildException) ex;
-            } else {
-                throw new BuildException("Error starting modern compiler",
-                                         ex, location);
             }
+            throw new BuildException("Error starting modern compiler",
+                                     ex, location);
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java b/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java
index e227ecf..f63d4ac 100644
--- a/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java
@@ -40,6 +40,7 @@
      * @return true if the compilation succeeded
      * @throws BuildException on error
      */
+    @Override
     public boolean execute() throws BuildException {
         attributes.log("Using external javac compiler", Project.MSG_VERBOSE);
 
@@ -82,7 +83,8 @@
                             true);
 
         } catch (IOException e) {
-            throw new BuildException("Failed to create a temporary file for \"-V\" switch");
+            throw new BuildException(
+                "Failed to create a temporary file for \"-V\" switch");
         } finally {
             FileUtils.delete(vmsFile);
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/Jikes.java b/src/main/org/apache/tools/ant/taskdefs/compilers/Jikes.java
index eac1bcf..cb9385c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/compilers/Jikes.java
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/Jikes.java
@@ -43,6 +43,7 @@
      * @return true if the compilation succeeded
      * @throws BuildException on error
      */
+    @Override
     public boolean execute() throws BuildException {
         attributes.log("Using jikes compiler", Project.MSG_VERBOSE);
 
@@ -50,7 +51,7 @@
 
         // For -sourcepath, use the "sourcepath" value if present.
         // Otherwise default to the "srcdir" value.
-        Path sourcepath = null;
+        Path sourcepath;
         if (compileSourcepath != null) {
             sourcepath = compileSourcepath;
         } else {
@@ -58,14 +59,14 @@
         }
         // If the buildfile specifies sourcepath="", then don't
         // output any sourcepath.
-        if (sourcepath.size() > 0) {
+        if (!sourcepath.isEmpty()) {
             cmd.createArgument().setValue("-sourcepath");
             cmd.createArgument().setPath(sourcepath);
         }
 
         Path classpath = new Path(project);
 
-        if (bootclasspath == null || bootclasspath.size() == 0) {
+        if (bootclasspath == null || bootclasspath.isEmpty()) {
             // no bootclasspath, therefore, get one from the java runtime
             includeJavaRuntime = true;
         } else {
@@ -82,7 +83,7 @@
             classpath.append(new Path(project, jikesPath));
         }
 
-        if (extdirs != null && extdirs.size() > 0) {
+        if (!(extdirs == null || extdirs.isEmpty())) {
             cmd.createArgument().setValue("-extdirs");
             cmd.createArgument().setPath(extdirs);
         }
@@ -136,7 +137,7 @@
         if (attributes.getSource() != null) {
             cmd.createArgument().setValue("-source");
             String source = attributes.getSource();
-            if (source.equals("1.1") || source.equals("1.2")) {
+            if ("1.1".equals(source) || "1.2".equals(source)) {
                 // support for -source 1.1 and -source 1.2 has been
                 // added with JDK 1.4.2, Jikes doesn't like it
                 attributes.log("Jikes doesn't support '-source " + source
@@ -151,7 +152,7 @@
         int firstFileName = cmd.size();
 
         Path boot = getBootClassPath();
-        if (boot.size() > 0) {
+        if (!boot.isEmpty()) {
             cmd.createArgument().setValue("-bootclasspath");
             cmd.createArgument().setPath(boot);
         }
@@ -161,7 +162,7 @@
     }
 
     private void addPropertyParams(Commandline cmd) {
-        /**
+        /*
          * TODO
          * Perhaps we shouldn't use properties for these
          * three options (emacs mode, warnings and pedantic),
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/Jvc.java b/src/main/org/apache/tools/ant/taskdefs/compilers/Jvc.java
index 85ec479..b56089a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/compilers/Jvc.java
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/Jvc.java
@@ -37,6 +37,7 @@
      * @return true if the compiler ran with a zero exit result (ok)
      * @exception BuildException if the compilation has problems.
      */
+    @Override
     public boolean execute() throws BuildException {
         attributes.log("Using jvc compiler", Project.MSG_VERBOSE);
 
@@ -45,7 +46,7 @@
         // jvc doesn't support bootclasspath dir (-bootclasspath)
         // so we'll emulate it for compatibility and convenience.
         Path p = getBootClassPath();
-        if (p.size() > 0) {
+        if (!p.isEmpty()) {
             classpath.append(p);
         }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/Kjc.java b/src/main/org/apache/tools/ant/taskdefs/compilers/Kjc.java
index 68b5ba1..d3c87f9 100644
--- a/src/main/org/apache/tools/ant/taskdefs/compilers/Kjc.java
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/Kjc.java
@@ -38,6 +38,7 @@
      * @return true if the compilation succeeded
      * @exception BuildException if the compilation has problems.
      */
+    @Override
     public boolean execute() throws BuildException {
         attributes.log("Using kjc compiler", Project.MSG_VERBOSE);
         Commandline cmd = setupKjcCommand();
@@ -73,7 +74,7 @@
 
         // kjc don't have bootclasspath option.
         Path p = getBootClassPath();
-        if (p.size() > 0) {
+        if (!p.isEmpty()) {
             cp.append(p);
         }
 
@@ -115,5 +116,3 @@
         return cmd;
     }
 }
-
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/Sj.java b/src/main/org/apache/tools/ant/taskdefs/compilers/Sj.java
index 0dcc0e4..b31712b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/compilers/Sj.java
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/Sj.java
@@ -35,6 +35,7 @@
      * @return true if the compilation succeeded
      * @throws BuildException on error
      */
+    @Override
     public boolean execute() throws BuildException {
         attributes.log("Using symantec java compiler", Project.MSG_VERBOSE);
 
@@ -54,8 +55,8 @@
      * @return null.
      * @since Ant 1.6.3
      */
+    @Override
     protected String getNoDebugArgument() {
         return null;
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/And.java b/src/main/org/apache/tools/ant/taskdefs/condition/And.java
index 91b34c8..5ec6608 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/And.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/And.java
@@ -36,11 +36,11 @@
      * @return true if all the contained conditions evaluates to true
      * @exception BuildException if an error occurs
      */
+    @Override
     public boolean eval() throws BuildException {
-        Enumeration e = getConditions();
+        Enumeration<Condition> e = getConditions();
         while (e.hasMoreElements()) {
-            Condition c = (Condition) e.nextElement();
-            if (!c.eval()) {
+            if (!e.nextElement().eval()) {
                 return false;
             }
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/AntVersion.java b/src/main/org/apache/tools/ant/taskdefs/condition/AntVersion.java
index ec21d4b..1c5fd82 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/AntVersion.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/AntVersion.java
@@ -36,6 +36,7 @@
      * Run as a task.
      * @throws BuildException if an error occurs.
      */
+    @Override
     public void execute() throws BuildException {
         if (propertyname == null) {
             throw new BuildException("'property' must be set.");
@@ -56,6 +57,7 @@
      * @return true if the condition is true.
      * @throws BuildException if an error occurs.
      */
+    @Override
     public boolean eval() throws BuildException {
         validate();
         DeweyDecimal actual = getVersion();
@@ -82,8 +84,8 @@
                 new DeweyDecimal(atLeast); //NOSONAR
             } catch (NumberFormatException e) {
                 throw new BuildException(
-                    "The 'atleast' attribute is not a Dewey Decimal eg 1.1.0 : "
-                    + atLeast);
+                    "The 'atleast' attribute is not a Dewey Decimal eg 1.1.0 : %s",
+                    atLeast);
             }
         } else {
             try {
@@ -91,8 +93,8 @@
                 new DeweyDecimal(exactly); //NOSONAR
             } catch (NumberFormatException e) {
                 throw new BuildException(
-                    "The 'exactly' attribute is not a Dewey Decimal eg 1.1.0 : "
-                    + exactly);
+                    "The 'exactly' attribute is not a Dewey Decimal eg 1.1.0 : %s",
+                    exactly);
             }
         }
     }
@@ -101,7 +103,7 @@
         Project p = new Project();
         p.init();
         char[] versionString = p.getProperty("ant.version").toCharArray();
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         boolean foundFirstDigit = false;
         for (int i = 0; i < versionString.length; i++) {
             if (Character.isDigit(versionString[i])) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/Condition.java b/src/main/org/apache/tools/ant/taskdefs/condition/Condition.java
index 62adbf3..c10cb6f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/Condition.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/Condition.java
@@ -32,4 +32,3 @@
      */
     boolean eval() throws BuildException;
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java b/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java
index d057b46..e1fc93d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java
@@ -18,7 +18,9 @@
 
 package org.apache.tools.ant.taskdefs.condition;
 
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.List;
 import java.util.Vector;
 
 import org.apache.tools.ant.ProjectComponent;
@@ -43,7 +45,7 @@
     /**
      *
      */
-    private Vector conditions = new Vector();
+    private List<Condition> conditions = new Vector<>();
 
     /**
      * Simple constructor.
@@ -77,8 +79,8 @@
      * @return an enumeration to use for iteration
      * @since 1.1
      */
-    protected final Enumeration getConditions() {
-        return conditions.elements();
+    protected final Enumeration<Condition> getConditions() {
+        return Collections.enumeration(conditions);
     }
 
     /**
@@ -108,7 +110,7 @@
      * @since 1.1
      */
     public void addAvailable(Available a) {
-        conditions.addElement(a);
+        conditions.add(a);
     }
 
     /**
@@ -118,7 +120,7 @@
      * @since 1.4, Ant 1.5
      */
     public void addChecksum(Checksum c) {
-        conditions.addElement(c);
+        conditions.add(c);
     }
 
     /**
@@ -128,7 +130,7 @@
      * @since 1.1
      */
     public void addUptodate(UpToDate u) {
-        conditions.addElement(u);
+        conditions.add(u);
     }
 
     /**
@@ -138,7 +140,7 @@
      * @since 1.1
      */
     public void addNot(Not n) {
-        conditions.addElement(n);
+        conditions.add(n);
     }
 
     /**
@@ -148,7 +150,7 @@
      * @since 1.1
      */
     public void addAnd(And a) {
-        conditions.addElement(a);
+        conditions.add(a);
     }
 
     /**
@@ -158,7 +160,7 @@
      * @since 1.1
      */
     public void addOr(Or o) {
-        conditions.addElement(o);
+        conditions.add(o);
     }
 
     /**
@@ -168,7 +170,7 @@
      * @since 1.1
      */
     public void addEquals(Equals e) {
-        conditions.addElement(e);
+        conditions.add(e);
     }
 
     /**
@@ -178,7 +180,7 @@
      * @since 1.1
      */
     public void addOs(Os o) {
-        conditions.addElement(o);
+        conditions.add(o);
     }
 
     /**
@@ -188,7 +190,7 @@
      * @since Ant 1.5
      */
     public void addIsSet(IsSet i) {
-        conditions.addElement(i);
+        conditions.add(i);
     }
 
     /**
@@ -198,7 +200,7 @@
      * @since Ant 1.5
      */
     public void addHttp(Http h) {
-        conditions.addElement(h);
+        conditions.add(h);
     }
 
     /**
@@ -208,7 +210,7 @@
      * @since Ant 1.5
      */
     public void addSocket(Socket s) {
-        conditions.addElement(s);
+        conditions.add(s);
     }
 
     /**
@@ -218,7 +220,7 @@
      * @since Ant 1.5
      */
     public void addFilesMatch(FilesMatch test) {
-        conditions.addElement(test);
+        conditions.add(test);
     }
 
     /**
@@ -228,7 +230,7 @@
      * @since Ant 1.5
      */
     public void addContains(Contains test) {
-        conditions.addElement(test);
+        conditions.add(test);
     }
 
     /**
@@ -238,7 +240,7 @@
      * @since Ant 1.5
      */
     public void addIsTrue(IsTrue test) {
-        conditions.addElement(test);
+        conditions.add(test);
     }
 
     /**
@@ -248,7 +250,7 @@
      * @since Ant 1.5
      */
     public void addIsFalse(IsFalse test) {
-        conditions.addElement(test);
+        conditions.add(test);
     }
 
     /**
@@ -258,7 +260,7 @@
      * @since Ant 1.6
      */
     public void addIsReference(IsReference i) {
-        conditions.addElement(i);
+        conditions.add(i);
     }
 
     /**
@@ -266,7 +268,7 @@
      * @param test the condition
      */
     public void addIsFileSelected(IsFileSelected test) {
-        conditions.addElement(test);
+        conditions.add(test);
     }
 
     /**
@@ -275,7 +277,7 @@
      * @since Ant 1.6
      */
     public void add(Condition c) {
-        conditions.addElement(c);
+        conditions.add(c);
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/Contains.java b/src/main/org/apache/tools/ant/taskdefs/condition/Contains.java
index 8830a39..79cf698 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/Contains.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/Contains.java
@@ -63,10 +63,11 @@
      * @return true if the substring is within the string
      * @exception BuildException if the attributes are not set correctly
      */
+    @Override
     public boolean eval() throws BuildException {
         if (string == null || subString == null) {
-            throw new BuildException("both string and substring are required "
-                                     + "in contains");
+            throw new BuildException(
+                "both string and substring are required in contains");
         }
 
         return caseSensitive
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/FilesMatch.java b/src/main/org/apache/tools/ant/taskdefs/condition/FilesMatch.java
index 5e99398..74c2b30 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/FilesMatch.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/FilesMatch.java
@@ -44,7 +44,6 @@
 
     private boolean textfile = false;
 
-
     /**
      * Sets the File1 attribute
      *
@@ -54,7 +53,6 @@
         this.file1 = file1;
     }
 
-
     /**
      * Sets the File2 attribute
      *
@@ -78,13 +76,14 @@
      * @return true if the files are equal
      * @exception BuildException if it all went pear-shaped
      */
+    @Override
     public boolean eval()
         throws BuildException {
 
         //validate
         if (file1 == null || file2 == null) {
-            throw new BuildException("both file1 and file2 are required in "
-                                     + "filesmatch");
+            throw new BuildException(
+                "both file1 and file2 are required in filesmatch");
         }
 
         //#now match the files
@@ -98,4 +97,3 @@
         return matches;
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/HasFreeSpace.java b/src/main/org/apache/tools/ant/taskdefs/condition/HasFreeSpace.java
index 420c189..c41e1ee 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/HasFreeSpace.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/HasFreeSpace.java
@@ -41,6 +41,7 @@
      * @return true if there enough free space.
      * @throws BuildException if there is a problem.
      */
+    @Override
     public boolean eval() throws BuildException {
         validate();
         try {
@@ -48,11 +49,11 @@
                 //reflection to avoid bootstrap/build problems
                 File fs = new File(partition);
                 ReflectWrapper w = new ReflectWrapper(fs);
-                long free = ((Long) w.invoke("getFreeSpace")).longValue();
+                long free = w.<Long> invoke("getFreeSpace").longValue();
                 return free >= StringUtils.parseHumanSizes(needed);
-            } else {
-                throw new BuildException("HasFreeSpace condition not supported on Java5 or less.");
             }
+            throw new BuildException(
+                "HasFreeSpace condition not supported on Java5 or less.");
         } catch (Exception e) {
             throw new BuildException(e);
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/HasMethod.java b/src/main/org/apache/tools/ant/taskdefs/condition/HasMethod.java
index 002af7a..1c338f8 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/HasMethod.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/HasMethod.java
@@ -37,7 +37,6 @@
     private AntClassLoader loader;
     private boolean ignoreSystemClasses = false;
 
-
     /**
      * Set the classpath to be used when searching for classes and resources.
      *
@@ -104,7 +103,7 @@
     /**
      * Check if a given class can be loaded.
      */
-    private Class loadClass(String classname) {
+    private Class<?> loadClass(String classname) {
         try {
             if (ignoreSystemClasses) {
                 loader = getProject().createClassLoader(classpath);
@@ -114,25 +113,23 @@
                     return loader.findClass(classname);
                 } catch (SecurityException se) {
                     // class found but restricted name
-                    throw new BuildException("class \"" + classname
-                                             + "\" was found but a"
-                                             + " SecurityException has been"
-                                             + " raised while loading it",
-                                             se);
-                }
-            } else if (loader != null) {
-                // How do we ever get here?
-                return loader.loadClass(classname);
-            } else {
-                ClassLoader l = this.getClass().getClassLoader();
-                // Can return null to represent the bootstrap class loader.
-                // see API docs of Class.getClassLoader.
-                if (l != null) {
-                    return Class.forName(classname, true, l);
-                } else {
-                    return Class.forName(classname);
+                    throw new BuildException(
+                        "class \"" + classname
+                            + "\" was found but a SecurityException has been raised while loading it",
+                        se);
                 }
             }
+            if (loader != null) {
+                // How do we ever get here?
+                return loader.loadClass(classname);
+            }
+            ClassLoader l = this.getClass().getClassLoader();
+            // Can return null to represent the bootstrap class loader.
+            // see API docs of Class.getClassLoader.
+            if (l != null) {
+                return Class.forName(classname, true, l);
+            }
+            return Class.forName(classname);
         } catch (ClassNotFoundException e) {
             throw new BuildException("class \"" + classname
                                      + "\" was not found");
@@ -143,15 +140,15 @@
         }
     }
 
-
     /** {@inheritDoc}. */
+    @Override
     public boolean eval() throws BuildException {
         if (classname == null) {
             throw new BuildException("No classname defined");
         }
         ClassLoader preLoadClass = loader;
         try {
-            Class clazz = loadClass(classname);
+            Class<?> clazz = loadClass(classname);
             if (method != null) {
                 return isMethodFound(clazz);
             }
@@ -167,7 +164,7 @@
         }
     }
 
-    private boolean isFieldFound(Class clazz) {
+    private boolean isFieldFound(Class<?> clazz) {
         Field[] fields = clazz.getDeclaredFields();
         for (int i = 0; i < fields.length; i++) {
             Field fieldEntry = fields[i];
@@ -178,7 +175,7 @@
         return false;
     }
 
-    private boolean isMethodFound(Class clazz) {
+    private boolean isMethodFound(Class<?> clazz) {
         Method[] methods = clazz.getDeclaredMethods();
         for (int i = 0; i < methods.length; i++) {
             Method methodEntry = methods[i];
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/Http.java b/src/main/org/apache/tools/ant/taskdefs/condition/Http.java
index c163ad7..5a46105 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/Http.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/Http.java
@@ -18,6 +18,7 @@
 
 package org.apache.tools.ant.taskdefs.condition;
 
+import java.io.IOException;
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.ProtocolException;
@@ -44,6 +45,8 @@
     private String requestMethod = DEFAULT_REQUEST_METHOD;
     private boolean followRedirects = true;
 
+    private int errorsBeginAt = ERROR_BEGINS;
+
     /**
      * Set the url attribute
      * @param url the url of the request
@@ -52,8 +55,6 @@
         spec = url;
     }
 
-    private int errorsBeginAt = ERROR_BEGINS;
-
     /**
      * Set the errorsBeginAt attribute
      * @param errorsBeginAt number at which errors begin at, default is
@@ -95,6 +96,7 @@
      * @return true if the HTTP request succeeds
      * @exception BuildException if an error occurs
      */
+    @Override
     public boolean eval() throws BuildException {
         if (spec == null) {
             throw new BuildException("No url specified in http condition");
@@ -119,7 +121,7 @@
             } catch (ProtocolException pe) {
                 throw new BuildException("Invalid HTTP protocol: "
                                          + requestMethod, pe);
-            } catch (java.io.IOException e) {
+            } catch (IOException e) {
                 return false;
             }
         } catch (MalformedURLException e) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/IsLastModified.java b/src/main/org/apache/tools/ant/taskdefs/condition/IsLastModified.java
index ac05478..cd2cb65 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/IsLastModified.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/IsLastModified.java
@@ -69,9 +69,11 @@
      */
     public void setPattern(final String pattern) {
         dfFactory = new Touch.DateFormatFactory() {
+            @Override
             public DateFormat getPrimaryFormat() {
                 return new SimpleDateFormat(pattern);
             }
+            @Override
             public DateFormat getFallbackFormat() {
                 return null;
             }
@@ -104,8 +106,8 @@
      */
     protected void validate() throws BuildException {
         if (millis >= 0 && dateTime != null) {
-            throw new BuildException("Only one of dateTime and millis can be"
-                                     + " set");
+            throw new BuildException(
+                "Only one of dateTime and millis can be set");
         }
         if (millis < 0 && dateTime == null) {
             throw new BuildException("millis or dateTime is required");
@@ -129,7 +131,7 @@
             return System.currentTimeMillis();
         }
         DateFormat df = dfFactory.getPrimaryFormat();
-        ParseException pe = null;
+        ParseException pe;
         try {
             return df.parse(dateTime).getTime();
         } catch (ParseException peOne) {
@@ -144,11 +146,7 @@
                 }
             }
         }
-        if (pe != null) {
-            throw new BuildException(pe.getMessage(), pe, getLocation());
-        }
-        /* NOTREACHED */
-        return 0;
+        throw new BuildException(pe.getMessage(), pe, getLocation());
     }
 
     /**
@@ -156,6 +154,7 @@
      * @return true or false depending on the comparison mode and the time of the resource
      * @throws BuildException if something goes wrong
      */
+    @Override
     public boolean eval() throws BuildException {
         validate();
         long expected = getMillis();
@@ -209,6 +208,7 @@
             setValue(s);
         }
 
+        @Override
         public String[] getValues() {
             return new String[] {
                 EQUALS_TEXT, BEFORE_TEXT, AFTER_TEXT, NOT_BEFORE_TEXT,
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/IsReachable.java b/src/main/org/apache/tools/ant/taskdefs/condition/IsReachable.java
index e673b82..9083dd6 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/IsReachable.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/IsReachable.java
@@ -52,16 +52,13 @@
  * @since Ant 1.7
  */
 public class IsReachable extends ProjectComponent implements Condition {
-
-    private static final int SECOND = 1000; // millis per second
-    private String host;
-    private String url;
-
     /**
      * The default timeout.
      */
     public static final int DEFAULT_TIMEOUT = 30;
-    private int timeout = DEFAULT_TIMEOUT;
+
+    private static final int SECOND = 1000; // millis per second
+
     /**
      * Error when no hostname is defined
      */
@@ -91,6 +88,11 @@
     /** The method name to look for in InetAddress */
     public static final String METHOD_NAME = "isReachable";
 
+    private String host;
+    private String url;
+
+    private int timeout = DEFAULT_TIMEOUT;
+
     /**
      * Set the host to ping.
      *
@@ -129,8 +131,6 @@
         return string == null || string.length() == 0;
     }
 
-    private static Class[] parameterTypes = {Integer.TYPE};
-
     /**
      * Evaluate the condition.
      *
@@ -139,6 +139,7 @@
      * @throws org.apache.tools.ant.BuildException
      *          if an error occurs
      */
+    @Override
     public boolean eval() throws BuildException {
         if (empty(host) && empty(url)) {
             throw new BuildException(ERROR_NO_HOSTNAME);
@@ -174,15 +175,12 @@
                 Project.MSG_VERBOSE);
         boolean reachable;
         //Java1.5: reachable = address.isReachable(timeout * 1000);
-        Method reachableMethod = null;
         try {
-            reachableMethod = InetAddress.class.getMethod(METHOD_NAME,
-                    parameterTypes);
-            final Object[] params = new Object[1];
-            params[0] = new Integer(timeout * SECOND);
+            Method reachableMethod =
+                InetAddress.class.getMethod(METHOD_NAME, Integer.class);
             try {
-                reachable = ((Boolean) reachableMethod.invoke(address, params))
-                        .booleanValue();
+                reachable = ((Boolean) reachableMethod.invoke(address,
+                    Integer.valueOf(timeout * SECOND))).booleanValue();
             } catch (final IllegalAccessException e) {
                 //utterly implausible, but catered for anyway
                 throw new BuildException("When calling " + reachableMethod);
@@ -198,7 +196,6 @@
             log("Not found: InetAddress." + METHOD_NAME, Project.MSG_VERBOSE);
             log(MSG_NO_REACHABLE_TEST);
             reachable = true;
-
         }
 
         log("host is" + (reachable ? "" : " not") + " reachable", Project.MSG_VERBOSE);
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/IsReference.java b/src/main/org/apache/tools/ant/taskdefs/condition/IsReference.java
index f172849..30e2573 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/IsReference.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/IsReference.java
@@ -56,34 +56,35 @@
      *              the reference is the same type
      * @exception BuildException if an error occurs
      */
+    @Override
     public boolean eval() throws BuildException {
         if (ref == null) {
-            throw new BuildException("No reference specified for isreference "
-                                     + "condition");
+            throw new BuildException(
+                "No reference specified for isreference condition");
         }
 
         String key = ref.getRefId();
         if (!getProject().hasReference(key)) {
             return false;
-        } else if (type == null) {
-            return true;
-        } else {
-            Object o = getProject().getReference(key);
-            Class typeClass =
-                (Class) getProject().getDataTypeDefinitions().get(type);
-
-            if (typeClass == null) {
-                typeClass =
-                    (Class) getProject().getTaskDefinitions().get(type);
-            }
-
-            if (typeClass == null) {
-                // don't know the type, should throw exception instead?
-                return false;
-            }
-
-            return typeClass.isAssignableFrom(o.getClass());
         }
+        if (type == null) {
+            return true;
+        }
+        Object o = getProject().getReference(key);
+        Class<?> typeClass =
+            getProject().getDataTypeDefinitions().get(type);
+
+        if (typeClass == null) {
+            typeClass =
+                getProject().getTaskDefinitions().get(type);
+        }
+
+        if (typeClass == null) {
+            // don't know the type, should throw exception instead?
+            return false;
+        }
+
+        return typeClass.isAssignableFrom(o.getClass());
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/IsSet.java b/src/main/org/apache/tools/ant/taskdefs/condition/IsSet.java
index d4a5914..1474a0b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/IsSet.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/IsSet.java
@@ -41,9 +41,11 @@
      * @return true if the property exists
      * @exception BuildException if the property attribute is not set
      */
+    @Override
     public boolean eval() throws BuildException {
         if (property == null) {
-            throw new BuildException("No property specified for isset " + "condition");
+            throw new BuildException(
+                "No property specified for isset condition");
         }
         return getProject().getProperty(property) != null;
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/IsSigned.java b/src/main/org/apache/tools/ant/taskdefs/condition/IsSigned.java
index 585fb3a..267ff19 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/IsSigned.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/IsSigned.java
@@ -71,13 +71,11 @@
      */
     public static boolean isSigned(File zipFile, String name)
         throws IOException {
-        ZipFile jarFile = null;
-        try {
-            jarFile = new ZipFile(zipFile);
+        try (ZipFile jarFile = new ZipFile(zipFile)) {
             if (null == name) {
-                Enumeration entries = jarFile.getEntries();
+                Enumeration<ZipEntry> entries = jarFile.getEntries();
                 while (entries.hasMoreElements()) {
-                    String eName = ((ZipEntry) entries.nextElement()).getName();
+                    String eName = entries.nextElement().getName();
                     if (eName.startsWith(SIG_START)
                         && eName.endsWith(SIG_END)) {
                         return true;
@@ -98,8 +96,6 @@
             }
 
             return shortSig || longSig;
-        } finally {
-            ZipFile.closeQuietly(jarFile);
         }
     }
 
@@ -109,6 +105,7 @@
      * specified, if the file contains a signature.
      * @return true if the file is signed.
      */
+    @Override
     public boolean eval() {
         if (file == null) {
             throw new BuildException("The file attribute must be set.");
@@ -135,7 +132,7 @@
     }
 
     private static String replaceInvalidChars(final String name) {
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         final int len = name.length();
         boolean changes = false;
         for (int i = 0; i < len; i++) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/IsTrue.java b/src/main/org/apache/tools/ant/taskdefs/condition/IsTrue.java
index 753b441..e64d9ac 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/IsTrue.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/IsTrue.java
@@ -44,6 +44,7 @@
      * @return the value
      * @throws BuildException if someone forgot to spec a value
      */
+    @Override
     public boolean eval() throws BuildException {
         if (value == null) {
             throw new BuildException("Nothing to test for truth");
@@ -52,4 +53,3 @@
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/JavaVersion.java b/src/main/org/apache/tools/ant/taskdefs/condition/JavaVersion.java
index 69a9290..3e37199 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/JavaVersion.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/JavaVersion.java
@@ -23,7 +23,7 @@
 
 /**
  * An Java version condition.
- * @since Java 1.9.10
+ * @since Java 1.10.2
  */
 public class JavaVersion implements Condition {
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/Not.java b/src/main/org/apache/tools/ant/taskdefs/condition/Not.java
index a39dcbb..453be71 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/Not.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/Not.java
@@ -36,15 +36,16 @@
      * @return true if the condition is true.
      * @throws BuildException if the condition is not configured correctly.
      */
+    @Override
     public boolean eval() throws BuildException {
         if (countConditions() > 1) {
-            throw new BuildException("You must not nest more than one "
-                + "condition into <not>");
+            throw new BuildException(
+                "You must not nest more than one condition into <not>");
         }
         if (countConditions() < 1) {
             throw new BuildException("You must nest a condition into <not>");
         }
-        return !((Condition) getConditions().nextElement()).eval();
+        return !getConditions().nextElement().eval();
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/Or.java b/src/main/org/apache/tools/ant/taskdefs/condition/Or.java
index aedfe74..c16f89f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/Or.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/Or.java
@@ -36,10 +36,11 @@
      * @return true if any of the contained conditions evaluate to true
      * @exception BuildException if an error occurs
      */
+    @Override
     public boolean eval() throws BuildException {
-        Enumeration e = getConditions();
+        Enumeration<Condition> e = getConditions();
         while (e.hasMoreElements()) {
-            Condition c = (Condition) e.nextElement();
+            Condition c = e.nextElement();
             if (c.eval()) {
                 return true;
             }
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/Os.java b/src/main/org/apache/tools/ant/taskdefs/condition/Os.java
index 7bd5b01..1d9e2d1 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/Os.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/Os.java
@@ -38,22 +38,6 @@
         System.getProperty("path.separator");
 
     /**
-     * OS family to look for
-     */
-    private String family;
-    /**
-     * Name of OS
-     */
-    private String name;
-    /**
-     * version of OS
-     */
-    private String version;
-    /**
-     * OS architecture
-     */
-    private String arch;
-    /**
      * OS family that can be tested for. {@value}
      */
     public static final String FAMILY_WINDOWS = "windows";
@@ -108,6 +92,23 @@
     private static final String DARWIN = "darwin";
 
     /**
+     * OS family to look for
+     */
+    private String family;
+    /**
+     * Name of OS
+     */
+    private String name;
+    /**
+     * version of OS
+     */
+    private String version;
+    /**
+     * OS architecture
+     */
+    private String arch;
+
+    /**
      * Default constructor
      *
      */
@@ -179,6 +180,7 @@
      * @throws BuildException if there is an error.
      * @see Os#setFamily(String)
      */
+    @Override
     public boolean eval() throws BuildException {
         return isOs(family, name, arch, version);
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/ParserSupports.java b/src/main/org/apache/tools/ant/taskdefs/condition/ParserSupports.java
index d283401..21a5c19 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/ParserSupports.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/ParserSupports.java
@@ -31,9 +31,6 @@
  */
 public class ParserSupports extends ProjectComponent implements Condition {
 
-    private String feature;
-    private String property;
-    private String value;
     // Error messages
     /** error - combined attributes not allowed */
     public static final String ERROR_BOTH_ATTRIBUTES =
@@ -56,6 +53,10 @@
     public static final String ERROR_NO_VALUE =
         "A value is needed when testing for property support";
 
+    private String feature;
+    private String property;
+    private String value;
+
     /**
      * Feature to probe for.
      * @param feature the feature to probe for.
@@ -82,6 +83,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public boolean eval() throws BuildException {
         if (feature != null && property != null) {
             throw new BuildException(ERROR_BOTH_ATTRIBUTES);
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/ResourceContains.java b/src/main/org/apache/tools/ant/taskdefs/condition/ResourceContains.java
index 76a9ad3..ae7e1f5 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/ResourceContains.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/ResourceContains.java
@@ -88,8 +88,8 @@
                         o = rc.iterator().next();
                     }
                 } else {
-                    throw new BuildException(
-                        "Illegal value at '" + refid + "': " + String.valueOf(o));
+                    throw new BuildException("Illegal value at '%s': %s", refid,
+                        o);
                 }
             }
             this.resource = (Resource) o;
@@ -122,8 +122,8 @@
             resolveRefid();
         }
         if (resource == null || substring == null) {
-            throw new BuildException("both resource and substring are required "
-                                     + "in <resourcecontains>");
+            throw new BuildException(
+                "both resource and substring are required in <resourcecontains>");
         }
     }
 
@@ -132,6 +132,7 @@
      * @return true if the substring is contained in the resource
      * @throws BuildException if there is a problem.
      */
+    @Override
     public synchronized boolean eval() throws BuildException {
         validate();
 
@@ -146,9 +147,8 @@
             return false;
         }
 
-        BufferedReader reader = null;
-        try {
-            reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
+        try (BufferedReader reader = new BufferedReader(
+            new InputStreamReader(resource.getInputStream()))) {
             String contents = FileUtils.safeReadFully(reader);
             String sub = substring;
             if (!casesensitive) {
@@ -158,8 +158,6 @@
             return contents.indexOf(sub) >= 0;
         } catch (IOException e) {
             throw new BuildException("There was a problem accessing resource : " + resource);
-        } finally {
-            FileUtils.close(reader);
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/ResourcesMatch.java b/src/main/org/apache/tools/ant/taskdefs/condition/ResourcesMatch.java
index 29e3e80..5a1282d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/ResourcesMatch.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/ResourcesMatch.java
@@ -65,6 +65,7 @@
      * @return true if all resources are equal.
      * @exception BuildException if there is an error.
      */
+    @Override
     public boolean eval() throws BuildException {
         if (resources == null) {
             throw new BuildException(
@@ -72,11 +73,11 @@
         }
         if (resources.size() > 1) {
             Iterator<Resource> i = resources.iterator();
-            Resource r1 = (Resource) i.next();
-            Resource r2 = null;
+            Resource r1 = i.next();
+            Resource r2;
 
             while (i.hasNext()) {
-                r2 = (Resource) i.next();
+                r2 = i.next();
                 try {
                     if (!ResourceUtils.contentEquals(r1, r2, asText)) {
                         return false;
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/Socket.java b/src/main/org/apache/tools/ant/taskdefs/condition/Socket.java
index d6a69ec..6801b5c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/Socket.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/Socket.java
@@ -57,31 +57,21 @@
      * @return true if a socket can be created
      * @exception BuildException if the attributes are not set
      */
+    @Override
     public boolean eval() throws BuildException {
         if (server == null) {
-            throw new BuildException("No server specified in socket "
-                                     + "condition");
+            throw new BuildException("No server specified in socket condition");
         }
         if (port == 0) {
             throw new BuildException("No port specified in socket condition");
         }
         log("Checking for listener at " + server + ":" + port,
             Project.MSG_VERBOSE);
-        java.net.Socket s = null;
-        try {
-            s = new java.net.Socket(server, port);
+        try (java.net.Socket s = new java.net.Socket(server, port)) {
+            return true;
         } catch (IOException e) {
             return false;
-        } finally {
-          if (s != null) {
-            try {
-              s.close();
-            } catch (IOException ioe) {
-              // Intentionally left blank
-            }
-          }
         }
-        return true;
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/TypeFound.java b/src/main/org/apache/tools/ant/taskdefs/condition/TypeFound.java
index f97c7f4..f51e02d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/TypeFound.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/TypeFound.java
@@ -58,7 +58,6 @@
      * @return true if the typename exists
      */
     protected boolean doesTypeExist(String typename) {
-
         ComponentHelper helper =
             ComponentHelper.getComponentHelper(getProject());
         String componentName = ProjectHelper.genComponentName(uri, typename);
@@ -81,6 +80,7 @@
      * @return true if the condition is true
      * @exception BuildException if an error occurs
      */
+    @Override
     public boolean eval() throws BuildException {
         if (name == null) {
             throw new BuildException("No type specified");
diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/Xor.java b/src/main/org/apache/tools/ant/taskdefs/condition/Xor.java
index a2e675c..4478f33 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/Xor.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/Xor.java
@@ -34,12 +34,13 @@
      * @throws org.apache.tools.ant.BuildException
      *          if an error occurs.
      */
+    @Override
     public boolean eval() throws BuildException {
-        Enumeration e = getConditions();
+        Enumeration<Condition> e = getConditions();
         //initial state is false.
         boolean state = false;
         while (e.hasMoreElements()) {
-            Condition c = (Condition) e.nextElement();
+            Condition c = e.nextElement();
             //every condition is xored against the previous one
             state ^= c.eval();
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/cvslib/CVSEntry.java b/src/main/org/apache/tools/ant/taskdefs/cvslib/CVSEntry.java
index b1a9a12..6f16f08 100644
--- a/src/main/org/apache/tools/ant/taskdefs/cvslib/CVSEntry.java
+++ b/src/main/org/apache/tools/ant/taskdefs/cvslib/CVSEntry.java
@@ -28,7 +28,7 @@
     private Date date;
     private String author;
     private final String comment;
-    private final Vector files = new Vector();
+    private final Vector<RCSFile> files = new Vector<>();
 
     /**
      * Creates a new instance of a CVSEntry
@@ -48,7 +48,7 @@
      * @param revision the revision
      */
     public void addFile(final String file, final String revision) {
-        files.addElement(new RCSFile(file, revision));
+        files.add(new RCSFile(file, revision));
     }
 
     /**
@@ -58,7 +58,7 @@
      * @param previousRevision the previous revision
      */
     public void addFile(final String file, final String revision, final String previousRevision) {
-        files.addElement(new RCSFile(file, revision, previousRevision));
+        files.add(new RCSFile(file, revision, previousRevision));
     }
 
     /**
@@ -97,7 +97,7 @@
      * Gets the files in this CVSEntry
      * @return the files
      */
-    public Vector getFiles() {
+    public Vector<RCSFile> getFiles() {
         return files;
     }
 
@@ -105,6 +105,7 @@
      * Gets a String containing author, date, files and comment
      * @return a string representation of this CVSEntry
      */
+    @Override
     public String toString() {
         return getAuthor() + "\n" + getDate() + "\n" + getFiles() + "\n"
             + getComment();
diff --git a/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogParser.java b/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogParser.java
index b088107..10a9bc4 100644
--- a/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogParser.java
+++ b/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogParser.java
@@ -20,24 +20,23 @@
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
-import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.TimeZone;
 
 import org.apache.tools.ant.taskdefs.AbstractCvsTask;
-import org.apache.tools.ant.util.CollectionUtils;
+import org.apache.tools.ant.taskdefs.AbstractCvsTask.Module;
 
 /**
  * A class used to parse the output of the CVS log command.
  *
  */
 class ChangeLogParser {
-    //private static final int GET_ENTRY = 0;
     private static final int GET_FILE = 1;
     private static final int GET_DATE = 2;
     private static final int GET_COMMENT = 3;
@@ -53,9 +52,6 @@
     private final SimpleDateFormat cvs1129InputDate =
         new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", Locale.US);
 
-    static {
-    }
-
     //The following is data used while processing stdout of CVS command
     private String file;
     private String date;
@@ -67,32 +63,29 @@
     private int status = GET_FILE;
 
     /** rcs entries */
-    private final Hashtable entries = new Hashtable();
+    private final Map<String, CVSEntry> entries = new Hashtable<>();
 
     private final boolean remote;
     private final String[] moduleNames;
     private final int[] moduleNameLengths;
 
     public ChangeLogParser() {
-        this(false, "", CollectionUtils.EMPTY_LIST);
+        this(false, "", Collections.emptyList());
     }
 
-    public ChangeLogParser(boolean remote, String packageName, List modules) {
+    public ChangeLogParser(boolean remote, String packageName, List<AbstractCvsTask.Module> modules) {
         this.remote = remote;
 
-        ArrayList names = new ArrayList();
+        List<String> names = new ArrayList<>();
         if (packageName != null) {
             for (StringTokenizer tok = new StringTokenizer(packageName);
                  tok.hasMoreTokens();) {
                 names.add(tok.nextToken());
             }
         }
-        for (Iterator iter = modules.iterator(); iter.hasNext();) {
-            AbstractCvsTask.Module m = (AbstractCvsTask.Module) iter.next();
-            names.add(m.getName());
-        }
+        modules.stream().map(Module::getName).forEach(names::add);
 
-        moduleNames = (String[]) names.toArray(new String[names.size()]);
+        moduleNames = names.toArray(new String[names.size()]);
         moduleNameLengths = new int[moduleNames.length];
         for (int i = 0; i < moduleNames.length; i++) {
             moduleNameLengths[i] = moduleNames[i].length();
@@ -109,12 +102,7 @@
      * @return a list of rcs entries as an array
      */
     public CVSEntry[] getEntrySetAsArray() {
-        final CVSEntry[] array = new CVSEntry[ entries.size() ];
-        int i = 0;
-        for (Enumeration e = entries.elements(); e.hasMoreElements();) {
-            array[i++] = (CVSEntry) e.nextElement();
-        }
-        return array;
+        return entries.values().toArray(new CVSEntry[entries.size()]);
     }
 
     /**
@@ -123,7 +111,7 @@
      * @param line the line to process
      */
     public void stdout(final String line) {
-        switch(status) {
+        switch (status) {
             case GET_FILE:
                 // make sure attributes are reset when
                 // working on a 'new' file.
@@ -159,8 +147,8 @@
      */
     private void processComment(final String line) {
         final String lineSeparator = System.getProperty("line.separator");
-        if (line.equals(
-                "=============================================================================")) {
+        if ("============================================================================="
+            .equals(line)) {
             //We have ended changelog for that particular file
             //so we can save it
             final int end
@@ -168,7 +156,7 @@
             comment = comment.substring(0, end);
             saveEntry();
             status = GET_FILE;
-        } else if (line.equals("----------------------------")) {
+        } else if ("----------------------------".equals(line)) {
             final int end
                 = comment.length() - lineSeparator.length(); //was -1
             comment = comment.substring(0, end);
@@ -275,17 +263,9 @@
      * Utility method that saves the current entry.
      */
     private void saveEntry() {
-        final String entryKey = date + author + comment;
-        CVSEntry entry;
-        if (!entries.containsKey(entryKey)) {
-            Date dateObject = parseDate(date);
-            entry = new CVSEntry(dateObject, author, comment);
-            entries.put(entryKey, entry);
-        } else {
-            entry = (CVSEntry) entries.get(entryKey);
-        }
-
-        entry.addFile(file, revision, previousRevision);
+        entries.computeIfAbsent(date + author + comment, k -> {
+            return new CVSEntry(parseDate(date), author, comment);
+        }).addFile(file, revision, previousRevision);
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogTask.java b/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogTask.java
index 81dadfd..8182749 100644
--- a/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogTask.java
@@ -18,15 +18,15 @@
 package org.apache.tools.ant.taskdefs.cvslib;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
+import java.nio.file.Files;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Date;
-import java.util.Enumeration;
+import java.util.List;
 import java.util.Properties;
 import java.util.Vector;
 
@@ -35,7 +35,6 @@
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.taskdefs.AbstractCvsTask;
 import org.apache.tools.ant.types.FileSet;
-import org.apache.tools.ant.util.FileUtils;
 
 /**
  * Examines the output of cvs log and group related changes together.
@@ -70,7 +69,7 @@
     private File usersFile;
 
     /** User list */
-    private Vector cvsUsers = new Vector();
+    private List<CvsUser> cvsUsers = new Vector<>();
 
     /** Input dir */
     private File inputDir;
@@ -98,8 +97,7 @@
      * performed. If empty then all files in the working directory will
      * be checked.
      */
-    private final Vector filesets = new Vector();
-
+    private final List<FileSet> filesets = new Vector<>();
 
     /**
      * Set the base dir for cvs.
@@ -110,7 +108,6 @@
         this.inputDir = inputDir;
     }
 
-
     /**
      * Set the output file for the log.
      *
@@ -120,7 +117,6 @@
         this.destFile = destFile;
     }
 
-
     /**
      * Set a lookup list of user names &amp; addresses
      *
@@ -130,17 +126,15 @@
         this.usersFile = usersFile;
     }
 
-
     /**
      * Add a user to list changelog knows about.
      *
      * @param user the user
      */
     public void addUser(final CvsUser user) {
-        cvsUsers.addElement(user);
+        cvsUsers.add(user);
     }
 
-
     /**
      * Set the date at which the changelog should start.
      *
@@ -150,7 +144,6 @@
         this.startDate = start;
     }
 
-
     /**
      * Set the date at which the changelog should stop.
      *
@@ -160,7 +153,6 @@
         this.endDate = endDate;
     }
 
-
     /**
      * Set the number of days worth of log entries to process.
      *
@@ -195,7 +187,6 @@
         this.startTag = start;
     }
 
-
     /**
      * Set the tag at which the changelog should stop.
      *
@@ -211,29 +202,26 @@
      * @param fileSet a set of files about which cvs logs will be generated.
      */
     public void addFileset(final FileSet fileSet) {
-        filesets.addElement(fileSet);
+        filesets.add(fileSet);
     }
 
-
     /**
      * Execute task
      *
      * @exception BuildException if something goes wrong executing the
      *            cvs command
      */
+    @Override
     public void execute() throws BuildException {
         File savedDir = inputDir; // may be altered in validate
 
         try {
-
             validate();
             final Properties userList = new Properties();
 
             loadUserlist(userList);
 
-            final int size = cvsUsers.size();
-            for (int i = 0; i < size; i++) {
-                final CvsUser user = (CvsUser) cvsUsers.get(i);
+            for (CvsUser user : cvsUsers) {
                 user.validate();
                 userList.put(user.getUserID(), user.getDisplayname());
             }
@@ -283,18 +271,11 @@
             }
 
             // Check if list of files to check has been specified
-            if (!filesets.isEmpty()) {
-                final Enumeration e = filesets.elements();
-
-                while (e.hasMoreElements()) {
-                    final FileSet fileSet = (FileSet) e.nextElement();
-                    final DirectoryScanner scanner =
-                        fileSet.getDirectoryScanner(getProject());
-                    final String[] files = scanner.getIncludedFiles();
-
-                    for (int i = 0; i < files.length; i++) {
-                        addCommandArgument(files[i]);
-                    }
+            for (FileSet fileSet : filesets) {
+                final DirectoryScanner scanner =
+                    fileSet.getDirectoryScanner(getProject());
+                for (String file : scanner.getIncludedFiles()) {
+                    addCommandArgument(file);
                 }
             }
 
@@ -340,27 +321,20 @@
             inputDir = getProject().getBaseDir();
         }
         if (null == destFile) {
-            final String message = "Destfile must be set.";
-
-            throw new BuildException(message);
+            throw new BuildException("Destfile must be set.");
         }
         if (!inputDir.exists()) {
-            final String message = "Cannot find base dir "
-                 + inputDir.getAbsolutePath();
-
-            throw new BuildException(message);
+            throw new BuildException("Cannot find base dir %s",
+                inputDir.getAbsolutePath());
         }
         if (null != usersFile && !usersFile.exists()) {
-            final String message = "Cannot find user lookup list "
-                 + usersFile.getAbsolutePath();
-
-            throw new BuildException(message);
+            throw new BuildException("Cannot find user lookup list %s",
+                usersFile.getAbsolutePath());
         }
         if ((null != startTag || null != endTag)
             && (null != startDate || null != endDate)) {
-            final String message = "Specify either a tag or date range,"
-                + " not both";
-            throw new BuildException(message);
+            throw new BuildException(
+                "Specify either a tag or date range, not both");
         }
     }
 
@@ -375,7 +349,7 @@
          throws BuildException {
         if (null != usersFile) {
             try {
-                userList.load(new FileInputStream(usersFile));
+                userList.load(Files.newInputStream(usersFile.toPath()));
             } catch (final IOException ioe) {
                 throw new BuildException(ioe.toString(), ioe);
             }
@@ -389,10 +363,9 @@
      * @return the filtered entry set
      */
     private CVSEntry[] filterEntrySet(final CVSEntry[] entrySet) {
-        final Vector results = new Vector();
+        final List<CVSEntry> results = new ArrayList<>();
 
-        for (int i = 0; i < entrySet.length; i++) {
-            final CVSEntry cvsEntry = entrySet[i];
+        for (CVSEntry cvsEntry : entrySet) {
             final Date date = cvsEntry.getDate();
 
             //bug#30471
@@ -420,13 +393,10 @@
                 //Skip dates that are too late
                 continue;
             }
-            results.addElement(cvsEntry);
+            results.add(cvsEntry);
         }
 
-        final CVSEntry[] resultArray = new CVSEntry[results.size()];
-
-        results.copyInto(resultArray);
-        return resultArray;
+        return results.toArray(new CVSEntry[results.size()]);
     }
 
     /**
@@ -434,9 +404,7 @@
      */
     private void replaceAuthorIdWithName(final Properties userList,
                                          final CVSEntry[] entrySet) {
-        for (int i = 0; i < entrySet.length; i++) {
-
-            final CVSEntry entry = entrySet[ i ];
+        for (final CVSEntry entry : entrySet) {
             if (userList.containsKey(entry.getAuthor())) {
                 entry.setAuthor(userList.getProperty(entry.getAuthor()));
             }
@@ -451,17 +419,11 @@
      */
     private void writeChangeLog(final CVSEntry[] entrySet)
          throws BuildException {
-        FileOutputStream output = null;
 
-        try {
-            output = new FileOutputStream(destFile);
+        try (final PrintWriter writer = new PrintWriter(
+            new OutputStreamWriter(Files.newOutputStream(destFile.toPath()), "UTF-8"))) {
 
-            final PrintWriter writer =
-                new PrintWriter(new OutputStreamWriter(output, "UTF-8"));
-
-            final ChangeLogWriter serializer = new ChangeLogWriter();
-
-            serializer.printChangeLog(writer, entrySet);
+            new ChangeLogWriter().printChangeLog(writer, entrySet);
 
             if (writer.checkError()) {
                 throw new IOException("Encountered an error writing changelog");
@@ -470,9 +432,6 @@
             getProject().log(uee.toString(), Project.MSG_ERR);
         } catch (final IOException ioe) {
             throw new BuildException(ioe.toString(), ioe);
-        } finally {
-            FileUtils.close(output);
         }
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogWriter.java b/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogWriter.java
index ce92327..991c6fb 100644
--- a/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogWriter.java
+++ b/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogWriter.java
@@ -20,9 +20,9 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
-import java.util.Enumeration;
 import java.util.TimeZone;
 
+import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.util.DOMElementWriter;
 import org.apache.tools.ant.util.DOMUtils;
 import org.w3c.dom.Document;
@@ -36,9 +36,11 @@
     /** output format for dates written to xml file */
     private final SimpleDateFormat outputDate
         = new SimpleDateFormat("yyyy-MM-dd");
+
     /** output format for times written to xml file */
     private SimpleDateFormat outputTime
         = new SimpleDateFormat("HH:mm");
+
     /** stateless helper for writing the XML document */
     private static final DOMElementWriter DOM_WRITER = new DOMElementWriter();
 
@@ -62,20 +64,17 @@
             Element root = doc.createElement("changelog");
             DOM_WRITER.openElement(root, output, 0, "\t");
             output.println();
-            for (int i = 0; i < entries.length; i++) {
-                final CVSEntry entry = entries[i];
-
+            for (final CVSEntry entry : entries) {
                 printEntry(doc, output, entry);
             }
             DOM_WRITER.closeElement(root, output, 0, "\t", true);
             output.flush();
             output.close();
         } catch (IOException e) {
-            throw new org.apache.tools.ant.BuildException(e);
+            throw new BuildException(e);
         }
     }
 
-
     /**
      * Print out an individual entry in changelog.
      *
@@ -92,11 +91,7 @@
                                    outputTime.format(entry.getDate()));
         DOMUtils.appendCDATAElement(ent, "author", entry.getAuthor());
 
-        final Enumeration enumeration = entry.getFiles().elements();
-
-        while (enumeration.hasMoreElements()) {
-            final RCSFile file = (RCSFile) enumeration.nextElement();
-
+        for (RCSFile file : entry.getFiles()) {
             Element f = DOMUtils.createChildElement(ent, "file");
             DOMUtils.appendCDATAElement(f, "name", file.getName());
             DOMUtils.appendTextElement(f, "revision", file.getRevision());
@@ -111,4 +106,3 @@
         DOM_WRITER.write(ent, output, 1, "\t");
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagDiff.java b/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagDiff.java
index 79111bd..3a61f7c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagDiff.java
+++ b/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagDiff.java
@@ -19,18 +19,15 @@
 
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
+import java.nio.file.Files;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.StringTokenizer;
-import java.util.Vector;
-
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.taskdefs.AbstractCvsTask;
@@ -151,7 +148,7 @@
     /**
      * temporary list of package names.
      */
-    private List packageNames = new ArrayList();
+    private List<String> packageNames = new ArrayList<>();
 
     /**
      * temporary list of "File:" + package name + "/" for all packages.
@@ -228,7 +225,6 @@
         ignoreRemoved = b;
     }
 
-
     /**
      * Execute task.
      *
@@ -296,10 +292,9 @@
      */
     private CvsTagEntry[] parseRDiff(File tmpFile) throws BuildException {
         // parse the output of the command
-        BufferedReader reader = null;
 
-        try {
-            reader = new BufferedReader(new FileReader(tmpFile)); //NOSONAR
+        try (BufferedReader reader =
+            new BufferedReader(new FileReader(tmpFile))) {
 
             // entries are of the form:
             //CVS 1.11
@@ -315,7 +310,7 @@
             // File testantoine/antoine.bat is removed; TESTANTOINE_1 revision 1.1.1.1
             //
             // get rid of 'File module/"
-            Vector entries = new Vector();
+            List<CvsTagEntry> entries = new ArrayList<>();
 
             String line = reader.readLine();
 
@@ -324,6 +319,7 @@
                                          packageNamePrefixLengths);
                 if (line != null) {
                     // use || in a perl like fashion
+                    @SuppressWarnings("unused")
                     boolean processed
                         =  doFileIsNew(entries, line)
                         || doFileHasChanged(entries, line)
@@ -332,24 +328,13 @@
                 line = reader.readLine();
             }
 
-            CvsTagEntry[] array = new CvsTagEntry[entries.size()];
-            entries.copyInto(array);
-
-            return array;
+            return entries.toArray(new CvsTagEntry[entries.size()]);
         } catch (IOException e) {
             throw new BuildException("Error in parsing", e);
-        } finally {
-            if (reader != null) {
-                try {
-                    reader.close();
-                } catch (IOException e) {
-                    log(e.toString(), Project.MSG_ERR);
-                }
-            }
         }
     }
 
-    private boolean doFileIsNew(Vector entries, String line) {
+    private boolean doFileIsNew(List<CvsTagEntry> entries, String line) {
         int index = line.indexOf(FILE_IS_NEW);
         if (index == -1) {
             return false;
@@ -363,12 +348,12 @@
             rev = line.substring(indexrev + REVISION.length());
         }
         CvsTagEntry entry = new CvsTagEntry(filename, rev);
-        entries.addElement(entry);
+        entries.add(entry);
         log(entry.toString(), Project.MSG_VERBOSE);
         return true;
     }
 
-    private boolean doFileHasChanged(Vector entries, String line) {
+    private boolean doFileHasChanged(List<CvsTagEntry> entries, String line) {
         int index = line.indexOf(FILE_HAS_CHANGED);
         if (index == -1) {
             return false;
@@ -384,12 +369,12 @@
         CvsTagEntry entry = new CvsTagEntry(filename,
                                             revision,
                                             prevRevision);
-        entries.addElement(entry);
+        entries.add(entry);
         log(entry.toString(), Project.MSG_VERBOSE);
         return true;
     }
 
-    private boolean doFileWasRemoved(Vector entries, String line) {
+    private boolean doFileWasRemoved(List<CvsTagEntry> entries, String line) {
         if (ignoreRemoved) {
             return false;
         }
@@ -405,7 +390,7 @@
             rev = line.substring(indexrev + REVISION.length());
         }
         CvsTagEntry entry = new CvsTagEntry(filename, null, rev);
-        entries.addElement(entry);
+        entries.add(entry);
         log(entry.toString(), Project.MSG_VERBOSE);
         return true;
     }
@@ -417,11 +402,8 @@
      * @exception BuildException if an error occurs
      */
     private void writeTagDiff(CvsTagEntry[] entries) throws BuildException {
-        FileOutputStream output = null;
-        try {
-            output = new FileOutputStream(mydestfile);
-            PrintWriter writer = new PrintWriter(
-                                     new OutputStreamWriter(output, "UTF-8"));
+        try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(
+            Files.newOutputStream(mydestfile.toPath()), "UTF-8"))) {
             writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
             Document doc = DOMUtils.newDocument();
             Element root = doc.createElement("tagdiff");
@@ -454,14 +436,6 @@
             log(uee.toString(), Project.MSG_ERR);
         } catch (IOException ioe) {
             throw new BuildException(ioe.toString(), ioe);
-        } finally {
-            if (null != output) {
-                try {
-                    output.close();
-                } catch (IOException ioe) {
-                    log(ioe.toString(), Project.MSG_ERR);
-                }
-            }
         }
     }
 
@@ -507,8 +481,8 @@
         }
 
         if (null != mystartTag && null != mystartDate) {
-            throw new BuildException("Only one of start tag and start date "
-                                     + "must be set.");
+            throw new BuildException(
+                "Only one of start tag and start date must be set.");
         }
 
         if (null == myendTag && null == myendDate) {
@@ -516,8 +490,8 @@
         }
 
         if (null != myendTag && null != myendDate) {
-            throw new BuildException("Only one of end tag and end date must "
-                                     + "be set.");
+            throw new BuildException(
+                "Only one of end tag and end date must be set.");
         }
     }
 
@@ -535,8 +509,7 @@
                 addCommandArgument(pack);
             }
         }
-        for (Iterator iter = getModules().iterator(); iter.hasNext();) {
-            AbstractCvsTask.Module m = (AbstractCvsTask.Module) iter.next();
+        for (Module m : getModules()) {
             packageNames.add(m.getName());
             // will be added to command line in super.execute()
         }
@@ -548,7 +521,6 @@
         }
     }
 
-
     /**
      * removes a "File: module/" prefix if present.
      *
@@ -560,17 +532,11 @@
         if (line.length() < FILE_STRING_LENGTH) {
             return null;
         }
-        boolean matched = false;
         for (int i = 0; i < packagePrefixes.length; i++) {
             if (line.startsWith(packagePrefixes[i])) {
-                matched = true;
-                line = line.substring(prefixLengths[i]);
-                break;
+                return line.substring(prefixLengths[i]);
             }
         }
-        if (!matched) {
-            line = line.substring(FILE_STRING_LENGTH);
-        }
-        return line;
+        return line.substring(FILE_STRING_LENGTH);
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagEntry.java b/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagEntry.java
index 6e349c7..031d164 100644
--- a/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagEntry.java
+++ b/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagEntry.java
@@ -89,8 +89,9 @@
      * Gets a String containing filename and difference from previous version
      * @return a string representation of this CVSTagEntry
      */
+    @Override
     public String toString() {
-        StringBuffer buffer = new StringBuffer();
+        StringBuilder buffer = new StringBuilder();
         buffer.append(filename);
         if (revision == null) {
             buffer.append(" was removed");
diff --git a/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsUser.java b/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsUser.java
index 85a2fc6..8fa6913 100644
--- a/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsUser.java
+++ b/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsUser.java
@@ -26,10 +26,10 @@
 public class CvsUser {
     /** The user's Id */
     private String userID;
+
     /** The user's full name */
     private String displayName;
 
-
     /**
      * Set the user's fullname
      *
@@ -39,7 +39,6 @@
         this.displayName = displayName;
     }
 
-
     /**
      * Set the user's id
      *
@@ -49,7 +48,6 @@
         this.userID = userID;
     }
 
-
     /**
      * Get the user's id.
      *
@@ -59,7 +57,6 @@
         return userID;
     }
 
-
     /**
      * Get the user's full name
      *
@@ -69,7 +66,6 @@
         return displayName;
     }
 
-
     /**
      * Validate that this object is configured.
      *
@@ -78,16 +74,11 @@
      */
     public void validate() throws BuildException {
         if (null == userID) {
-            final String message = "Username attribute must be set.";
-
-            throw new BuildException(message);
+            throw new BuildException("Username attribute must be set.");
         }
         if (null == displayName) {
-            final String message =
-                "Displayname attribute must be set for userID " + userID;
-
-            throw new BuildException(message);
+            throw new BuildException(
+                "Displayname attribute must be set for userID %s", userID);
         }
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsVersion.java b/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsVersion.java
index 618da4e..0e0fc20 100644
--- a/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsVersion.java
+++ b/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsVersion.java
@@ -43,6 +43,7 @@
 public class CvsVersion extends AbstractCvsTask {
     static final long VERSION_1_11_2 = 11102;
     static final long MULTIPLY = 100;
+
     private String clientVersion;
     private String serverVersion;
     private String clientVersionProperty;
@@ -55,6 +56,7 @@
     public String getClientVersion() {
         return clientVersion;
     }
+
     /**
      * Get the CVS server version
      * @return CVS server version
@@ -62,6 +64,7 @@
     public String getServerVersion() {
         return serverVersion;
     }
+
     /**
      * Set a property where to store the CVS client version
      * @param clientVersionProperty  property for CVS client version
@@ -77,6 +80,7 @@
     public void setServerVersionProperty(String serverVersionProperty) {
         this.serverVersionProperty = serverVersionProperty;
     }
+
     /**
      * Find out if the server version supports log with S option
      * @return  boolean indicating if the server version supports log with S option
@@ -90,7 +94,7 @@
         long version = 0;
         while (tokenizer.hasMoreTokens()) {
             String s = tokenizer.nextToken();
-            int i = 0;
+            int i;
             for (i = 0; i < s.length(); i++) {
                 if (!Character.isDigit(s.charAt(i))) {
                     break;
@@ -103,11 +107,13 @@
             }
             counter = counter / MULTIPLY;
         }
-        return (version >= VERSION_1_11_2);
+        return version >= VERSION_1_11_2;
     }
+
     /**
      * the execute method running CvsVersion
      */
+    @Override
     public void execute() {
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         this.setOutputStream(bos);
@@ -127,9 +133,9 @@
         while (haveReadAhead || st.hasMoreTokens()) {
             String currentToken = haveReadAhead ? cachedVersion : st.nextToken();
             haveReadAhead = false;
-            if (currentToken.equals("Client:")) {
+            if ("Client:".equals(currentToken)) {
                 client = true;
-            } else if (currentToken.equals("Server:")) {
+            } else if ("Server:".equals(currentToken)) {
                 server = true;
             } else if (currentToken.startsWith("(CVS")
                        && currentToken.endsWith(")")) {
@@ -151,7 +157,7 @@
                 }
                 server = false;
                 cvs = null;
-            } else if (currentToken.equals("(client/server)")
+            } else if ("(client/server)".equals(currentToken)
                        && cvs != null && cachedVersion != null
                        && !client && !server) {
                 client = server = true;
diff --git a/src/main/org/apache/tools/ant/taskdefs/cvslib/RCSFile.java b/src/main/org/apache/tools/ant/taskdefs/cvslib/RCSFile.java
index 70a8cf3..6c699aa 100644
--- a/src/main/org/apache/tools/ant/taskdefs/cvslib/RCSFile.java
+++ b/src/main/org/apache/tools/ant/taskdefs/cvslib/RCSFile.java
@@ -26,12 +26,10 @@
     private String revision;
     private String previousRevision;
 
-
     RCSFile(final String name, final String rev) {
         this(name, rev, null);
     }
 
-
     RCSFile(final String name,
                   final String revision,
                   final String previousRevision) {
@@ -66,4 +64,3 @@
         return previousRevision;
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingOutputStream.java b/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingOutputStream.java
index f2b61cf..6e3a28f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingOutputStream.java
+++ b/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingOutputStream.java
@@ -39,8 +39,8 @@
      *
      * @param line the line to log.
      */
+    @Override
     protected void processLine(final String line) {
         parser.stdout(line);
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingStreamHandler.java b/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingStreamHandler.java
index 713de0c..b43e645 100644
--- a/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingStreamHandler.java
+++ b/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingStreamHandler.java
@@ -18,10 +18,9 @@
 package org.apache.tools.ant.taskdefs.cvslib;
 
 import java.io.ByteArrayOutputStream;
-import java.io.IOException;
 
-import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.taskdefs.PumpStreamHandler;
+import org.apache.tools.ant.util.FileUtils;
 
 /**
  * A dummy stream handler that just passes stuff to the parser.
@@ -34,7 +33,6 @@
             new ByteArrayOutputStream());
     }
 
-
     String getErrors() {
         try {
             final ByteArrayOutputStream error
@@ -46,16 +44,10 @@
         }
     }
 
-
+    @Override
     public void stop() {
         super.stop();
-        try {
-            getErr().close();
-            getOut().close();
-        } catch (final IOException e) {
-            // plain impossible
-            throw new BuildException(e);
-        }
+        FileUtils.close(getErr());
+        FileUtils.close(getOut());
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/src/main/org/apache/tools/ant/taskdefs/defaults.properties
index 9cf1499..8db1ebc 100644
--- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties
+++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties
@@ -19,7 +19,6 @@
 antstructure=org.apache.tools.ant.taskdefs.AntStructure
 antversion=org.apache.tools.ant.taskdefs.condition.AntVersion
 apply=org.apache.tools.ant.taskdefs.Transform
-apt=org.apache.tools.ant.taskdefs.Apt
 attributenamespacedef=org.apache.tools.ant.taskdefs.AttributeNamespaceDef
 augment=org.apache.tools.ant.taskdefs.AugmentReference
 available=org.apache.tools.ant.taskdefs.Available
@@ -92,6 +91,7 @@
 resourcecount=org.apache.tools.ant.taskdefs.ResourceCount
 retry=org.apache.tools.ant.taskdefs.Retry
 rmic=org.apache.tools.ant.taskdefs.Rmic
+setpermissions=org.apache.tools.ant.taskdefs.SetPermissions
 sequential=org.apache.tools.ant.taskdefs.Sequential
 signjar=org.apache.tools.ant.taskdefs.SignJar
 sleep=org.apache.tools.ant.taskdefs.Sleep
@@ -108,6 +108,7 @@
 unjar=org.apache.tools.ant.taskdefs.Expand
 untar=org.apache.tools.ant.taskdefs.Untar
 unwar=org.apache.tools.ant.taskdefs.Expand
+unxz=org.apache.tools.ant.taskdefs.optional.xz.Unxz
 unzip=org.apache.tools.ant.taskdefs.Expand
 uptodate=org.apache.tools.ant.taskdefs.UpToDate
 waitfor=org.apache.tools.ant.taskdefs.WaitFor
@@ -115,6 +116,7 @@
 whichresource=org.apache.tools.ant.taskdefs.WhichResource
 xmlproperty=org.apache.tools.ant.taskdefs.XmlProperty
 xslt=org.apache.tools.ant.taskdefs.XSLTProcess
+xz=org.apache.tools.ant.taskdefs.optional.xz.Xz
 zip=org.apache.tools.ant.taskdefs.Zip
 
 # optional tasks
diff --git a/src/main/org/apache/tools/ant/taskdefs/email/EmailAddress.java b/src/main/org/apache/tools/ant/taskdefs/email/EmailAddress.java
index 25e3555..f8e2133 100644
--- a/src/main/org/apache/tools/ant/taskdefs/email/EmailAddress.java
+++ b/src/main/org/apache/tools/ant/taskdefs/email/EmailAddress.java
@@ -119,7 +119,7 @@
     private String trim(String t, boolean trimAngleBrackets) {
         int start = 0;
         int end = t.length();
-        boolean trim = false;
+        boolean trim;
         do {
             trim = false;
             if (t.charAt(end - 1) == ')'
@@ -140,7 +140,6 @@
         return t.substring(start, end);
     }
 
-
     /**
      * Sets the personal / display name of the address.
      *
@@ -150,7 +149,6 @@
         this.name = name;
     }
 
-
     /**
      * Sets the email address.
      *
@@ -160,21 +158,19 @@
         this.address = address;
     }
 
-
     /**
      * Constructs a string "name &lt;address&gt;" or "address"
      *
      * @return a string representation of the address
      */
+    @Override
     public String toString() {
         if (name == null) {
             return address;
-        } else {
-            return name + " <" + address + ">";
         }
+        return name + " <" + address + ">";
     }
 
-
     /**
      * Returns the address
      *
@@ -184,7 +180,6 @@
         return address;
     }
 
-
     /**
      * Returns the display name
      *
@@ -194,4 +189,3 @@
         return name;
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java b/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java
index 9715c12..ae3d525 100644
--- a/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java
@@ -20,7 +20,6 @@
 import java.io.File;
 import java.util.StringTokenizer;
 import java.util.Vector;
-
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
@@ -60,6 +59,7 @@
          *
          * @return a list of valid entries
          */
+        @Override
         public String[] getValues() {
             return new String[] {AUTO, MIME, UU, PLAIN};
         }
@@ -82,16 +82,16 @@
     /** sender  */
     private EmailAddress from = null;
     /** replyto */
-    private Vector replyToList = new Vector();
+    private Vector<EmailAddress> replyToList = new Vector<>();
     /** TO recipients  */
-    private Vector toList = new Vector();
+    private Vector<EmailAddress> toList = new Vector<>();
     /** CC (Carbon Copy) recipients  */
-    private Vector ccList = new Vector();
+    private Vector<EmailAddress> ccList = new Vector<>();
     /** BCC (Blind Carbon Copy) recipients  */
-    private Vector bccList = new Vector();
+    private Vector<EmailAddress> bccList = new Vector<>();
 
     /** generic headers */
-    private Vector headers = new Vector();
+    private Vector<Header> headers = new Vector<>();
 
     /** file list  */
     private Path attachments = null;
@@ -193,8 +193,8 @@
      */
     public void setMessage(String message) {
         if (this.message != null) {
-            throw new BuildException("Only one message can be sent in an "
-                 + "email");
+            throw new BuildException(
+                "Only one message can be sent in an email");
         }
         this.message = new Message(message);
         this.message.setProject(getProject());
@@ -207,8 +207,8 @@
      */
     public void setMessageFile(File file) {
         if (this.message != null) {
-            throw new BuildException("Only one message can be sent in an "
-                 + "email");
+            throw new BuildException(
+                "Only one message can be sent in an email");
         }
         this.message = new Message(file);
         this.message.setProject(getProject());
@@ -288,7 +288,7 @@
      * @param address An email address.
      */
     public void addTo(EmailAddress address) {
-        toList.addElement(address);
+        toList.add(address);
     }
 
     /**
@@ -300,7 +300,7 @@
         StringTokenizer tokens = new StringTokenizer(list, ",");
 
         while (tokens.hasMoreTokens()) {
-            toList.addElement(new EmailAddress(tokens.nextToken()));
+            toList.add(new EmailAddress(tokens.nextToken()));
         }
     }
 
@@ -310,7 +310,7 @@
      * @param address The email address.
      */
     public void addCc(EmailAddress address) {
-        ccList.addElement(address);
+        ccList.add(address);
     }
 
     /**
@@ -322,7 +322,7 @@
         StringTokenizer tokens = new StringTokenizer(list, ",");
 
         while (tokens.hasMoreTokens()) {
-            ccList.addElement(new EmailAddress(tokens.nextToken()));
+            ccList.add(new EmailAddress(tokens.nextToken()));
         }
     }
 
@@ -332,7 +332,7 @@
      * @param address The email address.
      */
     public void addBcc(EmailAddress address) {
-        bccList.addElement(address);
+        bccList.add(address);
     }
 
     /**
@@ -344,7 +344,7 @@
         StringTokenizer tokens = new StringTokenizer(list, ",");
 
         while (tokens.hasMoreTokens()) {
-            bccList.addElement(new EmailAddress(tokens.nextToken()));
+            bccList.add(new EmailAddress(tokens.nextToken()));
         }
     }
 
@@ -439,6 +439,7 @@
     /**
      * Send an email.
      */
+    @Override
     public void execute() {
         Message savedMessage = message;
 
@@ -448,15 +449,15 @@
             // prepare for the auto select mechanism
             boolean autoFound = false;
             // try MIME format
-            if (encoding.equals(MIME)
-                 || (encoding.equals(AUTO) && !autoFound)) {
+            if (MIME.equals(encoding)
+                 || (AUTO.equals(encoding) && !autoFound)) {
                 try {
                     //check to make sure that activation.jar
                     //and mail.jar are available - see bug 31969
                     Class.forName("javax.activation.DataHandler");
                     Class.forName("javax.mail.internet.MimeMessage");
 
-                    mailer = (Mailer) ClasspathUtils.newInstance(
+                    mailer = ClasspathUtils.newInstance(
                             "org.apache.tools.ant.taskdefs.email.MimeMailer",
                             EmailTask.class.getClassLoader(), Mailer.class);
                     autoFound = true;
@@ -468,20 +469,20 @@
             }
             // SMTP auth only allowed with MIME mail
             if (!autoFound && ((user != null) || (password != null))
-                && (encoding.equals(UU) || encoding.equals(PLAIN))) {
+                && (UU.equals(encoding) || PLAIN.equals(encoding))) {
                 throw new BuildException("SMTP auth only possible with MIME mail");
             }
             // SSL only allowed with MIME mail
             if (!autoFound  && (ssl || starttls)
-                && (encoding.equals(UU) || encoding.equals(PLAIN))) {
-                throw new BuildException("SSL and STARTTLS only possible with"
-                                         + " MIME mail");
+                && (UU.equals(encoding) || PLAIN.equals(encoding))) {
+                throw new BuildException(
+                    "SSL and STARTTLS only possible with MIME mail");
             }
             // try UU format
-            if (encoding.equals(UU)
-                 || (encoding.equals(AUTO) && !autoFound)) {
+            if (UU.equals(encoding)
+                 || (AUTO.equals(encoding) && !autoFound)) {
                 try {
-                    mailer = (Mailer) ClasspathUtils.newInstance(
+                    mailer = ClasspathUtils.newInstance(
                             "org.apache.tools.ant.taskdefs.email.UUMailer",
                             EmailTask.class.getClassLoader(), Mailer.class);
                     autoFound = true;
@@ -491,16 +492,16 @@
                 }
             }
             // try plain format
-            if (encoding.equals(PLAIN)
-                 || (encoding.equals(AUTO) && !autoFound)) {
+            if (PLAIN.equals(encoding)
+                 || (AUTO.equals(encoding) && !autoFound)) {
                 mailer = new PlainMailer();
                 autoFound = true;
                 log("Using plain mail", Project.MSG_VERBOSE);
             }
             // a valid mailer must be present by now
             if (mailer == null) {
-                throw new BuildException("Failed to initialise encoding: "
-                     + encoding);
+                throw new BuildException("Failed to initialise encoding: %s",
+                    encoding);
             }
             // a valid message is required
             if (message == null) {
@@ -513,33 +514,33 @@
             }
             // at least one address to send to/cc/bcc is required
             if (toList.isEmpty() && ccList.isEmpty() && bccList.isEmpty()) {
-                throw new BuildException("At least one of to, cc or bcc must "
-                     + "be supplied");
+                throw new BuildException(
+                    "At least one of to, cc or bcc must be supplied");
             }
             // set the mimetype if not done already (and required)
             if (messageMimeType != null) {
                 if (message.isMimeTypeSpecified()) {
-                    throw new BuildException("The mime type can only be "
-                         + "specified in one location");
+                    throw new BuildException(
+                        "The mime type can only be specified in one location");
                 }
                 message.setMimeType(messageMimeType);
             }
             // set the character set if not done already (and required)
             if (charset != null) {
                 if (message.getCharset() != null) {
-                    throw new BuildException("The charset can only be "
-                         + "specified in one location");
+                    throw new BuildException(
+                        "The charset can only be specified in one location");
                 }
                 message.setCharset(charset);
             }
             message.setInputEncoding(messageFileInputEncoding);
 
             // identify which files should be attached
-            Vector<File> files = new Vector<File>();
+            Vector<File> files = new Vector<>();
+
             if (attachments != null) {
                 for (Resource r : attachments) {
-                    files.addElement(r.as(FileProvider.class)
-                                     .getFile());
+                    files.add(r.as(FileProvider.class).getFile());
                 }
             }
             // let the user know what's going to happen
@@ -636,4 +637,3 @@
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/email/Header.java b/src/main/org/apache/tools/ant/taskdefs/email/Header.java
index 6bcfb66..aaee693 100644
--- a/src/main/org/apache/tools/ant/taskdefs/email/Header.java
+++ b/src/main/org/apache/tools/ant/taskdefs/email/Header.java
@@ -19,7 +19,9 @@
 package org.apache.tools.ant.taskdefs.email;
 
 /**
- * Class representing a generic e-mail header.
+ * Class representing a generic key-value header.
+ * TODO: This should be moved out of the email package
+ *
  * @since Ant 1.7
  */
 public class Header {
diff --git a/src/main/org/apache/tools/ant/taskdefs/email/Mailer.java b/src/main/org/apache/tools/ant/taskdefs/email/Mailer.java
index 352ae0b..010b87e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/email/Mailer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/email/Mailer.java
@@ -279,4 +279,3 @@
         return DateUtils.getDateForHeader();
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/email/Message.java b/src/main/org/apache/tools/ant/taskdefs/email/Message.java
index 8869ef1..0b763e4 100644
--- a/src/main/org/apache/tools/ant/taskdefs/email/Message.java
+++ b/src/main/org/apache/tools/ant/taskdefs/email/Message.java
@@ -20,13 +20,14 @@
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.PrintStream;
 import java.io.Reader;
+import java.nio.file.Files;
 
 import org.apache.tools.ant.ProjectComponent;
 
@@ -47,7 +48,6 @@
     public Message() {
     }
 
-
     /**
      * Creates a new message based on the given string
      *
@@ -57,7 +57,6 @@
         addText(text);
     }
 
-
     /**
      * Creates a new message using the contents of the given file.
      *
@@ -67,7 +66,6 @@
         messageSource = file;
     }
 
-
     /**
      * Adds a textual part of the message
      *
@@ -77,7 +75,6 @@
         buffer.append(text);
     }
 
-
     /**
      * Sets the source file of the message
      *
@@ -87,7 +84,6 @@
         this.messageSource = src;
     }
 
-
     /**
      * Sets the content type for the message
      *
@@ -98,7 +94,6 @@
         specified = true;
     }
 
-
     /**
      * Returns the content type
      *
@@ -108,7 +103,6 @@
         return mimeType;
     }
 
-
     /**
      * Prints the message onto an output stream
      *
@@ -126,17 +120,13 @@
                 : new BufferedWriter(new OutputStreamWriter(ps));
             if (messageSource != null) {
                 // Read message from a file
-                Reader freader = getReader(messageSource);
-
-                try {
-                    BufferedReader in = new BufferedReader(freader);
-                    String line = null;
+                try (Reader freader = getReader(messageSource);
+                     BufferedReader in = new BufferedReader(freader)) {
+                    String line;
                     while ((line = in.readLine()) != null) {
                         out.write(getProject().replaceProperties(line));
                         out.newLine();
                     }
-                } finally {
-                    freader.close();
                 }
             } else {
                 out.write(getProject().replaceProperties(buffer.substring(0)));
@@ -148,7 +138,6 @@
         }
     }
 
-
     /**
      * Returns true if the mimeType has been set.
      *
@@ -167,6 +156,7 @@
     public void setCharset(String charset) {
         this.charset = charset;
     }
+
     /**
      * Returns the charset of mail message.
      *
@@ -189,7 +179,7 @@
 
     private Reader getReader(File f) throws IOException {
         if (inputEncoding != null) {
-            FileInputStream fis = new FileInputStream(f);
+            InputStream fis = Files.newInputStream(f.toPath());
             try {
                 return new InputStreamReader(fis, inputEncoding);
             } catch (IOException ex) {
@@ -200,4 +190,3 @@
         return new FileReader(f);
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java b/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java
index 186d71e..b8f0516 100644
--- a/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java
@@ -27,8 +27,6 @@
 import java.io.UnsupportedEncodingException;
 import java.security.Provider;
 import java.security.Security;
-import java.util.Enumeration;
-import java.util.Iterator;
 import java.util.Locale;
 import java.util.Properties;
 import java.util.StringTokenizer;
@@ -81,6 +79,7 @@
         private String charset = null;
         private ByteArrayOutputStream out;
 
+        @Override
         public InputStream getInputStream() throws IOException {
             if (data == null && out == null) {
                 throw new IOException("No data");
@@ -93,6 +92,7 @@
             return new ByteArrayInputStream(data.getBytes(charset));
         }
 
+        @Override
         public OutputStream getOutputStream() throws IOException {
             out = (out == null) ? new ByteArrayOutputStream() : out;
             return out;
@@ -102,16 +102,18 @@
             this.type = type.toLowerCase(Locale.ENGLISH);
         }
 
+        @Override
         public String getContentType() {
             if (type != null && type.indexOf("charset") > 0
                 && type.startsWith("text/")) {
                 return type;
             }
             // Must be like "text/plain; charset=windows-1251"
-            return new StringBuffer(type != null ? type : "text/plain").append(
+            return new StringBuilder(type != null ? type : "text/plain").append(
                 "; charset=").append(charset).toString();
         }
 
+        @Override
         public String getName() {
             return "StringDataSource";
         }
@@ -130,6 +132,7 @@
      *
      * @throws BuildException if the email can't be sent.
      */
+    @Override
     public void send() {
         try {
             final Properties props = new Properties();
@@ -144,13 +147,13 @@
             Authenticator auth = null;
             if (SSL) {
                 try {
-                    final Provider p = (Provider) Class.forName(
-                        "com.sun.net.ssl.internal.ssl.Provider").newInstance();
+                    final Provider p =
+                        Class.forName("com.sun.net.ssl.internal.ssl.Provider")
+                            .asSubclass(Provider.class).newInstance();
                     Security.addProvider(p);
                 } catch (final Exception e) {
-                    throw new BuildException("could not instantiate ssl "
-                        + "security provider, check that you have JSSE in "
-                        + "your classpath");
+                    throw new BuildException(
+                        "could not instantiate ssl security provider, check that you have JSSE in your classpath");
                 }
                 // SMTP provider
                 props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
@@ -217,8 +220,7 @@
             msg.addHeader("Date", getDate());
 
             if (headers != null) {
-                for (final Iterator iter = headers.iterator(); iter.hasNext();) {
-                    final Header h = (Header) iter.next();
+                for (Header h : headers) {
                     msg.addHeader(h.getName(), h.getValue());
                 }
             }
@@ -230,18 +232,12 @@
             textbody.setDataHandler(new DataHandler(sds));
             attachments.addBodyPart(textbody);
 
-            final Enumeration e = files.elements();
-
-            while (e.hasMoreElements()) {
-                final File file = (File) e.nextElement();
-
-                MimeBodyPart body;
-
-                body = new MimeBodyPart();
+            for (File file : files) {
+                MimeBodyPart body = new MimeBodyPart();
                 if (!file.exists() || !file.canRead()) {
-                    throw new BuildException("File \"" + file.getAbsolutePath()
-                         + "\" does not exist or is not "
-                         + "readable.");
+                    throw new BuildException(
+                        "File \"%s\" does not exist or is not readable.",
+                        file.getAbsolutePath());
                 }
                 final FileDataSource fileData = new FileDataSource(file);
                 final DataHandler fileDataHandler = new DataHandler(fileData);
@@ -259,41 +255,40 @@
             } catch (final SendFailedException sfe) {
                 if (!shouldIgnoreInvalidRecipients()) {
                     throw new BuildException(GENERIC_ERROR, sfe);
-                } else if (sfe.getValidSentAddresses() == null
+                }
+                if (sfe.getValidSentAddresses() == null
                            || sfe.getValidSentAddresses().length == 0) {
                     throw new BuildException("Couldn't reach any recipient",
                                              sfe);
-                } else {
-                    Address[] invalid = sfe.getInvalidAddresses();
-                    if (invalid == null) {
-                        invalid = new Address[0];
-                    }
-                    for (int i = 0; i < invalid.length; i++) {
-                        didntReach(invalid[i], "invalid", sfe);
-                    }
-                    Address[] validUnsent = sfe.getValidUnsentAddresses();
-                    if (validUnsent == null) {
-                        validUnsent = new Address[0];
-                    }
-                    for (int i = 0; i < validUnsent.length; i++) {
-                        didntReach(validUnsent[i], "valid", sfe);
-                    }
+                }
+                Address[] invalid = sfe.getInvalidAddresses();
+                if (invalid == null) {
+                    invalid = new Address[0];
+                }
+                for (int i = 0; i < invalid.length; i++) {
+                    didntReach(invalid[i], "invalid", sfe);
+                }
+                Address[] validUnsent = sfe.getValidUnsentAddresses();
+                if (validUnsent == null) {
+                    validUnsent = new Address[0];
+                }
+                for (int i = 0; i < validUnsent.length; i++) {
+                    didntReach(validUnsent[i], "valid", sfe);
                 }
             }
-        } catch (final MessagingException e) {
-            throw new BuildException(GENERIC_ERROR, e);
-        } catch (final IOException e) {
+        } catch (MessagingException | IOException e) {
             throw new BuildException(GENERIC_ERROR, e);
         }
     }
 
-    private static InternetAddress[] internetAddresses(final Vector list)
+    private static InternetAddress[] internetAddresses(final Vector<EmailAddress> list)
         throws AddressException, UnsupportedEncodingException {
+
         final int size = list.size();
         final InternetAddress[] addrs = new InternetAddress[size];
 
         for (int i = 0; i < size; ++i) {
-            final EmailAddress addr = (EmailAddress) list.elementAt(i);
+            final EmailAddress addr = list.get(i);
 
             final String name = addr.getName();
             addrs[i] = (name == null)
@@ -309,7 +304,7 @@
         }
         final int pos = type.indexOf("charset");
         if (pos < 0) {
-          return null;
+            return null;
         }
         // Assuming mime type in form "text/XXXX; charset=XXXXXX"
         final StringTokenizer token = new StringTokenizer(type.substring(pos), "=; ");
@@ -331,10 +326,13 @@
     static class SimpleAuthenticator extends Authenticator {
         private String user = null;
         private String password = null;
+
         public SimpleAuthenticator(final String user, final String password) {
             this.user = user;
             this.password = password;
         }
+
+        @Override
         public PasswordAuthentication getPasswordAuthentication() {
             return new PasswordAuthentication(user, password);
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/email/PlainMailer.java b/src/main/org/apache/tools/ant/taskdefs/email/PlainMailer.java
index 20524ac..1d0c378 100644
--- a/src/main/org/apache/tools/ant/taskdefs/email/PlainMailer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/email/PlainMailer.java
@@ -19,11 +19,10 @@
 
 import java.io.BufferedInputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.PrintStream;
-import java.util.Enumeration;
-
+import java.nio.file.Files;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.mail.MailMessage;
@@ -39,49 +38,44 @@
      *
      * @see org.apache.tools.mail.MailMessage
      */
+    @Override
     public void send() {
         try {
             MailMessage mailMessage = new MailMessage(host, port);
 
             mailMessage.from(from.toString());
 
-            Enumeration e;
             boolean atLeastOneRcptReached = false;
 
-            e = replyToList.elements();
-            while (e.hasMoreElements()) {
-                mailMessage.replyto(e.nextElement().toString());
-            }
-            e = toList.elements();
-            while (e.hasMoreElements()) {
-                String to = e.nextElement().toString();
+            replyToList.stream().map(Object::toString).forEach(mailMessage::replyto);
+
+            for (EmailAddress to : toList) {
                 try {
-                    mailMessage.to(to);
+                    mailMessage.to(to.toString());
                     atLeastOneRcptReached = true;
                 } catch (IOException ex) {
                     badRecipient(to, ex);
                 }
             }
-            e = ccList.elements();
-            while (e.hasMoreElements()) {
-                String to = e.nextElement().toString();
+
+            for (EmailAddress cc : ccList) {
                 try {
-                    mailMessage.cc(to);
+                    mailMessage.cc(cc.toString());
                     atLeastOneRcptReached = true;
                 } catch (IOException ex) {
-                    badRecipient(to, ex);
+                    badRecipient(cc, ex);
                 }
             }
-            e = bccList.elements();
-            while (e.hasMoreElements()) {
-                String to = e.nextElement().toString();
+
+            for (EmailAddress bcc : bccList) {
                 try {
-                    mailMessage.bcc(to);
+                    mailMessage.bcc(bcc.toString());
                     atLeastOneRcptReached = true;
                 } catch (IOException ex) {
-                    badRecipient(to, ex);
+                    badRecipient(bcc, ex);
                 }
             }
+
             if (!atLeastOneRcptReached) {
                 throw new BuildException("Couldn't reach any recipient");
             }
@@ -96,18 +90,17 @@
                 mailMessage.setHeader("Content-Type", message.getMimeType());
             }
             if (headers != null) {
-                e = headers.elements();
-                while (e.hasMoreElements()) {
-                    Header h = (Header) e.nextElement();
+                for (Header h : headers) {
                     mailMessage.setHeader(h.getName(), h.getValue());
                 }
             }
             PrintStream out = mailMessage.getPrintStream();
             message.print(out);
 
-            e = files.elements();
-            while (e.hasMoreElements()) {
-                attach((File) e.nextElement(), out);
+            if (files != null) {
+                for (File f : files) {
+                    attach(f, out);
+                }
             }
             mailMessage.sendAndClose();
         } catch (IOException ioe) {
@@ -126,9 +119,9 @@
     protected void attach(File file, PrintStream out)
          throws IOException {
         if (!file.exists() || !file.canRead()) {
-            throw new BuildException("File \"" + file.getName()
-                 + "\" does not exist or is not "
-                 + "readable.");
+            throw new BuildException(
+                "File \"%s\" does not exist or is not readable.",
+                file.getAbsolutePath());
         }
 
         if (includeFileNames) {
@@ -144,23 +137,20 @@
             out.println();
         }
 
-        int length;
         final int maxBuf = 1024;
         byte[] buf = new byte[maxBuf];
-        FileInputStream finstr = new FileInputStream(file);
 
-        try {
-            BufferedInputStream in = new BufferedInputStream(finstr, buf.length);
+        try (InputStream finstr = Files.newInputStream(file.toPath());
+             BufferedInputStream in = new BufferedInputStream(finstr, buf.length)) {
 
+            int length;
             while ((length = in.read(buf)) != -1) {
                 out.write(buf, 0, length);
             }
-        } finally {
-            finstr.close();
         }
     }
 
-    private void badRecipient(String rcpt, IOException reason) {
+    private void badRecipient(EmailAddress rcpt, IOException reason) {
         String msg = "Failed to send mail to " + rcpt;
         if (shouldIgnoreInvalidRecipients()) {
             msg += " because of :" + reason.getMessage();
diff --git a/src/main/org/apache/tools/ant/taskdefs/email/UUMailer.java b/src/main/org/apache/tools/ant/taskdefs/email/UUMailer.java
index d6542be..9759601 100644
--- a/src/main/org/apache/tools/ant/taskdefs/email/UUMailer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/email/UUMailer.java
@@ -19,9 +19,10 @@
 
 import java.io.BufferedInputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.PrintStream;
+import java.nio.file.Files;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.util.UUEncoder;
@@ -32,24 +33,18 @@
  * @since Ant 1.5
  */
 class UUMailer extends PlainMailer {
+    @Override
     protected void attach(File file, PrintStream out)
          throws IOException {
         if (!file.exists() || !file.canRead()) {
-            throw new BuildException("File \"" + file.getName()
-                 + "\" does not exist or is not "
-                 + "readable.");
+            throw new BuildException(
+                "File \"%s" + "\" does not exist or is not " + "readable.",
+                file.getAbsolutePath());
         }
 
-        FileInputStream finstr = new FileInputStream(file);
-
-        try {
-            BufferedInputStream in = new BufferedInputStream(finstr);
-            UUEncoder encoder = new UUEncoder(file.getName());
-
-            encoder.encode(in, out);
-
-        } finally {
-            finstr.close();
+        try (InputStream in =
+            new BufferedInputStream(Files.newInputStream(file.toPath()))) {
+            new UUEncoder(file.getName()).encode(in, out);
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncher.java b/src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncher.java
index cc9fb88..4af7936 100644
--- a/src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncher.java
+++ b/src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncher.java
@@ -22,6 +22,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Optional;
 
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.taskdefs.condition.Os;
@@ -41,7 +42,7 @@
     private static CommandLauncher shellLauncher = null;
 
     static {
-        if(!Os.isFamily("os/2")) {
+        if (!Os.isFamily("os/2")) {
             vmLauncher = new Java13CommandLauncher();
         }
 
@@ -94,7 +95,7 @@
      */
     public Process exec(Project project, String[] cmd, String[] env)
         throws IOException {
-        if(project != null) {
+        if (project != null) {
             project.log("Execute:CommandLauncher: "
                 + Commandline.describeCommand(cmd), Project.MSG_DEBUG);
         }
@@ -124,8 +125,8 @@
         if (workingDir == null) {
             return exec(project, cmd, env);
         }
-        throw new IOException("Cannot execute a process in different "
-            + "directory under this JVM");
+        throw new IOException(
+            "Cannot execute a process in different directory under this JVM");
     }
 
     /**
@@ -163,37 +164,24 @@
 
     private static CommandLauncher extractLauncher(String referenceName,
                                                    Project project) {
-        CommandLauncher launcher = null;
-        if (project != null) {
-            launcher = (CommandLauncher) project.getReference(referenceName);
-        }
-
-        if (launcher == null) {
-            launcher = getSystemLauncher(referenceName);
-        }
-        return launcher;
+        return Optional.ofNullable(project)
+            .map(p -> p.<CommandLauncher> getReference(referenceName))
+            .orElseGet(() -> getSystemLauncher(referenceName));
     }
 
     private static CommandLauncher getSystemLauncher(String launcherRefId) {
-        CommandLauncher launcher = null;
         String launcherClass = System.getProperty(launcherRefId);
         if (launcherClass != null) {
             try {
-                launcher = (CommandLauncher) Class.forName(launcherClass)
-                    .newInstance();
-            } catch(InstantiationException e) {
+                return Class.forName(launcherClass)
+                    .asSubclass(CommandLauncher.class).newInstance();
+            } catch (InstantiationException | IllegalAccessException
+                    | ClassNotFoundException e) {
                 System.err.println("Could not instantiate launcher class "
-                                   + launcherClass + ": " + e.getMessage());
-            } catch(IllegalAccessException e) {
-                System.err.println("Could not instantiate launcher class "
-                                   + launcherClass + ": " + e.getMessage());
-            } catch(ClassNotFoundException e) {
-                System.err.println("Could not instantiate launcher class "
-                                   + launcherClass + ": " + e.getMessage());
+                    + launcherClass + ": " + e.getMessage());
             }
         }
-
-        return launcher;
+        return null;
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/taskdefs/launcher/PerlScriptCommandLauncher.java b/src/main/org/apache/tools/ant/taskdefs/launcher/PerlScriptCommandLauncher.java
index d5b06f7..77d1cc8 100644
--- a/src/main/org/apache/tools/ant/taskdefs/launcher/PerlScriptCommandLauncher.java
+++ b/src/main/org/apache/tools/ant/taskdefs/launcher/PerlScriptCommandLauncher.java
@@ -58,15 +58,14 @@
             if (workingDir == null) {
                 return exec(project, cmd, env);
             }
-            throw new IOException("Cannot locate antRun script: "
-                                  + "No project provided");
+            throw new IOException(
+                "Cannot locate antRun script: No project provided");
         }
         // Locate the auxiliary script
         String antHome = project.getProperty(MagicNames.ANT_HOME);
         if (antHome == null) {
-            throw new IOException("Cannot locate antRun script: "
-                                  + "Property '" + MagicNames.ANT_HOME
-                                  + "' not found");
+            throw new IOException("Cannot locate antRun script: Property '"
+                + MagicNames.ANT_HOME + "' not found");
         }
         String antRun = FILE_UTILS.resolveFile(project.getBaseDir(),
                                                antHome + File.separator
diff --git a/src/main/org/apache/tools/ant/taskdefs/launcher/ScriptCommandLauncher.java b/src/main/org/apache/tools/ant/taskdefs/launcher/ScriptCommandLauncher.java
index 936f948..bee01d6 100644
--- a/src/main/org/apache/tools/ant/taskdefs/launcher/ScriptCommandLauncher.java
+++ b/src/main/org/apache/tools/ant/taskdefs/launcher/ScriptCommandLauncher.java
@@ -58,15 +58,14 @@
             if (workingDir == null) {
                 return exec(project, cmd, env);
             }
-            throw new IOException("Cannot locate antRun script: "
-                                  + "No project provided");
+            throw new IOException(
+                "Cannot locate antRun script: No project provided");
         }
         // Locate the auxiliary script
         String antHome = project.getProperty(MagicNames.ANT_HOME);
         if (antHome == null) {
-            throw new IOException("Cannot locate antRun script: "
-                                  + "Property '" + MagicNames.ANT_HOME
-                                  + "' not found");
+            throw new IOException("Cannot locate antRun script: Property '"
+                + MagicNames.ANT_HOME + "' not found");
         }
         String antRun = FILE_UTILS.resolveFile(project.getBaseDir(),
                                                antHome + File.separator
diff --git a/src/main/org/apache/tools/ant/taskdefs/launcher/VmsCommandLauncher.java b/src/main/org/apache/tools/ant/taskdefs/launcher/VmsCommandLauncher.java
index b7c914c..19034c9 100644
--- a/src/main/org/apache/tools/ant/taskdefs/launcher/VmsCommandLauncher.java
+++ b/src/main/org/apache/tools/ant/taskdefs/launcher/VmsCommandLauncher.java
@@ -32,10 +32,6 @@
  */
 public class VmsCommandLauncher extends Java13CommandLauncher {
 
-    public VmsCommandLauncher() {
-        super();
-    }
-
     /**
      * Launches the given command in a new process.
      *
@@ -53,7 +49,8 @@
     public Process exec(Project project, String[] cmd, String[] env)
         throws IOException {
         File cmdFile = createCommandFile(cmd, env);
-        Process p = super.exec(project, new String[] {cmdFile.getPath()}, env);
+        Process p =
+            super.exec(project, new String[] {cmdFile.getPath()}, env);
         deleteAfter(cmdFile, p);
         return p;
     }
@@ -80,7 +77,8 @@
     public Process exec(Project project, String[] cmd, String[] env,
                         File workingDir) throws IOException {
         File cmdFile = createCommandFile(cmd, env);
-        Process p = super.exec(project, new String[] {cmdFile.getPath()}, env, workingDir);
+        Process p = super.exec(project, new String[] {cmdFile.getPath()}, env,
+            workingDir);
         deleteAfter(cmdFile, p);
         return p;
     }
@@ -96,9 +94,7 @@
     private File createCommandFile(String[] cmd, String[] env)
         throws IOException {
         File script = FILE_UTILS.createTempFile("ANT", ".COM", null, true, true);
-        BufferedWriter out = null;
-        try {
-            out = new BufferedWriter(new FileWriter(script));
+        try (BufferedWriter out = new BufferedWriter(new FileWriter(script))) {
 
             // add the environment as logicals to the DCL script
             if (env != null) {
@@ -121,8 +117,6 @@
                 out.newLine();
                 out.write(cmd[i]);
             }
-        } finally {
-            FileUtils.close(out);
         }
         return script;
     }
@@ -140,4 +134,4 @@
             }
         }.start();
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ANTLR.java b/src/main/org/apache/tools/ant/taskdefs/optional/ANTLR.java
index ba8afd2..fb7071c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ANTLR.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ANTLR.java
@@ -118,8 +118,9 @@
      * @param superGrammar the super grammar filename
      * @deprecated  since ant 1.6
      */
+    @Deprecated
     public void setGlib(String superGrammar) {
-        String sg = null;
+        String sg;
         if (Os.isFamily("dos")) {
             sg = superGrammar.replace('\\', '/');
         } else {
@@ -127,6 +128,7 @@
         }
         setGlib(FILE_UTILS.resolveFile(getProject().getBaseDir(), sg));
     }
+
     /**
      * Sets an optional super grammar file
      * @param superGrammar the super grammar file
@@ -135,6 +137,7 @@
     public void setGlib(File superGrammar) {
         this.superGrammar = superGrammar;
     }
+
     /**
      * Sets a flag to enable ParseView debugging
      * @param enable a <code>boolean</code> value
@@ -200,7 +203,6 @@
      * @param s a <code>boolean</code> value
      */
     public void setFork(boolean s) {
-        //this.fork = s;
     }
 
     /**
@@ -235,6 +237,7 @@
      * specify it directly.
      * @throws BuildException on error
      */
+    @Override
     public void init() throws BuildException {
         addClasspathEntry("/antlr/ANTLRGrammarParseBehavior.class");
     }
@@ -278,6 +281,7 @@
      * Execute the task.
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         validateAttributes();
 
@@ -302,12 +306,11 @@
             int err = run(commandline.getCommandline());
             if (err != 0) {
                 throw new BuildException("ANTLR returned: " + err, getLocation());
-            } else {
-                String output = bos.toString();
-                if (output.indexOf("error:") > -1) {
-                    throw new BuildException("ANTLR signaled an error: "
-                                             + output, getLocation());
-                }
+            }
+            String output = bos.toString();
+            if (output.indexOf("error:") > -1) {
+                throw new BuildException("ANTLR signaled an error: "
+                                         + output, getLocation());
             }
         } else {
             log("Skipped grammar file. Generated file " + generatedFile
@@ -357,7 +360,6 @@
         if (targetFile == null || !targetFile.isFile()) {
             throw new BuildException("Invalid target: " + targetFile);
         }
-
         // if no output directory is specified, used the target's directory
         if (outputDirectory == null) {
             setOutputdirectory(new File(targetFile.getParent()));
@@ -369,8 +371,8 @@
 
     private File getGeneratedFile() throws BuildException {
         String generatedFileName = null;
-        try {
-            BufferedReader in = new BufferedReader(new FileReader(targetFile));
+        try (BufferedReader in =
+            new BufferedReader(new FileReader(targetFile))) {
             String line;
             while ((line = in.readLine()) != null) {
                 int extendsIndex = line.indexOf(" extends ");
@@ -380,7 +382,6 @@
                     break;
                 }
             }
-            in.close();
         } catch (Exception e) {
             throw new BuildException("Unable to determine generated class", e);
         }
@@ -422,17 +423,12 @@
      * @since Ant 1.6
      */
     protected boolean is272() {
-        AntClassLoader l = null;
-        try {
-            l = getProject().createClassLoader(commandline.getClasspath());
+        try (AntClassLoader l =
+             getProject().createClassLoader(commandline.getClasspath())) {
             l.loadClass("antlr.Version");
             return true;
         } catch (ClassNotFoundException e) {
             return false;
-        } finally {
-            if (l != null) {
-                l.cleanup();
-            }
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/Cab.java b/src/main/org/apache/tools/ant/taskdefs/optional/Cab.java
index 7e71aed..b94387d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/Cab.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/Cab.java
@@ -23,7 +23,8 @@
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.Enumeration;
+import java.io.PrintWriter;
+import java.util.Collections;
 import java.util.Vector;
 
 import org.apache.tools.ant.BuildException;
@@ -46,9 +47,9 @@
 
 public class Cab extends MatchingTask {
     private static final int DEFAULT_RESULT = -99;
+
     private File cabFile;
     private File baseDir;
-    private Vector filesets = new Vector();
     private boolean doCompress = true;
     private boolean doVerbose = false;
     private String cmdOptions;
@@ -59,6 +60,10 @@
 
     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
 
+    {
+        fileset = null;
+    }
+
     /**
      * The name/location of where to create the .cab file.
      * @param cabFile the location of the cab file.
@@ -101,13 +106,13 @@
 
     /**
      * Adds a set of files to archive.
-     * @param set a set of files to archive.
+     * @param fileset a set of files to archive.
      */
-    public void addFileset(FileSet set) {
-        if (filesets.size() > 0) {
+    public void addFileset(FileSet fileset) {
+        if (fileset != null) {
             throw new BuildException("Only one nested fileset allowed");
         }
-        filesets.addElement(set);
+        this.fileset = fileset;
     }
 
     /*
@@ -120,15 +125,15 @@
      * @throws BuildException on error.
      */
     protected void checkConfiguration() throws BuildException {
-        if (baseDir == null && filesets.size() == 0) {
-            throw new BuildException("basedir attribute or one "
-                                     + "nested fileset is required!",
-                                     getLocation());
+        if (baseDir == null && fileset == null) {
+            throw new BuildException(
+                "basedir attribute or one nested fileset is required!",
+                getLocation());
         }
         if (baseDir != null && !baseDir.exists()) {
             throw new BuildException("basedir does not exist!", getLocation());
         }
-        if (baseDir != null && filesets.size() > 0) {
+        if (baseDir != null && fileset != null) {
             throw new BuildException(
                 "Both basedir attribute and a nested fileset is not allowed");
         }
@@ -145,8 +150,7 @@
      * @throws BuildException on error.
      */
     protected ExecTask createExec() throws BuildException {
-        ExecTask exec = new ExecTask(this);
-        return exec;
+        return new ExecTask(this);
     }
 
     /**
@@ -154,17 +158,10 @@
      * @param files the list of files to check.
      * @return true if the cab file is newer than its dependents.
      */
-    protected boolean isUpToDate(Vector files) {
-        boolean upToDate = true;
-        final int size = files.size();
-        for (int i = 0; i < size && upToDate; i++) {
-            String file = files.elementAt(i).toString();
-            if (FILE_UTILS.resolveFile(baseDir, file).lastModified()
-                    > cabFile.lastModified()) {
-                upToDate = false;
-            }
-        }
-        return upToDate;
+    protected boolean isUpToDate(Vector<String> files) {
+        final long cabModified = cabFile.lastModified();
+        return files.stream().map(f -> FILE_UTILS.resolveFile(baseDir, f))
+            .mapToLong(File::lastModified).allMatch(t -> t < cabModified);
     }
 
     /**
@@ -177,23 +174,15 @@
      * @return the list file created.
      * @throws IOException if there is an error.
      */
-    protected File createListFile(Vector files)
+    protected File createListFile(Vector<String> files)
         throws IOException {
         File listFile = FILE_UTILS.createTempFile("ant", "", null, true, true);
 
-        BufferedWriter writer = null;
-        try {
-            writer = new BufferedWriter(new FileWriter(listFile));
-
-            final int size = files.size();
-            for (int i = 0; i < size; i++) {
-                writer.write('\"' + files.elementAt(i).toString() + '\"');
-                writer.newLine();
-            }
-        } finally {
-            FileUtils.close(writer);
+        try (PrintWriter writer =
+            new PrintWriter(new BufferedWriter(new FileWriter(listFile)))) {
+            files.stream().map(f -> String.format("\"%s\"", f))
+                .forEach(writer::println);
         }
-
         return listFile;
     }
 
@@ -202,12 +191,8 @@
      * @param files the vector to append the files to.
      * @param ds the scanner to get the files from.
      */
-    protected void appendFiles(Vector files, DirectoryScanner ds) {
-        String[] dsfiles = ds.getIncludedFiles();
-
-        for (int i = 0; i < dsfiles.length; i++) {
-            files.addElement(dsfiles[i]);
-        }
+    protected void appendFiles(Vector<String> files, DirectoryScanner ds) {
+        Collections.addAll(files, ds.getIncludedFiles());
     }
 
     /**
@@ -217,18 +202,16 @@
      * @return the list of files.
      * @throws BuildException if there is an error.
      */
-    protected Vector getFileList() throws BuildException {
-        Vector files = new Vector();
+    protected Vector<String> getFileList() throws BuildException {
+        Vector<String> files = new Vector<>();
 
         if (baseDir != null) {
             // get files from old methods - includes and nested include
             appendFiles(files, super.getDirectoryScanner(baseDir));
         } else {
-            FileSet fs = (FileSet) filesets.elementAt(0);
-            baseDir = fs.getDir();
-            appendFiles(files, fs.getDirectoryScanner(getProject()));
+            baseDir = fileset.getDir();
+            appendFiles(files, fileset.getDirectoryScanner(getProject()));
         }
-
         return files;
     }
 
@@ -236,11 +219,12 @@
      * execute this task.
      * @throws BuildException on error.
      */
+    @Override
     public void execute() throws BuildException {
 
         checkConfiguration();
 
-        Vector files = getFileList();
+        Vector<String> files = getFileList();
 
         // quick exit if the target is up to date
         if (isUpToDate(files)) {
@@ -252,20 +236,17 @@
         if (!Os.isFamily("windows")) {
             log("Using listcab/libcabinet", Project.MSG_VERBOSE);
 
-            StringBuffer sb = new StringBuffer();
+            StringBuilder sb = new StringBuilder();
 
-            Enumeration fileEnum = files.elements();
+            files.forEach(f -> sb.append(f).append("\n"));
 
-            while (fileEnum.hasMoreElements()) {
-                sb.append(fileEnum.nextElement()).append("\n");
-            }
             sb.append("\n").append(cabFile.getAbsolutePath()).append("\n");
 
             try {
                 Process p = Execute.launch(getProject(),
-                                           new String[] {"listcab"}, null,
-                                           baseDir != null ? baseDir : getProject().getBaseDir(),
-                                           true);
+                    new String[] {"listcab"}, null,
+                    baseDir != null ? baseDir : getProject().getBaseDir(),
+                    true);
                 OutputStream out = p.getOutputStream();
 
                 // Create the stream pumpers to forward listcab's stdout and stderr to the log
@@ -277,8 +258,8 @@
                 StreamPumper    errPump = new StreamPumper(p.getErrorStream(), errLog);
 
                 // Pump streams asynchronously
-                (new Thread(outPump)).start();
-                (new Thread(errPump)).start();
+                new Thread(outPump).start();
+                new Thread(errPump).start();
 
                 out.write(sb.toString().getBytes());
                 out.flush();
@@ -305,8 +286,9 @@
                     log("Error executing listcab; error code: " + result);
                 }
             } catch (IOException ex) {
-                String msg = "Problem creating " + cabFile + " " + ex.getMessage();
-                throw new BuildException(msg, getLocation());
+                throw new BuildException(
+                    "Problem creating " + cabFile + " " + ex.getMessage(),
+                    getLocation());
             }
         } else {
             try {
@@ -348,8 +330,9 @@
 
                 listFile.delete();
             } catch (IOException ioe) {
-                String msg = "Problem creating " + cabFile + " " + ioe.getMessage();
-                throw new BuildException(msg, getLocation());
+                throw new BuildException(
+                    "Problem creating " + cabFile + " " + ioe.getMessage(),
+                    getLocation());
             }
         }
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java b/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java
index 8a0a9e1..2ce593e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java
@@ -17,39 +17,38 @@
  */
 package org.apache.tools.ant.taskdefs.optional;
 
-import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Properties;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.Vector;
-
+import java.util.function.Function;
+import java.util.stream.Collectors;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.LogOutputStream;
 import org.apache.tools.ant.types.EnumeratedAttribute;
 import org.apache.tools.ant.types.PropertySet;
-import org.apache.tools.ant.util.CollectionUtils;
 import org.apache.tools.ant.util.DOMElementWriter;
-import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.JavaEnvUtils;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -130,7 +129,7 @@
      */
     private boolean failonerror = true;
 
-    private Vector propertySets = new Vector();
+    private List<PropertySet> propertySets = new Vector<>();
 
     private String format = "text";
 
@@ -160,7 +159,6 @@
         this.destfile = destfile;
     }
 
-
     /**
      * If true, the task will fail if an error occurs writing the properties
      * file, otherwise errors are just logged.
@@ -172,7 +170,6 @@
         this.failonerror = failonerror;
     }
 
-
     /**
      * If the prefix is set, then only properties which start with this
      * prefix string will be recorded. If regex is not set and  if this
@@ -212,7 +209,7 @@
      * @since Ant 1.7
      */
     public void setRegex(String regex) {
-        if (regex != null && regex.length() != 0) {
+        if (!(regex == null || regex.isEmpty())) {
             this.regex = regex;
             PropertySet ps = new PropertySet();
             ps.setProject(getProject());
@@ -227,7 +224,7 @@
      * @since Ant 1.6
      */
     public void addPropertyset(PropertySet ps) {
-        propertySets.addElement(ps);
+        propertySets.add(ps);
     }
 
     /**
@@ -249,6 +246,7 @@
          * @see EnumeratedAttribute#getValues()
          * @return accepted values
          */
+        @Override
         public String[] getValues() {
             return formats;
         }
@@ -259,27 +257,28 @@
      *
      * @exception BuildException  trouble, probably file IO
      */
+    @Override
     public void execute() throws BuildException {
         if (prefix != null && regex != null) {
-            throw new BuildException("Please specify either prefix"
-                    + " or regex, but not both", getLocation());
+            throw new BuildException(
+                "Please specify either prefix or regex, but not both",
+                getLocation());
         }
         //copy the properties file
-        Hashtable allProps = new Hashtable();
+        Hashtable<Object, Object> allProps = new Hashtable<>();
 
         /* load properties from file if specified, otherwise
         use Ant's properties */
-        if (inFile == null && propertySets.size() == 0) {
+        if (inFile == null && propertySets.isEmpty()) {
             // add ant properties
             allProps.putAll(getProject().getProperties());
         } else if (inFile != null) {
-            if (inFile.exists() && inFile.isDirectory()) {
+            if (inFile.isDirectory()) {
                 String message = "srcfile is a directory!";
                 if (failonerror) {
                     throw new BuildException(message, getLocation());
-                } else {
-                    log(message, Project.MSG_ERR);
                 }
+                log(message, Project.MSG_ERR);
                 return;
             }
 
@@ -293,9 +292,7 @@
                 return;
             }
 
-            FileInputStream in = null;
-            try {
-                in = new FileInputStream(inFile);
+            try (InputStream in = Files.newInputStream(inFile.toPath())) {
                 Properties props = new Properties();
                 props.load(in);
                 allProps.putAll(props);
@@ -304,72 +301,35 @@
                     "Could not find file " + inFile.getAbsolutePath();
                 if (failonerror) {
                     throw new BuildException(message, fnfe, getLocation());
-                } else {
-                    log(message, Project.MSG_WARN);
                 }
+                log(message, Project.MSG_WARN);
                 return;
             } catch (IOException ioe) {
                 String message =
                     "Could not read file " + inFile.getAbsolutePath();
                 if (failonerror) {
                     throw new BuildException(message, ioe, getLocation());
-                } else {
-                    log(message, Project.MSG_WARN);
                 }
+                log(message, Project.MSG_WARN);
                 return;
-            } finally {
-                FileUtils.close(in);
             }
         }
 
-        Enumeration e = propertySets.elements();
-        while (e.hasMoreElements()) {
-            PropertySet ps = (PropertySet) e.nextElement();
-            allProps.putAll(ps.getProperties());
-        }
+        propertySets.stream().map(PropertySet::getProperties)
+            .forEach(allProps::putAll);
 
-        OutputStream os = null;
-        try {
-            if (destfile == null) {
-                os = new ByteArrayOutputStream();
-                saveProperties(allProps, os);
-                log(os.toString(), Project.MSG_INFO);
-            } else {
-                if (destfile.exists() && destfile.isDirectory()) {
-                    String message = "destfile is a directory!";
-                    if (failonerror) {
-                        throw new BuildException(message, getLocation());
-                    } else {
-                        log(message, Project.MSG_ERR);
-                    }
-                    return;
-                }
-
-                if (destfile.exists() && !destfile.canWrite()) {
-                    String message =
-                        "Can not write to the specified destfile!";
-                    if (failonerror) {
-                        throw new BuildException(message, getLocation());
-                    } else {
-                        log(message, Project.MSG_ERR);
-                    }
-                    return;
-                }
-                os = new FileOutputStream(this.destfile);
+        try (OutputStream os = createOutputStream()) {
+            if (os != null) {
                 saveProperties(allProps, os);
             }
         } catch (IOException ioe) {
             if (failonerror) {
                 throw new BuildException(ioe, getLocation());
-            } else {
-                log(ioe.getMessage(), Project.MSG_INFO);
             }
-        } finally {
-            FileUtils.close(os);
+            log(ioe.getMessage(), Project.MSG_INFO);
         }
     }
 
-
     /**
      * Send the key/value pairs in the hashtable to the given output stream.
      * Only those properties matching the <tt>prefix</tt> constraint will be
@@ -381,37 +341,37 @@
      * @throws IOException      on output errors
      * @throws BuildException   on other errors
      */
-    protected void saveProperties(Hashtable allProps, OutputStream os)
+    protected void saveProperties(Hashtable<Object, Object> allProps, OutputStream os)
         throws IOException, BuildException {
-        final List keyList = new ArrayList(allProps.keySet());
-        Collections.sort(keyList);
+        final List<Object> keyList = new ArrayList<>(allProps.keySet());
+
         Properties props = new Properties() {
             private static final long serialVersionUID = 5090936442309201654L;
-            public Enumeration keys() {
-                return CollectionUtils.asEnumeration(keyList.iterator());
+
+            @Override
+            public Enumeration<Object> keys() {
+                return keyList.stream()
+                    .sorted(Comparator.comparing(Object::toString))
+                    .collect(Collectors.collectingAndThen(Collectors.toList(),
+                        Collections::enumeration));
             }
-            public Set entrySet() {
-                Set result = super.entrySet();
+
+            @Override
+            public Set<Map.Entry<Object, Object>> entrySet() {
+                Set<Map.Entry<Object, Object>> result = super.entrySet();
                 if (JavaEnvUtils.isKaffe()) {
-                    TreeSet t = new TreeSet(new Comparator() {
-                        public int compare(Object o1, Object o2) {
-                            String key1 = (String) ((Map.Entry) o1).getKey();
-                            String key2 = (String) ((Map.Entry) o2).getKey();
-                            return key1.compareTo(key2);
-                        }
-                    });
+                    Set<Map.Entry<Object, Object>> t =
+                        new TreeSet<>(Comparator.comparing(
+                            ((Function<Map.Entry<Object, Object>, Object>) Map.Entry::getKey)
+                                .andThen(Object::toString)));
                     t.addAll(result);
-                    result = t;
+                    return t;
                 }
                 return result;
             }
         };
-        final int size = keyList.size();
-        for (int i = 0; i < size; i++) {
-            String name = keyList.get(i).toString();
-            String value = allProps.get(name).toString();
-            props.setProperty(name, value);
-        }
+        allProps.forEach((k, v) -> props.put(String.valueOf(k), String.valueOf(v)));
+
         if ("text".equals(format)) {
             jdkSaveProperties(props, os, "Ant properties");
         } else if ("xml".equals(format)) {
@@ -422,7 +382,7 @@
     /**
      * a tuple for the sort list.
      */
-    private static final class Tuple implements Comparable {
+    private static final class Tuple implements Comparable<Tuple> {
         private String key;
         private String value;
 
@@ -439,9 +399,9 @@
          * @throws ClassCastException if the specified object's type prevents it
          *                            from being compared to this Object.
          */
-        public int compareTo(Object o) {
-            Tuple that = (Tuple) o;
-            return key.compareTo(that.key);
+        @Override
+        public int compareTo(Tuple o) {
+            return Comparator.<String> naturalOrder().compare(key, o.key);
         }
 
         @Override
@@ -453,26 +413,21 @@
                 return false;
             }
             Tuple that = (Tuple) o;
-            return (key == null ? that.key == null : key.equals(that.key))
-                && (value == null ? that.value == null : value.equals(that.value));
+            return Objects.equals(key, that.key)
+                && Objects.equals(value, that.value);
         }
 
         @Override
         public int hashCode() {
-            return key != null ? key.hashCode() : 0;
+            return Objects.hash(key);
         }
     }
 
-    private List sortProperties(Properties props) {
+    private List<Tuple> sortProperties(Properties props) {
         // sort the list. Makes SCM and manual diffs easier.
-        List sorted = new ArrayList(props.size());
-        Enumeration e = props.propertyNames();
-        while (e.hasMoreElements()) {
-            String name = (String) e.nextElement();
-            sorted.add(new Tuple(name, props.getProperty(name)));
-        }
-        Collections.sort(sorted);
-        return sorted;
+        return props.stringPropertyNames().stream()
+            .map(k -> new Tuple(k, props.getProperty(k))).sorted()
+            .collect(Collectors.toList());
     }
 
     /**
@@ -487,29 +442,22 @@
         Document doc = getDocumentBuilder().newDocument();
         Element rootElement = doc.createElement(PROPERTIES);
 
-        List sorted = sortProperties(props);
-
+        List<Tuple> sorted = sortProperties(props);
 
         // output properties
-        Iterator iten = sorted.iterator();
-        while (iten.hasNext()) {
-            Tuple tuple = (Tuple) iten.next();
+        for (Tuple tuple : sorted) {
             Element propElement = doc.createElement(PROPERTY);
             propElement.setAttribute(ATTR_NAME, tuple.key);
             propElement.setAttribute(ATTR_VALUE, tuple.value);
             rootElement.appendChild(propElement);
         }
 
-        Writer wri = null;
-        try {
-            wri = new OutputStreamWriter(os, "UTF8");
+        try (Writer wri = new OutputStreamWriter(os, "UTF8")) {
             wri.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-            (new DOMElementWriter()).write(rootElement, wri, 0, "\t");
+            new DOMElementWriter().write(rootElement, wri, 0, "\t");
             wri.flush();
         } catch (IOException ioe) {
             throw new BuildException("Unable to write XML file", ioe);
-        } finally {
-            FileUtils.close(wri);
         }
     }
 
@@ -527,7 +475,6 @@
                                      String header) throws IOException {
        try {
            props.store(os, header);
-
        } catch (IOException ioe) {
            throw new BuildException(ioe, getLocation());
        } finally {
@@ -541,6 +488,29 @@
        }
     }
 
+    private OutputStream createOutputStream() throws IOException {
+        if (destfile == null) {
+            return new LogOutputStream(this);
+        }
+        if (destfile.exists() && destfile.isDirectory()) {
+            String message = "destfile is a directory!";
+            if (failonerror) {
+                throw new BuildException(message, getLocation());
+            }
+            log(message, Project.MSG_ERR);
+            return null;
+        }
+        if (destfile.exists() && !destfile.canWrite()) {
+            String message =
+                "Can not write to the specified destfile!";
+            if (failonerror) {
+                throw new BuildException(message, getLocation());
+            }
+            log(message, Project.MSG_ERR);
+            return null;
+        }
+        return Files.newOutputStream(this.destfile.toPath());
+    }
 
     /**
      * Uses the DocumentBuilderFactory to get a DocumentBuilder instance.
@@ -555,4 +525,3 @@
         }
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/Javah.java b/src/main/org/apache/tools/ant/taskdefs/optional/Javah.java
index e9753df..ded183a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/Javah.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/Javah.java
@@ -19,10 +19,11 @@
 package org.apache.tools.ant.taskdefs.optional;
 
 import java.io.File;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.StringTokenizer;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
 import java.util.Vector;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -70,7 +71,7 @@
 
 public class Javah extends Task {
 
-    private Vector classes = new Vector(2);
+    private List<ClassArgument> classes = new Vector<>(2);
     private String cls;
     private File destDir;
     private Path classpath = null;
@@ -80,9 +81,8 @@
     private boolean old     = false;
     private boolean stubs   = false;
     private Path bootclasspath;
-    //private Path extdirs;
     private FacadeTaskHelper facade = null;
-    private Vector files = new Vector();
+    private Vector<FileSet> files = new Vector<>();
     private JavahAdapter nestedAdapter = null;
 
     /**
@@ -106,7 +106,7 @@
      */
     public ClassArgument createClass() {
         ClassArgument ga = new ClassArgument();
-        classes.addElement(ga);
+        classes.add(ga);
         return ga;
     }
 
@@ -117,10 +117,6 @@
     public class ClassArgument {
         private String name;
 
-        /** Constructor for ClassArgument. */
-        public ClassArgument() {
-        }
-
         /**
          * Set the name attribute.
          * @param name the name attribute.
@@ -152,33 +148,21 @@
      * @since Ant 1.6.3
      */
     public String[] getClasses() {
-        ArrayList al = new ArrayList();
+        Stream<String> stream = Stream.concat(
+            files.stream()
+                .map(fs -> fs.getDirectoryScanner(getProject())
+                    .getIncludedFiles())
+                .flatMap(Stream::of)
+                .map(s -> s.replace('\\', '.').replace('/', '.')
+                    .replaceFirst("\\.class$", "")),
+            classes.stream().map(ClassArgument::getName));
+
         if (cls != null) {
-            StringTokenizer tok = new StringTokenizer(cls, ",", false);
-            while (tok.hasMoreTokens()) {
-                al.add(tok.nextToken().trim());
-            }
+            stream = Stream.concat(Stream.of(cls.split(",")).map(String::trim),
+                stream);
         }
 
-        if (files.size() > 0) {
-            for (Enumeration e = files.elements(); e.hasMoreElements();) {
-                FileSet fs = (FileSet) e.nextElement();
-                String[] includedClasses = fs.getDirectoryScanner(
-                    getProject()).getIncludedFiles();
-                for (int i = 0; i < includedClasses.length; i++) {
-                    String className =
-                        includedClasses[i].replace('\\', '.').replace('/', '.')
-                        .substring(0, includedClasses[i].length() - 6);
-                    al.add(className);
-                }
-            }
-        }
-        Enumeration e = classes.elements();
-        while (e.hasMoreElements()) {
-            ClassArgument arg = (ClassArgument) e.nextElement();
-            al.add(arg.getName());
-        }
-        return (String[]) al.toArray(new String[al.size()]);
+        return stream.toArray(String[]::new);
     }
 
     /**
@@ -426,8 +410,7 @@
      */
     public void add(JavahAdapter adapter) {
         if (nestedAdapter != null) {
-            throw new BuildException("Can't have more than one javah"
-                                     + " adapter");
+            throw new BuildException("Can't have more than one javah adapter");
         }
         nestedAdapter = adapter;
     }
@@ -437,17 +420,22 @@
      *
      * @throws BuildException is there is a problem in the task execution.
      */
+    @Override
     public void execute() throws BuildException {
         // first off, make sure that we've got a srcdir
+        final Set<Settings> settings = EnumSet.noneOf(Settings.class);
 
-        if ((cls == null) && (classes.size() == 0) && (files.size() == 0)) {
-            throw new BuildException("class attribute must be set!",
-                getLocation());
+        if (cls != null) {
+            settings.add(Settings.cls);
         }
-
-        if ((cls != null) && (classes.size() > 0) && (files.size() > 0)) {
-            throw new BuildException("set class attribute OR class element OR fileset, "
-                + "not 2 or more of them.", getLocation());
+        if (!classes.isEmpty()) {
+            settings.add(Settings.classes);
+        }
+        if (!files.isEmpty()) {
+            settings.add(Settings.files);
+        }
+        if (settings.size() > 1) {
+            throw new BuildException("Exactly one of " + Settings.values() + " attributes is required", getLocation());
         }
 
         if (destDir != null) {
@@ -462,7 +450,7 @@
         }
 
         if (classpath == null) {
-            classpath = (new Path(getProject())).concatSystemClasspath("last");
+            classpath = new Path(getProject()).concatSystemClasspath("last");
         } else {
             classpath = classpath.concatSystemClasspath("ignore");
         }
@@ -493,22 +481,21 @@
         log("Compilation " + cmd.describeArguments(),
             Project.MSG_VERBOSE);
 
-        StringBuffer niceClassList = new StringBuffer();
         String[] c = getClasses();
-        for (int i = 0; i < c.length; i++) {
-            cmd.createArgument().setValue(c[i]);
-            niceClassList.append("    ");
-            niceClassList.append(c[i]);
-            niceClassList.append(StringUtils.LINE_SEP);
-        }
-
-        StringBuffer prefix = new StringBuffer("Class");
+        StringBuilder message = new StringBuilder("Class");
         if (c.length > 1) {
-            prefix.append("es");
+            message.append("es");
         }
-        prefix.append(" to be compiled:");
-        prefix.append(StringUtils.LINE_SEP);
+        message.append(" to be compiled:");
+        message.append(StringUtils.LINE_SEP);
+        for (String element : c) {
+            cmd.createArgument().setValue(element);
+            message.append("    ").append(element).append(StringUtils.LINE_SEP);
+        }
+        log(message.toString(), Project.MSG_VERBOSE);
+    }
 
-        log(prefix.toString() + niceClassList.toString(), Project.MSG_VERBOSE);
+    private enum Settings {
+        cls, files, classes
     }
 }
\ No newline at end of file
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java b/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java
index 664e574..2c7e9de 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java
@@ -198,8 +198,8 @@
      */
     public void add(Native2AsciiAdapter adapter) {
         if (nestedAdapter != null) {
-            throw new BuildException("Can't have more than one native2ascii"
-                                     + " adapter");
+            throw new BuildException(
+                "Can't have more than one native2ascii adapter");
         }
         nestedAdapter = adapter;
     }
@@ -209,6 +209,7 @@
      *
      * @throws BuildException is there is a problem in the task execution.
      */
+    @Override
     public void execute() throws BuildException {
 
         DirectoryScanner scanner = null; // Scanner to find our inputs
@@ -228,11 +229,11 @@
         // to be set, so we don't stomp every file.  One could still
         // include a file with the same extension, but ....
         if (srcDir.equals(destDir) && extension == null && mapper == null) {
-            throw new BuildException("The ext attribute or a mapper must be set if"
-                                     + " src and dest dirs are the same.");
+            throw new BuildException(
+                "The ext attribute or a mapper must be set if src and dest dirs are the same.");
         }
 
-        FileNameMapper m = null;
+        FileNameMapper m;
         if (mapper == null) {
             if (extension == null) {
                 m = new IdentityMapper();
@@ -276,8 +277,7 @@
 
         // Make sure we're not about to clobber something
         if (srcFile.equals(destFile)) {
-            throw new BuildException("file " + srcFile
-                                     + " would overwrite its self");
+            throw new BuildException("file %s would overwrite itself", srcFile);
         }
 
         // Make intermediate directories if needed
@@ -288,8 +288,8 @@
 
             if (!parentFile.exists()
                 && !(parentFile.mkdirs() || parentFile.isDirectory())) {
-                throw new BuildException("cannot create parent directory "
-                                         + parentName);
+                throw new BuildException("cannot create parent directory %s",
+                    parentName);
             }
         }
 
@@ -314,18 +314,21 @@
 
     private class ExtMapper implements FileNameMapper {
 
+        @Override
         public void setFrom(String s) {
         }
+
+        @Override
         public void setTo(String s) {
         }
 
+        @Override
         public String[] mapFileName(String fileName) {
             int lastDot = fileName.lastIndexOf('.');
             if (lastDot >= 0) {
                 return new String[] {fileName.substring(0, lastDot) + extension};
-            } else {
-                return new String[] {fileName + extension};
             }
+            return new String[] {fileName + extension};
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/NetRexxC.java b/src/main/org/apache/tools/ant/taskdefs/optional/NetRexxC.java
index a8aec7b..423fdbd 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/NetRexxC.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/NetRexxC.java
@@ -23,11 +23,14 @@
 import java.io.PrintWriter;
 import java.io.StringReader;
 import java.io.StringWriter;
-import java.util.Enumeration;
+import java.util.ArrayList;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Properties;
 import java.util.StringTokenizer;
 import java.util.Vector;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import netrexx.lang.Rexx;
 
@@ -142,8 +145,8 @@
     static final String MSG_DEPRECATION = "has been deprecated";
 
     // other implementation variables
-    private Vector compileList = new Vector();
-    private Hashtable filecopyList = new Hashtable();
+    private Vector<String> compileList = new Vector<>();
+    private Hashtable<String, String> filecopyList = new Hashtable<>();
 
     /**
      * Set whether literals are treated as binary, rather than NetRexx types.
@@ -155,7 +158,6 @@
         this.binary = binary;
     }
 
-
     /**
      * Set the classpath used for NetRexx compilation.
      * @param classpath the classpath to use.
@@ -164,7 +166,6 @@
         this.classpath = classpath;
     }
 
-
     /**
      * Set whether comments are passed through to the generated java source.
      * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
@@ -175,7 +176,6 @@
         this.comments = comments;
     }
 
-
     /**
      * Set whether error messages come out in compact or verbose format.
      * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
@@ -186,7 +186,6 @@
         this.compact = compact;
     }
 
-
     /**
      * Set whether the NetRexx compiler should compile the generated java code.
      * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
@@ -201,7 +200,6 @@
         }
     }
 
-
     /**
      * Set whether or not compiler messages should be displayed on the 'console'.
      * Note that this task will rely on the default value for filtering compile messages.
@@ -213,7 +211,6 @@
         this.console = console;
     }
 
-
     /**
      * Whether variable cross references are generated.
      * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
@@ -224,7 +221,6 @@
         this.crossref = crossref;
     }
 
-
     /**
      * Set whether decimal arithmetic should be used for the netrexx code.
      * Setting this to off will report decimal arithmetic as an error, for
@@ -237,7 +233,6 @@
         this.decimal = decimal;
     }
 
-
     /**
      * Set the destination directory into which the NetRexx source files
      * should be copied and then compiled.
@@ -247,7 +242,6 @@
         destDir = destDirName;
     }
 
-
     /**
      * Whether diagnostic information about the compile is generated
      * @param diag a <code>boolean</code> value.
@@ -256,7 +250,6 @@
         this.diag = diag;
     }
 
-
     /**
      * Sets whether variables must be declared explicitly before use.
      * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
@@ -267,7 +260,6 @@
         this.explicit = explicit;
     }
 
-
     /**
      * Whether the generated java code is formatted nicely or left to match
      * NetRexx line numbers for call stack debugging.
@@ -279,7 +271,6 @@
         this.format = format;
     }
 
-
     /**
      * Whether the generated java code is produced.
      * This is not implemented yet.
@@ -289,7 +280,6 @@
         log("The attribute java is currently unused.", Project.MSG_WARN);
     }
 
-
     /**
      * Sets whether the generated java source file should be kept after
      * compilation. The generated files will have an extension of .java.keep,
@@ -303,7 +293,6 @@
         this.keep = keep;
     }
 
-
     /**
      * Whether the compiler text logo is displayed when compiling.
      * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
@@ -314,7 +303,6 @@
         this.logo = logo;
     }
 
-
     /**
      * Whether the generated .java file should be replaced when compiling.
      * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
@@ -325,7 +313,6 @@
         this.replace = replace;
     }
 
-
     /**
      * Sets whether the compiler messages will be written to NetRexxC.log as
      * well as to the console.
@@ -337,7 +324,6 @@
         this.savelog = savelog;
     }
 
-
     /**
      * Tells the NetRexx compiler to store the class files in the same
      * directory as the source files. The alternative is the working directory.
@@ -349,7 +335,6 @@
         this.sourcedir = sourcedir;
     }
 
-
     /**
      * Set the source dir to find the source Java files.
      * @param srcDirName the source directory.
@@ -358,7 +343,6 @@
         srcDir = srcDirName;
     }
 
-
     /**
      * Tells the NetRexx compiler that method calls always need parentheses,
      * even if no arguments are needed, e.g. <code>aStringVar.getBytes</code>
@@ -371,7 +355,6 @@
         this.strictargs = strictargs;
     }
 
-
     /**
      * Tells the NetRexx compile that assignments must match exactly on type.
      * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
@@ -382,7 +365,6 @@
         this.strictassign = strictassign;
     }
 
-
     /**
      * Specifies whether the NetRexx compiler should be case sensitive or not.
      * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
@@ -393,7 +375,6 @@
         this.strictcase = strictcase;
     }
 
-
     /**
      * Sets whether classes need to be imported explicitly using an <code>import</code>
      * statement. By default the NetRexx compiler will import certain packages
@@ -406,7 +387,6 @@
         this.strictimport = strictimport;
     }
 
-
     /**
      * Sets whether local properties need to be qualified explicitly using
      * <code>this</code>.
@@ -418,7 +398,6 @@
         this.strictprops = strictprops;
     }
 
-
     /**
      * Whether the compiler should force catching of exceptions by explicitly
      * named types.
@@ -430,7 +409,6 @@
         this.strictsignal = strictsignal;
     }
 
-
     /**
      * Sets whether debug symbols should be generated into the class file.
      * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
@@ -441,7 +419,6 @@
         this.symbols = symbols;
     }
 
-
     /**
      * Asks the NetRexx compiler to print compilation times to the console
      * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
@@ -470,12 +447,10 @@
      */
     public void setTrace(String trace) {
         TraceAttr t = new TraceAttr();
-
         t.setValue(trace);
         setTrace(t);
     }
 
-
     /**
      * Tells the NetRexx compiler that the source is in UTF8.
      * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
@@ -486,7 +461,6 @@
         this.utf8 = utf8;
     }
 
-
     /**
      * Whether lots of warnings and error messages should be generated
      * @param verbose the value to set - verbose&lt;level&gt; or noverbose.
@@ -495,14 +469,12 @@
         this.verbose = verbose.getValue();
     }
 
-
     /**
      * Whether lots of warnings and error messages should be generated
      * @param verbose the value to set - verbose&lt;level&gt; or noverbose.
      */
     public void setVerbose(String verbose) {
         VerboseAttr v = new VerboseAttr();
-
         v.setValue(verbose);
         setVerbose(v);
     }
@@ -517,7 +489,6 @@
         this.suppressMethodArgumentNotUsed = suppressMethodArgumentNotUsed;
     }
 
-
     /**
      * Whether the task should suppress the "Private property is defined but
      * not used" in strictargs-Mode, which can be quite annoying while
@@ -528,7 +499,6 @@
         this.suppressPrivatePropertyNotUsed = suppressPrivatePropertyNotUsed;
     }
 
-
     /**
      * Whether the task should suppress the "Variable is set but not used" in
      * strictargs-Mode. Be careful with this one! The warning is logged as
@@ -539,7 +509,6 @@
         this.suppressVariableNotUsed = suppressVariableNotUsed;
     }
 
-
     /**
      * Whether the task should suppress the "FooException is in SIGNALS list
      * but is not signalled within the method", which is sometimes rather
@@ -550,7 +519,6 @@
         this.suppressExceptionNotSignalled = suppressExceptionNotSignalled;
     }
 
-
     /**
      * Tells whether we should filter out any deprecation-messages
      * of the compiler out.
@@ -560,7 +528,6 @@
         this.suppressDeprecation = suppressDeprecation;
     }
 
-
     /**
      * Tells whether the trailing .keep in nocompile-mode should be removed
      * so that the resulting java source really ends on .java.
@@ -571,12 +538,12 @@
         this.removeKeepExtension = removeKeepExtension;
     }
 
-
     /**
      * init-Method sets defaults from Properties. That way, when ant is called
      * with arguments like -Dant.netrexxc.verbose=verbose5 one can easily take
      * control of all netrexxc-tasks.
      */
+    @Override
     public void init() {
         String p;
 
@@ -681,11 +648,11 @@
         }
     }
 
-
     /**
      * Executes the task - performs the actual compiler call.
      * @throws BuildException on error.
      */
+    @Override
     public void execute() throws BuildException {
 
         // first off, make sure that we've got a srcdir and destdir
@@ -695,7 +662,6 @@
 
         // scan source and dest dirs to build up both copy lists and
         // compile lists
-        //        scanDir(srcDir, destDir);
         DirectoryScanner ds = getDirectoryScanner(srcDir);
 
         String[] files = ds.getIncludedFiles();
@@ -706,7 +672,7 @@
         copyFilesToDestination();
 
         // compile the source files
-        if (compileList.size() > 0) {
+        if (!compileList.isEmpty()) {
             log("Compiling " + compileList.size() + " source file"
                  + (compileList.size() == 1 ? "" : "s")
                  + " to " + destDir);
@@ -717,16 +683,14 @@
         }
     }
 
-
     /**
      * Scans the directory looking for source files to be compiled and support
      * files to be copied.
      */
     private void scanDir(File srcDir, File destDir, String[] files) {
-        for (int i = 0; i < files.length; i++) {
-            File srcFile = new File(srcDir, files[i]);
-            File destFile = new File(destDir, files[i]);
-            String filename = files[i];
+        for (String filename : files) {
+            File srcFile = new File(srcDir, filename);
+            File destFile = new File(destDir, filename);
             // if it's a non source file, copy it if a later date than the
             // dest
             // if it's a source file, see if the destination class file
@@ -749,112 +713,79 @@
                     filecopyList.put(srcFile.getAbsolutePath(), destFile.getAbsolutePath());
                     compileList.addElement(destFile.getAbsolutePath());
                 }
-            } else {
-                if (srcFile.lastModified() > destFile.lastModified()) {
-                    filecopyList.put(srcFile.getAbsolutePath(), destFile.getAbsolutePath());
-                }
+            } else if (srcFile.lastModified() > destFile.lastModified()) {
+                filecopyList.put(srcFile.getAbsolutePath(), destFile.getAbsolutePath());
             }
         }
     }
 
-
     /** Copy eligible files from the srcDir to destDir  */
     private void copyFilesToDestination() {
-        if (filecopyList.size() > 0) {
+        if (!filecopyList.isEmpty()) {
             log("Copying " + filecopyList.size() + " file"
                  + (filecopyList.size() == 1 ? "" : "s")
                  + " to " + destDir.getAbsolutePath());
 
-            Enumeration e = filecopyList.keys();
-
-            while (e.hasMoreElements()) {
-                String fromFile = (String) e.nextElement();
-                String toFile = (String) filecopyList.get(fromFile);
-
+            filecopyList.forEach((fromFile, toFile) -> {
                 try {
                     FileUtils.getFileUtils().copyFile(fromFile, toFile);
                 } catch (IOException ioe) {
-                    String msg = "Failed to copy " + fromFile + " to " + toFile
-                         + " due to " + ioe.getMessage();
-
-                    throw new BuildException(msg, ioe);
+                    throw new BuildException("Failed to copy " + fromFile
+                        + " to " + toFile + " due to " + ioe.getMessage(), ioe);
                 }
-            }
+            });
         }
     }
 
-
     /**
      * Rename .java.keep files (back) to .java. The netrexxc renames all
      * .java files to .java.keep if either -keep or -nocompile option is set.
      */
     private void removeKeepExtensions() {
-        if (compileList.size() > 0) {
+        if (!compileList.isEmpty()) {
             log("Removing .keep extension on " + compileList.size() + " file"
                  + (compileList.size() == 1 ? "" : "s"));
-            Enumeration e = compileList.elements();
-            while (e.hasMoreElements()) {
-                String nrxName = (String) e.nextElement();
-                String baseName = nrxName.substring(0, nrxName.lastIndexOf('.'));
+            compileList.forEach(nrxName -> {
+                String baseName =
+                    nrxName.substring(0, nrxName.lastIndexOf('.'));
                 File fromFile = new File(baseName + ".java.keep");
                 File toFile = new File(baseName + ".java");
                 if (fromFile.renameTo(toFile)) {
-                    log("Successfully renamed " + fromFile + " to " + toFile, Project.MSG_VERBOSE);
+                    log("Successfully renamed " + fromFile + " to " + toFile,
+                        Project.MSG_VERBOSE);
                 } else {
                     log("Failed to rename " + fromFile + " to " + toFile);
                 }
-            }
+            });
         }
     }
 
-
     /** Performs a compile using the NetRexx 1.1.x compiler  */
     private void doNetRexxCompile() throws BuildException {
         log("Using NetRexx compiler", Project.MSG_VERBOSE);
 
         String classpath = getCompileClasspath();
-        StringBuffer compileOptions = new StringBuffer();
 
         // create an array of strings for input to the compiler: one array
         // comes from the compile options, the other from the compileList
         String[] compileOptionsArray = getCompileOptionsAsArray();
-        String[] fileListArray = new String[compileList.size()];
-        Enumeration e = compileList.elements();
-        int j = 0;
-
-        while (e.hasMoreElements()) {
-            fileListArray[j] = (String) e.nextElement();
-            j++;
-        }
-        // create a single array of arguments for the compiler
-        String[] compileArgs = new String[compileOptionsArray.length + fileListArray.length];
-
-        for (int i = 0; i < compileOptionsArray.length; i++) {
-            compileArgs[i] = compileOptionsArray[i];
-        }
-        for (int i = 0; i < fileListArray.length; i++) {
-            compileArgs[i + compileOptionsArray.length] = fileListArray[i];
-        }
 
         // print nice output about what we are doing for the log
-        compileOptions.append("Compilation args: ");
-        for (int i = 0; i < compileOptionsArray.length; i++) {
-            compileOptions.append(compileOptionsArray[i]);
-            compileOptions.append(" ");
-        }
-        log(compileOptions.toString(), Project.MSG_VERBOSE);
+        log(Stream.of(compileOptionsArray)
+            .collect(Collectors.joining(" ", "Compilation args: ", "")),
+            Project.MSG_VERBOSE);
 
-        String eol = System.getProperty("line.separator");
-        StringBuffer niceSourceList = new StringBuffer("Files to be compiled:" + eol);
+        log("Files to be compiled:", Project.MSG_VERBOSE);
 
-        final int size = compileList.size();
-        for (int i = 0; i < size; i++) {
-            niceSourceList.append("    ");
-            niceSourceList.append(compileList.elementAt(i).toString());
-            niceSourceList.append(eol);
-        }
+        final String eol = System.getProperty("line.separator");
+        log(
+            compileList.stream().map(s -> "    " + s).collect(Collectors.joining(eol))
+            , Project.MSG_VERBOSE);
 
-        log(niceSourceList.toString(), Project.MSG_VERBOSE);
+        // create a single array of arguments for the compiler
+        String[] compileArgs =
+                Stream.concat(Stream.of(compileOptionsArray), compileList.stream())
+                .toArray(String[]::new);
 
         // need to set java.class.path property and restore it later
         // since the NetRexx compiler has no option for the classpath
@@ -865,7 +796,7 @@
 
         try {
             StringWriter out = new StringWriter();
-            PrintWriter w = null;
+            PrintWriter w;
             int rc =
                 COM.ibm.netrexx.process.NetRexxC.main(new Rexx(compileArgs),
                                                       w = new PrintWriter(out)); //NOSONAR
@@ -873,17 +804,18 @@
             String ddir = destDir.getAbsolutePath();
             boolean doReplace = !(sdir.equals(ddir));
             int dlen = ddir.length();
-            String l;
             BufferedReader in = new BufferedReader(new StringReader(out.toString()));
 
             log("replacing destdir '" + ddir + "' through sourcedir '"
                 + sdir + "'", Project.MSG_VERBOSE);
+
+            String l;
             while ((l = in.readLine()) != null) {
                 int idx;
 
                 while (doReplace && ((idx = l.indexOf(ddir)) != -1)) {
                     // path is mentioned in the message
-                    l = (new StringBuffer(l)).replace(idx, idx + dlen, sdir).toString();
+                    l = new StringBuilder(l).replace(idx, idx + dlen, sdir).toString();
                 }
                 // verbose level logging for suppressed messages
                 if (suppressMethodArgumentNotUsed
@@ -912,28 +844,26 @@
                 }
             }
             if (rc > 1) {
-                throw new BuildException("Compile failed, messages should "
-                    + "have been provided.");
+                throw new BuildException(
+                    "Compile failed, messages should have been provided.");
             }
             if (w.checkError()) {
                 throw new IOException("Encountered an error");
             }
         } catch (IOException ioe) {
-            throw new BuildException("Unexpected IOException while "
-                + "playing with Strings", ioe);
+            throw new BuildException(
+                "Unexpected IOException while playing with Strings", ioe);
         } finally {
             // need to reset java.class.path property
             // since the NetRexx compiler has no option for the classpath
             currentProperties = System.getProperties();
             currentProperties.put("java.class.path", currentClassPath);
         }
-
     }
 
-
     /** Builds the compilation classpath.  */
     private String getCompileClasspath() {
-        StringBuffer classpath = new StringBuffer();
+        StringBuilder classpath = new StringBuilder();
 
         // add dest dir to classpath so that previously compiled and
         // untouched classes are on classpath
@@ -945,49 +875,43 @@
         }
 
         // add the system classpath
-        // addExistingToClasspath(classpath,System.getProperty("java.class.path"));
         return classpath.toString();
     }
 
-
     /** This  */
     private String[] getCompileOptionsAsArray() {
-        Vector options = new Vector();
+        List<String> options = new ArrayList<>();
 
-        options.addElement(binary ? "-binary" : "-nobinary");
-        options.addElement(comments ? "-comments" : "-nocomments");
-        options.addElement(compile ? "-compile" : "-nocompile");
-        options.addElement(compact ? "-compact" : "-nocompact");
-        options.addElement(console ? "-console" : "-noconsole");
-        options.addElement(crossref ? "-crossref" : "-nocrossref");
-        options.addElement(decimal ? "-decimal" : "-nodecimal");
-        options.addElement(diag ? "-diag" : "-nodiag");
-        options.addElement(explicit ? "-explicit" : "-noexplicit");
-        options.addElement(format ? "-format" : "-noformat");
-        options.addElement(keep ? "-keep" : "-nokeep");
-        options.addElement(logo ? "-logo" : "-nologo");
-        options.addElement(replace ? "-replace" : "-noreplace");
-        options.addElement(savelog ? "-savelog" : "-nosavelog");
-        options.addElement(sourcedir ? "-sourcedir" : "-nosourcedir");
-        options.addElement(strictargs ? "-strictargs" : "-nostrictargs");
-        options.addElement(strictassign ? "-strictassign" : "-nostrictassign");
-        options.addElement(strictcase ? "-strictcase" : "-nostrictcase");
-        options.addElement(strictimport ? "-strictimport" : "-nostrictimport");
-        options.addElement(strictprops ? "-strictprops" : "-nostrictprops");
-        options.addElement(strictsignal ? "-strictsignal" : "-nostrictsignal");
-        options.addElement(symbols ? "-symbols" : "-nosymbols");
-        options.addElement(time ? "-time" : "-notime");
-        options.addElement("-" + trace);
-        options.addElement(utf8 ? "-utf8" : "-noutf8");
-        options.addElement("-" + verbose);
+        options.add(binary ? "-binary" : "-nobinary");
+        options.add(comments ? "-comments" : "-nocomments");
+        options.add(compile ? "-compile" : "-nocompile");
+        options.add(compact ? "-compact" : "-nocompact");
+        options.add(console ? "-console" : "-noconsole");
+        options.add(crossref ? "-crossref" : "-nocrossref");
+        options.add(decimal ? "-decimal" : "-nodecimal");
+        options.add(diag ? "-diag" : "-nodiag");
+        options.add(explicit ? "-explicit" : "-noexplicit");
+        options.add(format ? "-format" : "-noformat");
+        options.add(keep ? "-keep" : "-nokeep");
+        options.add(logo ? "-logo" : "-nologo");
+        options.add(replace ? "-replace" : "-noreplace");
+        options.add(savelog ? "-savelog" : "-nosavelog");
+        options.add(sourcedir ? "-sourcedir" : "-nosourcedir");
+        options.add(strictargs ? "-strictargs" : "-nostrictargs");
+        options.add(strictassign ? "-strictassign" : "-nostrictassign");
+        options.add(strictcase ? "-strictcase" : "-nostrictcase");
+        options.add(strictimport ? "-strictimport" : "-nostrictimport");
+        options.add(strictprops ? "-strictprops" : "-nostrictprops");
+        options.add(strictsignal ? "-strictsignal" : "-nostrictsignal");
+        options.add(symbols ? "-symbols" : "-nosymbols");
+        options.add(time ? "-time" : "-notime");
+        options.add("-" + trace);
+        options.add(utf8 ? "-utf8" : "-noutf8");
+        options.add("-" + verbose);
 
-        String[] results = new String[options.size()];
-
-        options.copyInto(results);
-        return results;
+        return options.toArray(new String[options.size()]);
     }
 
-
     /**
      * Takes a classpath-like string, and adds each element of this string to
      * a new classpath, if the components exist. Components that don't exist,
@@ -998,7 +922,7 @@
      * @param target - target classpath
      * @param source - source classpath to get file objects.
      */
-    private void addExistingToClasspath(StringBuffer target, String source) {
+    private void addExistingToClasspath(StringBuilder target, String source) {
         StringTokenizer tok = new StringTokenizer(source,
             System.getProperty("path.separator"), false);
 
@@ -1013,15 +937,14 @@
                     + f.getAbsolutePath(), Project.MSG_VERBOSE);
             }
         }
-
     }
 
-
     /**
      * Enumerated class corresponding to the trace attribute.
      */
     public static class TraceAttr extends EnumeratedAttribute {
         /** {@inheritDoc}. */
+        @Override
         public String[] getValues() {
             return new String[] {"trace", "trace1", "trace2", "notrace"};
         }
@@ -1032,9 +955,10 @@
      */
     public static class VerboseAttr extends EnumeratedAttribute {
         /** {@inheritDoc}. */
+        @Override
         public String[] getValues() {
             return new String[] {"verbose", "verbose0", "verbose1", "verbose2",
-                    "verbose3", "verbose4", "verbose5", "noverbose"};
+                "verbose3", "verbose4", "verbose5", "noverbose"};
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java b/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java
index 71f2841..064336a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java
@@ -21,17 +21,16 @@
 import java.io.BufferedInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.file.Files;
 import java.text.DateFormat;
 import java.text.DecimalFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
@@ -147,7 +146,7 @@
     private File                propertyfile;
     private boolean             useJDKProperties;
 
-    private Vector entries = new Vector();
+    private Vector<Entry> entries = new Vector<>();
 
     /* ========================================================================
      *
@@ -182,10 +181,7 @@
     }
 
     private void executeOperation() throws BuildException {
-        for (Enumeration e = entries.elements(); e.hasMoreElements();) {
-            Entry entry = (Entry) e.nextElement();
-            entry.executeOn(properties);
-        }
+        entries.forEach(e -> e.executeOn(properties));
     }
 
     private void readFile() throws BuildException {
@@ -200,27 +196,16 @@
             if (propertyfile.exists()) {
                 log("Updating property file: "
                     + propertyfile.getAbsolutePath());
-                FileInputStream fis = null;
-                try {
-                    fis = new FileInputStream(propertyfile);
-                    BufferedInputStream bis = new BufferedInputStream(fis);
+                try (InputStream fis = Files.newInputStream(propertyfile.toPath());
+                     BufferedInputStream bis = new BufferedInputStream(fis)) {
                     properties.load(bis);
-                } finally {
-                    if (fis != null) {
-                        fis.close();
-                    }
                 }
             } else {
                 log("Creating new property file: "
                     + propertyfile.getAbsolutePath());
-                FileOutputStream out = null;
-                try {
-                    out = new FileOutputStream(propertyfile.getAbsolutePath());
+                try (OutputStream out =
+                     Files.newOutputStream(propertyfile.toPath())) {
                     out.flush();
-                } finally {
-                    if (out != null) {
-                        out.close();
-                    }
                 }
             }
         } catch (IOException ioe) {
@@ -269,7 +254,7 @@
             throw new BuildException(x, getLocation());
         }
         try {
-            OutputStream os = new FileOutputStream(propertyfile); //NOSONAR
+            OutputStream os = Files.newOutputStream(propertyfile.toPath()); //NOSONAR
             try {
                 try {
                     os.write(baos.toByteArray());
@@ -286,7 +271,7 @@
     }
 
     private boolean checkParam(File param) {
-        return !(param == null);
+        return param != null;
     }
 
     /**
@@ -404,7 +389,7 @@
                 } else if (type == Type.STRING_TYPE) {
                     executeString(oldValue);
                 } else {
-                    throw new BuildException("Unknown operation type: " + type);
+                    throw new BuildException("Unknown operation type: %d", type);
                 }
             } catch (NullPointerException npe) {
                 // Default to string type
@@ -466,7 +451,6 @@
             newValue = fmt.format(currentValue.getTime());
         }
 
-
         /**
          * Handle operations for type <code>int</code>.
          *
@@ -478,7 +462,6 @@
             int currentValue = DEFAULT_INT_VALUE;
             int newV  = DEFAULT_INT_VALUE;
 
-
             DecimalFormat fmt = (pattern != null) ? new DecimalFormat(pattern)
                 : new DecimalFormat();
             try {
@@ -554,15 +537,17 @@
                                          + "properties (key:" + key + ")");
             }
             if (value == null && defaultValue == null  && operation != Operation.DELETE_OPER) {
-                throw new BuildException("\"value\" and/or \"default\" "
-                                         + "attribute must be specified (key:" + key + ")");
+                throw new BuildException(
+                    "\"value\" and/or \"default\" attribute must be specified (key: %s)",
+                    key);
             }
             if (key == null) {
                 throw new BuildException("key is mandatory");
             }
             if (type == Type.STRING_TYPE && pattern != null) {
-                throw new BuildException("pattern is not supported for string "
-                                         + "properties (key:" + key + ")");
+                throw new BuildException(
+                    "pattern is not supported for string properties (key: %s)",
+                    key);
             }
         }
 
@@ -601,7 +586,7 @@
                     ret = defaultValue;
                 }
             } else {
-                ret = (oldValue == null) ? defaultValue : oldValue;
+                ret = oldValue == null ? defaultValue : oldValue;
             }
 
             return ret;
@@ -636,9 +621,11 @@
             public static int toOperation(String oper) {
                 if ("+".equals(oper)) {
                     return INCREMENT_OPER;
-                } else if ("-".equals(oper)) {
+                }
+                if ("-".equals(oper)) {
                     return DECREMENT_OPER;
-                } else if ("del".equals(oper)) {
+                }
+                if ("del".equals(oper)) {
                     return DELETE_OPER;
                 }
                 return EQUALS_OPER;
@@ -672,7 +659,8 @@
             public static int toType(String type) {
                 if ("int".equals(type)) {
                     return INTEGER_TYPE;
-                } else if ("date".equals(type)) {
+                }
+                if ("date".equals(type)) {
                     return DATE_TYPE;
                 }
                 return STRING_TYPE;
@@ -699,19 +687,19 @@
         private static final String[] UNITS = {MILLISECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH,
                 YEAR};
 
-        private Map calendarFields = new HashMap();
+        private Map<String, Integer> calendarFields = new HashMap<>();
 
         /** no arg constructor */
         public Unit() {
             calendarFields.put(MILLISECOND,
-                               new Integer(Calendar.MILLISECOND));
-            calendarFields.put(SECOND, new Integer(Calendar.SECOND));
-            calendarFields.put(MINUTE, new Integer(Calendar.MINUTE));
-            calendarFields.put(HOUR, new Integer(Calendar.HOUR_OF_DAY));
-            calendarFields.put(DAY, new Integer(Calendar.DATE));
-            calendarFields.put(WEEK, new Integer(Calendar.WEEK_OF_YEAR));
-            calendarFields.put(MONTH, new Integer(Calendar.MONTH));
-            calendarFields.put(YEAR, new Integer(Calendar.YEAR));
+                Integer.valueOf(Calendar.MILLISECOND));
+            calendarFields.put(SECOND, Integer.valueOf(Calendar.SECOND));
+            calendarFields.put(MINUTE, Integer.valueOf(Calendar.MINUTE));
+            calendarFields.put(HOUR, Integer.valueOf(Calendar.HOUR_OF_DAY));
+            calendarFields.put(DAY, Integer.valueOf(Calendar.DATE));
+            calendarFields.put(WEEK, Integer.valueOf(Calendar.WEEK_OF_YEAR));
+            calendarFields.put(MONTH, Integer.valueOf(Calendar.MONTH));
+            calendarFields.put(YEAR, Integer.valueOf(Calendar.YEAR));
         }
 
         /**
@@ -719,9 +707,7 @@
          * @return the calendar value.
          */
         public int getCalendarField() {
-            String key = getValue().toLowerCase();
-            Integer i = (Integer) calendarFields.get(key);
-            return i.intValue();
+            return calendarFields.get(getValue().toLowerCase()).intValue();
         }
 
         /** {@inheritDoc}. */
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java b/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java
index cf07885..e4271ff 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java
@@ -20,8 +20,6 @@
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -29,6 +27,8 @@
 import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.io.Writer;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -144,7 +144,6 @@
         this.subs = null;
     }
 
-
     /**
      * file for which the regular expression should be replaced;
      * required unless a nested fileset is supplied.
@@ -155,7 +154,6 @@
         this.file = file;
     }
 
-
     /**
      * the regular expression pattern to match in the file(s);
      * required if no nested &lt;regexp&gt; is used
@@ -171,7 +169,6 @@
         regex.setPattern(match);
     }
 
-
     /**
      * The substitution pattern to place in the file(s) in place
      * of the regular expression.
@@ -182,8 +179,8 @@
 
     public void setReplace(String replace) {
         if (subs != null) {
-            throw new BuildException("Only one substitution expression is "
-                                     + "allowed");
+            throw new BuildException(
+                "Only one substitution expression is allowed");
         }
 
         subs = new Substitution();
@@ -210,7 +207,6 @@
         this.flags = flags;
     }
 
-
     /**
      * Process the file(s) one line at a time, executing the replacement
      * on one line at a time.  This is useful if you
@@ -224,12 +220,7 @@
      */
     @Deprecated
     public void setByLine(String byline) {
-        Boolean res = Boolean.valueOf(byline);
-
-        if (res == null) {
-            res = Boolean.FALSE;
-        }
-        this.byline = res.booleanValue();
+        this.byline = Boolean.parseBoolean(byline);
     }
 
     /**
@@ -305,8 +296,8 @@
      */
     public Substitution createSubstitution() {
         if (subs != null) {
-            throw new BuildException("Only one substitution expression is "
-                                     + "allowed");
+            throw new BuildException(
+                "Only one substitution expression is allowed");
         }
 
         subs = new Substitution();
@@ -350,7 +341,6 @@
         return res;
     }
 
-
     /**
      * Perform the replacement on a file
      *
@@ -364,13 +354,14 @@
         try {
             boolean changes = false;
 
-            InputStream is = new FileInputStream(f);
-            try {
-                Reader r = encoding != null ? new InputStreamReader(is, encoding) : new InputStreamReader(is);
-                OutputStream os = new FileOutputStream(temp);
+            final Charset charset = encoding == null ? Charset.defaultCharset() : Charset.forName(encoding);
+            try (InputStream is = Files.newInputStream(f.toPath());
+                 OutputStream os = Files.newOutputStream(temp.toPath())) {
+                Reader r = null;
+                Writer w = null;
                 try {
-                    Writer w = encoding != null ? new OutputStreamWriter(os, encoding) : new OutputStreamWriter(os);
-
+                    r = new InputStreamReader(is, charset);
+                    w = new OutputStreamWriter(os, charset);
                     log("Replacing pattern '" + regex.getPattern(getProject())
                         + "' with '" + subs.getExpression(getProject())
                         + "' in '" + f.getPath() + "'" + (byline ? " by line" : "")
@@ -381,7 +372,7 @@
                         r = new BufferedReader(r);
                         w = new BufferedWriter(w);
 
-                        StringBuffer linebuf = new StringBuffer();
+                        StringBuilder linebuf = new StringBuilder();
                         int c;
                         boolean hasCR = false;
 
@@ -395,7 +386,7 @@
                                                                w, options);
                                     w.write('\r');
 
-                                    linebuf = new StringBuffer();
+                                    linebuf = new StringBuilder();
                                     // hasCR is still true (for the second one)
                                 } else {
                                     // first CR in this line
@@ -411,7 +402,7 @@
                                 }
                                 w.write('\n');
 
-                                linebuf = new StringBuffer();
+                                linebuf = new StringBuilder();
                             } else { // any other char
                                 if ((hasCR) || (c < 0)) {
                                     // Mac-style linebreak or EOF (or both)
@@ -422,7 +413,7 @@
                                         hasCR = false;
                                     }
 
-                                    linebuf = new StringBuffer();
+                                    linebuf = new StringBuilder();
                                 }
 
                                 if (c >= 0) {
@@ -434,15 +425,10 @@
                     } else {
                         changes = multilineReplace(r, w, options);
                     }
-
-                    r.close();
-                    w.close();
-
                 } finally {
-                    os.close();
+                    FileUtils.close(r);
+                    FileUtils.close(w);
                 }
-            } finally {
-                is.close();
             }
             if (changes) {
                 log("File has changed; saving the updated file", Project.MSG_VERBOSE);
@@ -467,7 +453,6 @@
         }
     }
 
-
     /**
      * Execute the task
      *
@@ -483,9 +468,8 @@
         }
 
         if (file != null && resources != null) {
-            throw new BuildException("You cannot supply the 'file' attribute "
-                                     + "and resource collections at the same "
-                                     + "time.");
+            throw new BuildException(
+                "You cannot supply the 'file' attribute and resource collections at the same time.");
         }
 
         int options = RegexpUtil.asOptions(flags);
@@ -505,9 +489,7 @@
 
         if (resources != null) {
             for (Resource r : resources) {
-                FileProvider fp =
-                    r.as(FileProvider.class);
-                File f = fp.getFile();
+                File f = r.as(FileProvider.class).getFile();
 
                 if (f.exists()) {
                     try {
@@ -537,5 +519,3 @@
         return !res.equals(s);
     }
 }
-
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/Rpm.java b/src/main/org/apache/tools/ant/taskdefs/optional/Rpm.java
index a816f6e..65a934b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/Rpm.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/Rpm.java
@@ -19,10 +19,10 @@
 
 import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintStream;
+import java.nio.file.Files;
 import java.util.Map;
 
 import org.apache.tools.ant.BuildException;
@@ -110,6 +110,7 @@
      *
      * @throws BuildException is there is a problem in the task execution.
      */
+    @Override
     public void execute() throws BuildException {
 
         Commandline toExecute = new Commandline();
@@ -148,9 +149,9 @@
             }
         } else {
             if (output != null) {
-                FileOutputStream fos = null;
+                OutputStream fos = null;
                 try {
-                    fos = new FileOutputStream(output); //NOSONAR
+                    fos = Files.newOutputStream(output.toPath()); //NOSONAR
                     BufferedOutputStream bos = new BufferedOutputStream(fos);
                     outputstream = new PrintStream(bos);
                 } catch (IOException e) {
@@ -163,9 +164,9 @@
                 outputstream = new LogOutputStream(this, Project.MSG_DEBUG);
             }
             if (error != null) {
-                FileOutputStream fos = null;
+                OutputStream fos = null;
                 try {
-                    fos = new FileOutputStream(error);
+                    fos = Files.newOutputStream(error.toPath());
                     BufferedOutputStream bos = new BufferedOutputStream(fos);
                     errorstream = new PrintStream(bos);
                 } catch (IOException e) {
@@ -226,7 +227,7 @@
      * @param sf the spec file name to use.
      */
     public void setSpecFile(String sf) {
-        if ((sf == null) || (sf.trim().length() == 0)) {
+        if (sf == null || sf.trim().isEmpty()) {
             throw new BuildException("You must specify a spec file", getLocation());
         }
         this.specFile = sf;
@@ -319,20 +320,20 @@
      * @since 1.6
      */
     protected String guessRpmBuildCommand() {
-        Map/*<String, String>*/ env = Execute.getEnvironmentVariables();
-        String path = (String) env.get(PATH1);
+        Map<String, String> env = Execute.getEnvironmentVariables();
+        String path = env.get(PATH1);
         if (path == null) {
-            path = (String) env.get(PATH2);
+            path = env.get(PATH2);
             if (path == null) {
-                path = (String) env.get(PATH3);
+                path = env.get(PATH3);
             }
         }
 
         if (path != null) {
             Path p = new Path(getProject(), path);
             String[] pElements = p.list();
-            for (int i = 0; i < pElements.length; i++) {
-                File f = new File(pElements[i],
+            for (String pElement : pElements) {
+                File f = new File(pElement,
                                   "rpmbuild"
                                   + (Os.isFamily("dos") ? ".exe" : ""));
                 if (f.canRead()) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/SchemaValidate.java b/src/main/org/apache/tools/ant/taskdefs/optional/SchemaValidate.java
index 30801de..4e1837c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/SchemaValidate.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/SchemaValidate.java
@@ -20,7 +20,8 @@
 import java.io.File;
 import java.net.MalformedURLException;
 import java.util.HashMap;
-import java.util.Iterator;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
@@ -48,23 +49,6 @@
  */
 
 public class SchemaValidate extends XMLValidateTask {
-
-    /** map of all declared schemas; we catch and complain about redefinitions */
-    private HashMap schemaLocations = new HashMap();
-
-    /** full checking of a schema */
-    private boolean fullChecking = true;
-
-    /**
-     * flag to disable DTD support. Best left enabled.
-     */
-    private boolean disableDTD = false;
-
-    /**
-     * default URL for nonamespace schemas
-     */
-    private SchemaLocation anonymousSchema;
-
     // Error strings
     /** SAX1 not supported */
     public static final String ERROR_SAX_1 = "SAX1 parsers are not supported";
@@ -88,12 +72,29 @@
     public static final String ERROR_DUPLICATE_SCHEMA
         = "Duplicate declaration of schema ";
 
+    /** map of all declared schemas; we catch and complain about redefinitions */
+    private Map<String, SchemaLocation> schemaLocations = new HashMap<>();
+
+    /** full checking of a schema */
+    private boolean fullChecking = true;
+
+    /**
+     * flag to disable DTD support. Best left enabled.
+     */
+    private boolean disableDTD = false;
+
+    /**
+     * default URL for nonamespace schemas
+     */
+    private SchemaLocation anonymousSchema;
+
     /**
      * Called by the project to let the task initialize properly. The default
      * implementation is a no-op.
      *
      * @throws BuildException if something goes wrong with the build
      */
+    @Override
     public void init() throws BuildException {
         super.init();
         //validating
@@ -155,7 +156,7 @@
     public void addConfiguredSchema(SchemaLocation location) {
         log("adding schema " + location, Project.MSG_DEBUG);
         location.validateNamespace();
-        SchemaLocation old = (SchemaLocation) schemaLocations.get(location.getNamespace());
+        SchemaLocation old = schemaLocations.get(location.getNamespace());
         if (old != null && !old.equals(location)) {
             throw new BuildException(ERROR_DUPLICATE_SCHEMA + location);
         }
@@ -213,6 +214,7 @@
      *
      * @throws BuildException if something went wrong
      */
+    @Override
     protected void initValidator() {
         super.initValidator();
         //validate the parser type
@@ -221,7 +223,6 @@
         }
 
         //enable schema
-        //setFeature(XmlConstants.FEATURE_VALIDATION, false);
         setFeature(XmlConstants.FEATURE_NAMESPACES, true);
         if (!enableXercesSchemaValidation() && !enableJAXP12SchemaValidation()) {
             //could not use xerces or jaxp calls
@@ -244,6 +245,7 @@
      * create our own factory with our own options.
      * @return a default XML parser
      */
+    @Override
     protected XMLReader createDefaultReader() {
         SAXParserFactory factory = SAXParserFactory.newInstance();
         factory.setValidating(true);
@@ -252,9 +254,7 @@
         try {
             SAXParser saxParser = factory.newSAXParser();
             reader = saxParser.getXMLReader();
-        } catch (ParserConfigurationException e) {
-            throw new BuildException(ERROR_PARSER_CREATION_FAILURE, e);
-        } catch (SAXException e) {
+        } catch (ParserConfigurationException | SAXException e) {
             throw new BuildException(ERROR_PARSER_CREATION_FAILURE, e);
         }
         return reader;
@@ -265,23 +265,15 @@
      * property.
      */
     protected void addSchemaLocations() {
-        Iterator it = schemaLocations.values().iterator();
-        StringBuffer buffer = new StringBuffer();
-        int count = 0;
-        while (it.hasNext()) {
-            if (count > 0) {
-                buffer.append(' ');
-            }
-            SchemaLocation schemaLocation = (SchemaLocation) it.next();
-            String tuple = schemaLocation.getURIandLocation();
-            buffer.append(tuple);
-            log("Adding schema " + tuple, Project.MSG_VERBOSE);
-            count++;
-        }
-        if (count > 0) {
-            setProperty(XmlConstants.PROPERTY_SCHEMA_LOCATION, buffer.toString());
-        }
+        if (!schemaLocations.isEmpty()) {
+            String joinedValue = schemaLocations.values().stream()
+                .map(SchemaLocation::getURIandLocation)
+                .peek(
+                    tuple -> log("Adding schema " + tuple, Project.MSG_VERBOSE))
+                .collect(Collectors.joining(" "));
 
+            setProperty(XmlConstants.PROPERTY_SCHEMA_LOCATION, joinedValue);
+        }
     }
 
     /**
@@ -289,11 +281,8 @@
      * @return the schema URL
      */
     protected String getNoNamespaceSchemaURL() {
-        if (anonymousSchema == null) {
-            return null;
-        } else {
-            return anonymousSchema.getSchemaLocationURL();
-        }
+        return anonymousSchema == null ? null
+            : anonymousSchema.getSchemaLocationURL();
     }
 
     /**
@@ -317,6 +306,7 @@
      *
      * @param fileProcessed number of files processed.
      */
+    @Override
     protected void onSuccessfulValidation(int fileProcessed) {
         log(fileProcessed + MESSAGE_FILES_VALIDATED, Project.MSG_VERBOSE);
     }
@@ -350,10 +340,6 @@
         public static final String ERROR_NO_LOCATION
             = "No file or URL supplied for the schema ";
 
-        /** No arg constructor */
-        public SchemaLocation() {
-        }
-
         /**
          * Get the namespace.
          * @return the namespace.
@@ -442,11 +428,8 @@
          */
         public String getURIandLocation() throws BuildException {
             validateNamespace();
-            StringBuffer buffer = new StringBuffer();
-            buffer.append(namespace);
-            buffer.append(' ');
-            buffer.append(getSchemaLocationURL());
-            return new String(buffer);
+            return new StringBuilder(namespace).append(' ')
+                .append(getSchemaLocationURL()).toString();
         }
 
         /**
@@ -465,7 +448,7 @@
          * @return true if it is not null or empty
          */
         private boolean isSet(String property) {
-            return property != null && property.length() != 0;
+            return property != null && !property.isEmpty();
         }
 
         /**
@@ -474,6 +457,7 @@
          * @return true iff the objects are considered equal in value
          */
 
+        @Override
         public boolean equals(Object o) {
             if (this == o) {
                 return true;
@@ -502,6 +486,7 @@
          * Generate a hashcode depending on the namespace, url and file name.
          * @return the hashcode.
          */
+        @Override
         public int hashCode() {
             int result;
             // CheckStyle:MagicNumber OFF
@@ -517,8 +502,9 @@
          * and the like
          * @return a string representation of the object.
          */
+        @Override
         public String toString() {
-            StringBuffer buffer = new StringBuffer();
+            StringBuilder buffer = new StringBuilder();
             buffer.append(namespace != null ? namespace : "(anonymous)");
             buffer.append(' ');
             buffer.append(url != null ? (url + " ") : "");
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/Script.java b/src/main/org/apache/tools/ant/taskdefs/optional/Script.java
index a29347f..72b8f87 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/Script.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/Script.java
@@ -130,4 +130,15 @@
     public void setSetBeans(boolean setBeans) {
         helper.setSetBeans(setBeans);
     }
+
+    /**
+     * Set the encoding of the script from an external file; optional.
+     *
+     * @param encoding the encoding of the file containing the script source.
+     * @since Ant 1.10.2
+     */
+    public void setEncoding(String encoding) {
+        helper.setEncoding(encoding);
+    }
+
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java b/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java
index 569f5ed..71c3f00 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java
@@ -21,13 +21,12 @@
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.reflect.Field;
 import java.net.URL;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -191,8 +190,8 @@
         InputStream fis = null;
         OutputStream fos = null;
         try {
-            fis = new BufferedInputStream(new FileInputStream(infile));
-            fos = new BufferedOutputStream(new FileOutputStream(outfile));
+            fis = new BufferedInputStream(Files.newInputStream(infile.toPath()));
+            fos = new BufferedOutputStream(Files.newOutputStream(outfile.toPath()));
             final StreamResult res = new StreamResult(fos);
             // not sure what could be the need of this...
             res.setSystemId(JAXPUtils.getSystemId(outfile));
@@ -301,17 +300,11 @@
         // and avoid keeping the handle until the object is garbaged.
         // (always keep control), otherwise you won't be able to delete
         // the file quickly on windows.
-        InputStream xslStream = null;
-        try {
-            xslStream
-                = new BufferedInputStream(stylesheet.getInputStream());
+        try (InputStream xslStream =
+             new BufferedInputStream(stylesheet.getInputStream())) {
             templatesModTime = stylesheet.getLastModified();
             final Source src = getSource(xslStream, stylesheet);
             templates = getFactory().newTemplates(src);
-        } finally {
-            if (xslStream != null) {
-                xslStream.close();
-            }
         }
     }
 
@@ -671,8 +664,7 @@
 
     private void applyReflectionHackForExtensionMethods() {
         // Jigsaw doesn't allow reflection to work, so we can stop trying
-        if (JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_1_7)
-            && !JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_9)) {
+        if (!JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_9)) {
             try { // #51668, #52382
                 final Field _isNotSecureProcessing = tfactory.getClass().getDeclaredField("_isNotSecureProcessing");
                 _isNotSecureProcessing.setAccessible(true);
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
index 7b9d3bb..a2d1153 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
@@ -18,8 +18,8 @@
 package org.apache.tools.ant.taskdefs.optional;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
+import java.nio.file.Files;
 import java.util.Vector;
 
 import org.apache.tools.ant.AntClassLoader;
@@ -287,42 +287,40 @@
      */
     public void execute() throws BuildException {
         try {
-        int fileProcessed = 0;
-        if (file == null && (filesets.size() == 0)) {
-            throw new BuildException(
-                "Specify at least one source - " + "a file or a fileset.");
-        }
+            int fileProcessed = 0;
+            if (file == null && (filesets.size() == 0)) {
+                throw new BuildException(
+                    "Specify at least one source - " + "a file or a fileset.");
+            }
 
-
-
-        if (file != null) {
-            if (file.exists() && file.canRead() && file.isFile()) {
-                doValidate(file);
-                fileProcessed++;
-            } else {
-                String errorMsg = "File " + file + " cannot be read";
-                if (failOnError) {
-                    throw new BuildException(errorMsg);
+            if (file != null) {
+                if (file.exists() && file.canRead() && file.isFile()) {
+                    doValidate(file);
+                    fileProcessed++;
                 } else {
-                    log(errorMsg, Project.MSG_ERR);
+                    String errorMsg = "File " + file + " cannot be read";
+                    if (failOnError) {
+                        throw new BuildException(errorMsg);
+                    } else {
+                        log(errorMsg, Project.MSG_ERR);
+                    }
                 }
             }
-        }
 
-        final int size = filesets.size();
-        for (int i = 0; i < size; i++) {
+            final int size = filesets.size();
+            for (int i = 0; i < size; i++) {
 
-            FileSet fs = (FileSet) filesets.elementAt(i);
-            DirectoryScanner ds = fs.getDirectoryScanner(getProject());
-            String[] files = ds.getIncludedFiles();
+                FileSet fs = (FileSet) filesets.elementAt(i);
+                DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+                String[] files = ds.getIncludedFiles();
 
-            for (int j = 0; j < files.length; j++) {
-                File srcFile = new File(fs.getDir(getProject()), files[j]);
-                doValidate(srcFile);
-                fileProcessed++;
+                for (int j = 0; j < files.length; j++) {
+                    File srcFile = new File(fs.getDir(getProject()), files[j]);
+                    doValidate(srcFile);
+                    fileProcessed++;
+                }
             }
-        }
-        onSuccessfulValidation(fileProcessed);
+            onSuccessfulValidation(fileProcessed);
         } finally {
             cleanup();
         }
@@ -552,7 +550,7 @@
         try {
             log("Validating " + afile.getName() + "... ", Project.MSG_VERBOSE);
             errorHandler.init(afile);
-            InputSource is = new InputSource(new FileInputStream(afile));
+            InputSource is = new InputSource(Files.newInputStream(afile.toPath()));
             String uri = FILE_UTILS.toURI(afile.getAbsolutePath());
             is.setSystemId(uri);
             xmlReader.parse(is);
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheck.java b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheck.java
index f6a94b5..a872f48 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheck.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheck.java
@@ -29,12 +29,20 @@
 import org.apache.tools.ant.types.Commandline;
 import org.apache.tools.ant.types.FileSet;
 
-
 /**
  * Class common to all check commands (checkout, checkin,checkin default task);
  * @ant.task ignore="true"
  */
 public class CCMCheck extends Continuus {
+    /**
+     * -comment flag -- comment to attach to the file
+     */
+    public static final String FLAG_COMMENT = "/comment";
+
+    /**
+     *  -task flag -- associate checkout task with task
+     */
+    public static final String FLAG_TASK = "/task";
 
     private File file = null;
     private String comment = null;
@@ -42,15 +50,10 @@
 
     // CheckStyle:VisibilityModifier OFF - bc
 
-    protected Vector filesets = new Vector();
+    protected Vector<FileSet> filesets = new Vector<>();
 
     // CheckStyle:VisibilityModifier ON
 
-    /** Constructor for CCMCheck. */
-    public CCMCheck() {
-        super();
-    }
-
     /**
      * Get the value of file.
      * @return value of file.
@@ -84,7 +87,6 @@
         this.comment = v;
     }
 
-
     /**
      * Get the value of task.
      * @return value of task.
@@ -102,7 +104,6 @@
         this.task = v;
     }
 
-
     /**
      * Adds a set of files to copy.
      * @param set the set of files
@@ -120,9 +121,10 @@
      * </p>
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
 
-        if (file == null && filesets.size() == 0) {
+        if (file == null && filesets.isEmpty()) {
             throw new BuildException(
                 "Specify at least one source - a file or a fileset.");
         }
@@ -131,7 +133,7 @@
             throw new BuildException("CCMCheck cannot be generated for directories");
         }
 
-        if (file != null  && filesets.size() > 0) {
+        if (file != null && !filesets.isEmpty()) {
             throw new BuildException("Choose between file and fileset !");
         }
 
@@ -140,14 +142,11 @@
             return;
         }
 
-        int sizeofFileSet = filesets.size();
-        for (int i = 0; i < sizeofFileSet; i++) {
-            FileSet fs = (FileSet) filesets.elementAt(i);
+        for (FileSet fs : filesets) {
+            final File basedir = fs.getDir(getProject());
             DirectoryScanner ds = fs.getDirectoryScanner(getProject());
-            String[] srcFiles = ds.getIncludedFiles();
-            for (int j = 0; j < srcFiles.length; j++) {
-                File src = new File(fs.getDir(getProject()), srcFiles[j]);
-                setFile(src);
+            for (String srcFile : ds.getIncludedFiles()) {
+                setFile(new File(basedir, srcFile));
                 doit();
             }
         }
@@ -170,12 +169,11 @@
 
         int result = run(commandLine);
         if (Execute.isFailure(result)) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
-
     /**
      * Check the command line options.
      */
@@ -195,14 +193,4 @@
         }
     }
 
-    /**
-     * -comment flag -- comment to attach to the file
-     */
-    public static final String FLAG_COMMENT = "/comment";
-
-    /**
-     *  -task flag -- associate checkout task with task
-     */
-    public static final String FLAG_TASK = "/task";
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckin.java b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckin.java
index ff7472c..3f274d7 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckin.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckin.java
@@ -36,4 +36,3 @@
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckinDefault.java b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckinDefault.java
index 2fe2a2a..8bf9fe1 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckinDefault.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckinDefault.java
@@ -25,14 +25,13 @@
  */
 public class CCMCheckinDefault extends CCMCheck {
 
+    /** The default task */
+    public static final String DEFAULT_TASK = "default";
+
     /** Constructor for CCMCheckinDefault. */
     public CCMCheckinDefault() {
         super();
         setCcmAction(COMMAND_CHECKIN);
         setTask(DEFAULT_TASK);
     }
-
-    /** The default task */
-    public static final String DEFAULT_TASK = "default";
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckout.java b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckout.java
index 44bbc6b..1850cd3 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckout.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckout.java
@@ -32,4 +32,3 @@
         setCcmAction(COMMAND_CHECKOUT);
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCreateTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCreateTask.java
index 7777718..09b39ab 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCreateTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCreateTask.java
@@ -38,6 +38,35 @@
  * @ant.task name="ccmcreatetask" category="scm"
  */
 public class CCMCreateTask extends Continuus implements ExecuteStreamHandler {
+    /**
+     * /comment -- comments associated to the task
+     */
+    public static final String FLAG_COMMENT = "/synopsis";
+
+    /**
+     *  /platform flag -- target platform
+     */
+    public static final String FLAG_PLATFORM = "/plat";
+
+    /**
+     * /resolver flag
+     */
+    public static final String FLAG_RESOLVER = "/resolver";
+
+    /**
+     * /release flag
+     */
+    public static final String FLAG_RELEASE = "/release";
+
+    /**
+     * /release flag
+     */
+    public static final String FLAG_SUBSYSTEM = "/subsystem";
+
+    /**
+     *  -task flag -- associate checkout task with task
+     */
+    public static final String FLAG_TASK = "/task";
 
     private String comment = null;
     private String platform = null;
@@ -63,9 +92,9 @@
      * </p>
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
-        int result = 0;
 
         // build the command line from what we got the format
         // as specified in the CCM.EXE help
@@ -74,10 +103,9 @@
 
         checkOptions(commandLine);
 
-        result = run(commandLine, this);
-        if (Execute.isFailure(result)) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+        if (Execute.isFailure(run(commandLine, this))) {
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
 
         //create task ok, set this task as the default one
@@ -88,15 +116,12 @@
 
         log(commandLine.describeCommand(), Project.MSG_DEBUG);
 
-        result = run(commandLine2);
-        if (result != 0) {
-            String msg = "Failed executing: " + commandLine2.toString();
-            throw new BuildException(msg, getLocation());
+        if (run(commandLine2) != 0) {
+            throw new BuildException("Failed executing: " + commandLine2,
+                getLocation());
         }
-
     }
 
-
     /**
      * Check the command line options.
      */
@@ -127,7 +152,6 @@
         }
     }
 
-
     /**
      * Get the value of comment.
      * @return value of comment.
@@ -145,7 +169,6 @@
         this.comment = v;
     }
 
-
     /**
      * Get the value of platform.
      * @return value of platform.
@@ -163,7 +186,6 @@
         this.platform = v;
     }
 
-
     /**
      * Get the value of resolver.
      * @return value of resolver.
@@ -181,7 +203,6 @@
         this.resolver = v;
     }
 
-
     /**
      * Get the value of release.
      * @return value of release.
@@ -216,7 +237,6 @@
         this.subSystem = v;
     }
 
-
     /**
      * Get the value of task.
      * @return value of task.
@@ -235,71 +255,45 @@
         this.task = v;
     }
 
-    /**
-     * /comment -- comments associated to the task
-     */
-    public static final String FLAG_COMMENT = "/synopsis";
-
-    /**
-     *  /platform flag -- target platform
-     */
-    public static final String FLAG_PLATFORM = "/plat";
-
-    /**
-     * /resolver flag
-     */
-    public static final String FLAG_RESOLVER = "/resolver";
-
-    /**
-     * /release flag
-     */
-    public static final String FLAG_RELEASE = "/release";
-
-    /**
-     * /release flag
-     */
-    public static final String FLAG_SUBSYSTEM = "/subsystem";
-
-    /**
-     *  -task flag -- associate checkout task with task
-     */
-    public static final String FLAG_TASK = "/task";
-
-
     // implementation of org.apache.tools.ant.taskdefs.ExecuteStreamHandler interface
 
     /**
      *
      * @throws IOException on error
      */
+    @Override
     public void start() throws IOException {
     }
 
     /**
      *
      */
+    @Override
     public void stop() {
     }
 
     /**
      *
      * @param param1 the output stream
-     * @exception java.io.IOException on error
+     * @exception IOException on error
      */
+    @Override
     public void setProcessInputStream(OutputStream param1) throws IOException {
     }
 
     /**
      *
      * @param is the input stream
-     * @exception java.io.IOException on error
+     * @exception IOException on error
      */
+    @Override
     public void setProcessErrorStream(InputStream is) throws IOException {
-        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
-        String s = reader.readLine();
-        if (s != null) {
-            log("err " + s, Project.MSG_DEBUG);
-        } // end of if ()
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
+            String s = reader.readLine();
+            if (s != null) {
+                log("err " + s, Project.MSG_DEBUG);
+            }
+        }
     }
 
     /**
@@ -307,12 +301,11 @@
      * @param is InputStream
      * @throws IOException on error
      */
+    @Override
     public void setProcessOutputStream(InputStream is) throws IOException {
-
-        String buffer = "";
-        try {
-            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
-            buffer = reader.readLine();
+        try (BufferedReader reader =
+            new BufferedReader(new InputStreamReader(is))) {
+            String buffer = reader.readLine();
             if (buffer != null) {
                 log("buffer:" + buffer, Project.MSG_DEBUG);
                 String taskstring = buffer.substring(buffer.indexOf(' ')).trim();
@@ -323,7 +316,7 @@
         } catch (NullPointerException npe) {
             log("error procession stream, null pointer exception", Project.MSG_ERR);
             log(StringUtils.getStackTrace(npe), Project.MSG_ERR);
-            throw new BuildException(npe.getClass().getName());
+            throw new BuildException(npe);
         } catch (Exception e) {
             log("error procession stream " + e.getMessage(), Project.MSG_ERR);
             throw new BuildException(e.getMessage());
@@ -332,4 +325,3 @@
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMReconfigure.java b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMReconfigure.java
index 35a0834..15ce99b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMReconfigure.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMReconfigure.java
@@ -28,6 +28,21 @@
  * Task allows to reconfigure a project, recursively or not
  */
 public class CCMReconfigure extends Continuus {
+    /**
+     * /recurse --
+     */
+    public static final String FLAG_RECURSE = "/recurse";
+
+    /**
+     * /recurse --
+     */
+    public static final String FLAG_VERBOSE = "/verbose";
+
+
+    /**
+     *  /project flag -- target project
+     */
+    public static final String FLAG_PROJECT = "/project";
 
     private String ccmProject = null;
     private boolean recurse = false;
@@ -39,7 +54,6 @@
         setCcmAction(COMMAND_RECONFIGURE);
     }
 
-
     /**
      * Executes the task.
      * <p>
@@ -48,9 +62,9 @@
      * </p>
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
-        int result = 0;
 
         // build the command line from what we got the format
         // as specified in the CCM.EXE help
@@ -59,14 +73,13 @@
 
         checkOptions(commandLine);
 
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result)) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
-
     /**
      * Check the command line options.
      */
@@ -103,7 +116,6 @@
         this.ccmProject = v;
     }
 
-
     /**
      * Get the value of recurse.
      * @return value of recurse.
@@ -121,7 +133,6 @@
         this.recurse = v;
     }
 
-
     /**
      * Get the value of verbose.
      * @return value of verbose.
@@ -138,22 +149,4 @@
         this.verbose = v;
     }
 
-
-    /**
-     * /recurse --
-     */
-    public static final String FLAG_RECURSE = "/recurse";
-
-    /**
-     * /recurse --
-     */
-    public static final String FLAG_VERBOSE = "/verbose";
-
-
-    /**
-     *  /project flag -- target project
-     */
-    public static final String FLAG_PROJECT = "/project";
-
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/Continuus.java b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/Continuus.java
index 5618dd6..845c7bf 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ccm/Continuus.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ccm/Continuus.java
@@ -18,6 +18,8 @@
 
 package org.apache.tools.ant.taskdefs.optional.ccm;
 
+import java.io.IOException;
+
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
@@ -39,80 +41,6 @@
  *
  */
 public abstract class Continuus extends Task {
-
-    private String ccmDir = "";
-    private String ccmAction = "";
-
-    /**
-     * Get the value of ccmAction.
-     * @return value of ccmAction.
-     */
-    public String getCcmAction() {
-        return ccmAction;
-    }
-
-    /**
-     * Set the value of ccmAction.
-     * @param v  Value to assign to ccmAction.
-     * @ant.attribute ignore="true"
-     */
-    public void setCcmAction(String v) {
-        this.ccmAction = v;
-    }
-
-
-    /**
-     * Set the directory where the ccm executable is located.
-     *
-     * @param dir the directory containing the ccm executable
-     */
-    public final void setCcmDir(String dir) {
-        ccmDir = FileUtils.translatePath(dir);
-    }
-
-    /**
-     * Builds and returns the command string to execute ccm
-     * @return String containing path to the executable
-     */
-    protected final String getCcmCommand() {
-        String toReturn = ccmDir;
-        if (!toReturn.equals("") && !toReturn.endsWith("/")) {
-            toReturn += "/";
-        }
-
-        toReturn += CCM_EXE;
-
-        return toReturn;
-    }
-
-
-    /**
-     * Run the command.
-     * @param cmd the command line
-     * @param handler an execute stream handler
-     * @return the exit status of the command
-     */
-    protected int run(Commandline cmd, ExecuteStreamHandler handler) {
-        try {
-            Execute exe = new Execute(handler);
-            exe.setAntRun(getProject());
-            exe.setWorkingDirectory(getProject().getBaseDir());
-            exe.setCommandline(cmd.getCommandline());
-            return exe.execute();
-        } catch (java.io.IOException e) {
-            throw new BuildException(e, getLocation());
-        }
-    }
-
-    /**
-     * Run the command.
-     * @param cmd the command line
-     * @return the exit status of the command
-     */
-    protected int run(Commandline cmd) {
-        return run(cmd, new LogStreamHandler(this, Project.MSG_VERBOSE, Project.MSG_WARN));
-    }
-
     /**
      * Constant for the thing to execute
      */
@@ -140,5 +68,75 @@
      */
     public static final String COMMAND_DEFAULT_TASK = "default_task";
 
+    private String ccmDir = "";
+    private String ccmAction = "";
+
+    /**
+     * Get the value of ccmAction.
+     * @return value of ccmAction.
+     */
+    public String getCcmAction() {
+        return ccmAction;
+    }
+
+    /**
+     * Set the value of ccmAction.
+     * @param v  Value to assign to ccmAction.
+     * @ant.attribute ignore="true"
+     */
+    public void setCcmAction(String v) {
+        this.ccmAction = v;
+    }
+
+    /**
+     * Set the directory where the ccm executable is located.
+     *
+     * @param dir the directory containing the ccm executable
+     */
+    public final void setCcmDir(String dir) {
+        ccmDir = FileUtils.translatePath(dir);
+    }
+
+    /**
+     * Builds and returns the command string to execute ccm
+     * @return String containing path to the executable
+     */
+    protected final String getCcmCommand() {
+        String toReturn = ccmDir;
+        if (!("".equals(toReturn) || toReturn.endsWith("/"))) {
+            toReturn += "/";
+        }
+
+        toReturn += CCM_EXE;
+
+        return toReturn;
+    }
+
+    /**
+     * Run the command.
+     * @param cmd the command line
+     * @param handler an execute stream handler
+     * @return the exit status of the command
+     */
+    protected int run(Commandline cmd, ExecuteStreamHandler handler) {
+        try {
+            Execute exe = new Execute(handler);
+            exe.setAntRun(getProject());
+            exe.setWorkingDirectory(getProject().getBaseDir());
+            exe.setCommandline(cmd.getCommandline());
+            return exe.execute();
+        } catch (IOException e) {
+            throw new BuildException(e, getLocation());
+        }
+    }
+
+    /**
+     * Run the command.
+     * @param cmd the command line
+     * @return the exit status of the command
+     */
+    protected int run(Commandline cmd) {
+        return run(cmd, new LogStreamHandler(this, Project.MSG_VERBOSE, Project.MSG_WARN));
+    }
 
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckin.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckin.java
index f7c4a5f..8d2c66c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckin.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckin.java
@@ -79,6 +79,41 @@
  *
  */
 public class CCCheckin extends ClearCase {
+    /**
+     * -c flag -- comment to attach to the file
+     */
+    public static final String FLAG_COMMENT = "-c";
+
+    /**
+     * -cfile flag -- file containing a comment to attach to the file
+     */
+    public static final String FLAG_COMMENTFILE = "-cfile";
+
+    /**
+     * -nc flag -- no comment is specified
+     */
+    public static final String FLAG_NOCOMMENT = "-nc";
+
+    /**
+     * -nwarn flag -- suppresses warning messages
+     */
+    public static final String FLAG_NOWARN = "-nwarn";
+
+    /**
+     * -ptime flag -- preserves the modification time
+     */
+    public static final String FLAG_PRESERVETIME = "-ptime";
+
+    /**
+     * -keep flag -- keeps a copy of the file with a .keep extension
+     */
+    public static final String FLAG_KEEPCOPY = "-keep";
+
+    /**
+     * -identical flag -- allows the file to be checked in even if it is identical to the original
+     */
+    public static final String FLAG_IDENTICAL = "-identical";
+
     private String mComment = null;
     private String mCfile = null;
     private boolean mNwarn = false;
@@ -93,10 +128,10 @@
      * to execute the command line.
      * @throws BuildException if the command fails and failonerr is set to true
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
         Project aProj = getProject();
-        int result = 0;
 
         // Default the viewpath to basedir if it is not specified
         if (getViewPath() == null) {
@@ -115,14 +150,12 @@
             getProject().log("Ignoring any errors that occur for: "
                     + getViewPathBasename(), Project.MSG_VERBOSE);
         }
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result) && getFailOnErr()) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine, getLocation());
         }
     }
 
-
     /**
      * Check the command line options.
      */
@@ -273,7 +306,6 @@
         return mIdentical;
     }
 
-
     /**
      * Get the 'comment' command
      *
@@ -310,35 +342,5 @@
         }
     }
 
-
-        /**
-     * -c flag -- comment to attach to the file
-     */
-    public static final String FLAG_COMMENT = "-c";
-        /**
-     * -cfile flag -- file containing a comment to attach to the file
-     */
-    public static final String FLAG_COMMENTFILE = "-cfile";
-        /**
-     * -nc flag -- no comment is specified
-     */
-    public static final String FLAG_NOCOMMENT = "-nc";
-        /**
-     * -nwarn flag -- suppresses warning messages
-     */
-    public static final String FLAG_NOWARN = "-nwarn";
-        /**
-     * -ptime flag -- preserves the modification time
-     */
-    public static final String FLAG_PRESERVETIME = "-ptime";
-        /**
-     * -keep flag -- keeps a copy of the file with a .keep extension
-     */
-    public static final String FLAG_KEEPCOPY = "-keep";
-        /**
-     * -identical flag -- allows the file to be checked in even if it is identical to the original
-     */
-    public static final String FLAG_IDENTICAL = "-identical";
-
 }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckout.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckout.java
index e60bfc9..795a098 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckout.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckout.java
@@ -95,6 +95,56 @@
  *
  */
 public class CCCheckout extends ClearCase {
+    /**
+     *  -reserved flag -- check out the file as reserved
+     */
+    public static final String FLAG_RESERVED = "-reserved";
+
+    /**
+     *  -reserved flag -- check out the file as unreserved
+     */
+    public static final String FLAG_UNRESERVED = "-unreserved";
+
+    /**
+     * -out flag -- create a writable file under a different filename
+     */
+    public static final String FLAG_OUT = "-out";
+
+    /**
+     * -ndata flag -- checks out the file but does not create an editable file containing its data
+     */
+    public static final String FLAG_NODATA = "-ndata";
+
+    /**
+     * -branch flag -- checks out the file on a specified branch
+     */
+    public static final String FLAG_BRANCH = "-branch";
+
+    /**
+     * -version flag -- allows checkout of a version that is not main latest
+     */
+    public static final String FLAG_VERSION = "-version";
+
+    /**
+     * -nwarn flag -- suppresses warning messages
+     */
+    public static final String FLAG_NOWARN = "-nwarn";
+
+    /**
+     * -c flag -- comment to attach to the file
+     */
+    public static final String FLAG_COMMENT = "-c";
+
+    /**
+     * -cfile flag -- file containing a comment to attach to the file
+     */
+    public static final String FLAG_COMMENTFILE = "-cfile";
+
+    /**
+     * -nc flag -- no comment is specified
+     */
+    public static final String FLAG_NOCOMMENT = "-nc";
+
     private boolean mReserved = true;
     private String mOut = null;
     private boolean mNdata = false;
@@ -112,10 +162,10 @@
      * to execute the command line.
      * @throws BuildException if the command fails and failonerr is set to true
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
         Project aProj = getProject();
-        int result = 0;
 
         // Default the viewpath to basedir if it is not specified
         if (getViewPath() == null) {
@@ -143,10 +193,10 @@
             getProject().log("Ignoring any errors that occur for: "
                     + getViewPathBasename(), Project.MSG_VERBOSE);
         }
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result) && getFailOnErr()) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
@@ -155,7 +205,6 @@
      */
     private boolean lsCheckout() {
         Commandline cmdl = new Commandline();
-        String result;
 
         // build the command line from what we got the format is
         // cleartool lsco [options...] [viewpath ...]
@@ -168,12 +217,11 @@
         // viewpath
         cmdl.createArgument().setValue(getViewPath());
 
-        result = runS(cmdl);
+        String result = runS(cmdl);
 
-        // System.out.println( "lsCheckout: " + result );
-
-        return (result != null && result.length() > 0) ? true : false;
+        return (result != null && result.length() > 0);
     }
+
     /**
      * Check the command line options.
      */
@@ -190,23 +238,17 @@
         if (getOut() != null) {
             // -out
             getOutCommand(cmd);
-        } else {
-            if (getNoData()) {
-                // -ndata
-                cmd.createArgument().setValue(FLAG_NODATA);
-            }
-
+        } else if (getNoData()) {
+            // -ndata
+            cmd.createArgument().setValue(FLAG_NODATA);
         }
 
         if (getBranch() != null) {
             // -branch
             getBranchCommand(cmd);
-        } else {
-            if (getVersion()) {
-                // -version
-                cmd.createArgument().setValue(FLAG_VERSION);
-            }
-
+        } else if (getVersion()) {
+            // -version
+            cmd.createArgument().setValue(FLAG_VERSION);
         }
 
         if (getNoWarn()) {
@@ -217,20 +259,15 @@
         if (getComment() != null) {
             // -c
             getCommentCommand(cmd);
+        } else if (getCommentFile() != null) {
+            // -cfile
+            getCommentFileCommand(cmd);
         } else {
-            if (getCommentFile() != null) {
-                // -cfile
-                getCommentFileCommand(cmd);
-            } else {
-                cmd.createArgument().setValue(FLAG_NOCOMMENT);
-            }
+            cmd.createArgument().setValue(FLAG_NOCOMMENT);
         }
 
         // viewpath
         cmd.createArgument().setValue(getViewPath());
-
-        // Print out info about the notco option
-        // System.out.println( "Notco: " + (getNotco() ? "yes" : "no") );
     }
 
     /**
@@ -271,7 +308,6 @@
         return mNotco;
     }
 
-
     /**
      * Creates a writable file under a different filename.
      *
@@ -435,7 +471,6 @@
         }
     }
 
-
     /**
      * Get the 'comment' command
      *
@@ -472,46 +507,5 @@
         }
     }
 
-        /**
-     *  -reserved flag -- check out the file as reserved
-     */
-    public static final String FLAG_RESERVED = "-reserved";
-        /**
-     *  -reserved flag -- check out the file as unreserved
-     */
-    public static final String FLAG_UNRESERVED = "-unreserved";
-        /**
-     * -out flag -- create a writable file under a different filename
-     */
-    public static final String FLAG_OUT = "-out";
-        /**
-     * -ndata flag -- checks out the file but does not create an editable file containing its data
-     */
-    public static final String FLAG_NODATA = "-ndata";
-        /**
-     * -branch flag -- checks out the file on a specified branch
-     */
-    public static final String FLAG_BRANCH = "-branch";
-        /**
-     * -version flag -- allows checkout of a version that is not main latest
-     */
-    public static final String FLAG_VERSION = "-version";
-        /**
-     * -nwarn flag -- suppresses warning messages
-     */
-    public static final String FLAG_NOWARN = "-nwarn";
-        /**
-     * -c flag -- comment to attach to the file
-     */
-    public static final String FLAG_COMMENT = "-c";
-        /**
-     * -cfile flag -- file containing a comment to attach to the file
-     */
-    public static final String FLAG_COMMENTFILE = "-cfile";
-        /**
-     * -nc flag -- no comment is specified
-     */
-    public static final String FLAG_NOCOMMENT = "-nc";
-
 }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCLock.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCLock.java
index ba7def7..6e6cb0d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCLock.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCLock.java
@@ -18,19 +18,19 @@
 
 package org.apache.tools.ant.taskdefs.optional.clearcase;
 
+import java.util.Optional;
+
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.taskdefs.Execute;
 import org.apache.tools.ant.types.Commandline;
 
 
-/**
+/*
  * TODO:
  * comment field doesn't include all options yet
  */
 
-
-
 /**
  * Performs a ClearCase Lock command.
  *
@@ -86,6 +86,31 @@
  *
  */
 public class CCLock extends ClearCase {
+    /**
+     *  -replace flag -- replace existing lock on object(s)
+     */
+    public static final String FLAG_REPLACE = "-replace";
+
+    /**
+     * -nusers flag -- list of users to exclude from lock
+     */
+    public static final String FLAG_NUSERS = "-nusers";
+
+    /**
+     * -obsolete flag -- mark locked object as obsolete
+     */
+    public static final String FLAG_OBSOLETE = "-obsolete";
+
+    /**
+     * -comment flag -- method to use for commenting events
+     */
+    public static final String FLAG_COMMENT = "-comment";
+
+    /**
+     * -pname flag -- pathname to lock
+     */
+    public static final String FLAG_PNAME = "-pname";
+
     private boolean mReplace = false;
     private boolean mObsolete = false;
     private String mComment = null;
@@ -100,10 +125,10 @@
      * to execute the command line.
      * @throws BuildException if the command fails and failonerr is set to true
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
         Project aProj = getProject();
-        int result = 0;
 
         // Default the viewpath to basedir if it is not specified
         if (getViewPath() == null) {
@@ -126,17 +151,17 @@
             getProject().log("Ignoring any errors that occur for: "
                     + getOpType(), Project.MSG_VERBOSE);
         }
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result) && getFailOnErr()) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
     /**
      * Check the command line options.
      */
-private void checkOptions(Commandline cmd) {
+    private void checkOptions(Commandline cmd) {
         // ClearCase items
         if (getReplace()) {
             // -replace
@@ -151,15 +176,15 @@
         getCommentCommand(cmd);
 
         if (getObjselect() == null && getPname() == null) {
-            throw new BuildException("Should select either an element "
-            + "(pname) or an object (objselect)");
+            throw new BuildException(
+                "Should select either an element (pname) or an object (objselect)");
         }
         getPnameCommand(cmd);
         // object selector
         if (getObjselect() != null) {
             cmd.createArgument().setValue(getObjselect());
         }
-}
+    }
 
     /**
      * If true, replace an existing lock.
@@ -290,15 +315,14 @@
     private void getNusersCommand(Commandline cmd) {
         if (getNusers() == null) {
             return;
-        } else {
-            /* Had to make two separate commands here because if a space is
-               inserted between the flag and the value, it is treated as a
-               Windows filename with a space and it is enclosed in double
-               quotes ("). This breaks clearcase.
-            */
-            cmd.createArgument().setValue(FLAG_NUSERS);
-            cmd.createArgument().setValue(getNusers());
         }
+        /* Had to make two separate commands here because if a space is
+           inserted between the flag and the value, it is treated as a
+           Windows filename with a space and it is enclosed in double
+           quotes ("). This breaks clearcase.
+        */
+        cmd.createArgument().setValue(FLAG_NUSERS);
+        cmd.createArgument().setValue(getNusers());
     }
 
     /**
@@ -310,15 +334,14 @@
     private void getCommentCommand(Commandline cmd) {
         if (getComment() == null) {
             return;
-        } else {
-            /* Had to make two separate commands here because if a space is
-               inserted between the flag and the value, it is treated as a
-               Windows filename with a space and it is enclosed in double
-               quotes ("). This breaks clearcase.
-            */
-            cmd.createArgument().setValue(FLAG_COMMENT);
-            cmd.createArgument().setValue(getComment());
         }
+        /* Had to make two separate commands here because if a space is
+           inserted between the flag and the value, it is treated as a
+           Windows filename with a space and it is enclosed in double
+           quotes ("). This breaks clearcase.
+        */
+        cmd.createArgument().setValue(FLAG_COMMENT);
+        cmd.createArgument().setValue(getComment());
     }
 
     /**
@@ -330,15 +353,14 @@
     private void getPnameCommand(Commandline cmd) {
         if (getPname() == null) {
             return;
-        } else {
-            /* Had to make two separate commands here because if a space is
-               inserted between the flag and the value, it is treated as a
-               Windows filename with a space and it is enclosed in double
-               quotes ("). This breaks clearcase.
-            */
-            cmd.createArgument().setValue(FLAG_PNAME);
-            cmd.createArgument().setValue(getPname());
         }
+        /* Had to make two separate commands here because if a space is
+           inserted between the flag and the value, it is treated as a
+           Windows filename with a space and it is enclosed in double
+           quotes ("). This breaks clearcase.
+        */
+        cmd.createArgument().setValue(FLAG_PNAME);
+        cmd.createArgument().setValue(getPname());
     }
 
     /**
@@ -347,33 +369,7 @@
      * @return String containing the object/pname being worked on
      */
     private String getOpType() {
-
-        if (getPname() != null) {
-            return getPname();
-        } else {
-            return getObjselect();
-        }
+        return Optional.ofNullable(getPname()).orElseGet(this::getObjselect);
     }
 
-    /**
-     *  -replace flag -- replace existing lock on object(s)
-     */
-    public static final String FLAG_REPLACE = "-replace";
-    /**
-     * -nusers flag -- list of users to exclude from lock
-     */
-    public static final String FLAG_NUSERS = "-nusers";
-    /**
-     * -obsolete flag -- mark locked object as obsolete
-     */
-    public static final String FLAG_OBSOLETE = "-obsolete";
-    /**
-     * -comment flag -- method to use for commenting events
-     */
-    public static final String FLAG_COMMENT = "-comment";
-    /**
-     * -pname flag -- pathname to lock
-     */
-    public static final String FLAG_PNAME = "-pname";
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkattr.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkattr.java
index 89b55f9..b83e162 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkattr.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkattr.java
@@ -84,6 +84,31 @@
  *
  */
 public class CCMkattr extends ClearCase {
+    /**
+     * -replace flag -- replace the existing value of the attribute
+     */
+    public static final String FLAG_REPLACE = "-replace";
+    /**
+     * -recurse flag -- process all subdirectories
+     */
+    public static final String FLAG_RECURSE = "-recurse";
+    /**
+     * -version flag -- attach attribute to specified version
+     */
+    public static final String FLAG_VERSION = "-version";
+    /**
+     * -c flag -- comment to attach to the element
+     */
+    public static final String FLAG_COMMENT = "-c";
+    /**
+     * -cfile flag -- file containing a comment to attach to the file
+     */
+    public static final String FLAG_COMMENTFILE = "-cfile";
+    /**
+     * -nc flag -- no comment is specified
+     */
+    public static final String FLAG_NOCOMMENT = "-nc";
+
     private boolean mReplace = false;
     private boolean mRecurse = false;
     private String mVersion = null;
@@ -99,10 +124,10 @@
      * to execute the command line.
      * @throws BuildException if the command fails and failonerr is set to true
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
         Project aProj = getProject();
-        int result = 0;
 
         // Check for required attributes
         if (getTypeName() == null) {
@@ -132,10 +157,10 @@
         // For debugging
         // System.out.println(commandLine.toString());
 
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result) && getFailOnErr()) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
@@ -162,13 +187,11 @@
         if (getComment() != null) {
             // -c
             getCommentCommand(cmd);
+        } else if (getCommentFile() != null) {
+            // -cfile
+            getCommentFileCommand(cmd);
         } else {
-            if (getCommentFile() != null) {
-                // -cfile
-                getCommentFileCommand(cmd);
-            } else {
-                cmd.createArgument().setValue(FLAG_NOCOMMENT);
-            }
+            cmd.createArgument().setValue(FLAG_NOCOMMENT);
         }
 
         if (getTypeName() != null) {
@@ -183,7 +206,6 @@
         cmd.createArgument().setValue(getViewPath());
     }
 
-
     /**
      * Set the replace flag
      *
@@ -310,7 +332,6 @@
         return mTypeValue;
     }
 
-
     /**
      * Get the 'version' command
      *
@@ -398,29 +419,4 @@
         }
     }
 
-    /**
-     * -replace flag -- replace the existing value of the attribute
-     */
-    public static final String FLAG_REPLACE = "-replace";
-    /**
-     * -recurse flag -- process all subdirectories
-     */
-    public static final String FLAG_RECURSE = "-recurse";
-    /**
-     * -version flag -- attach attribute to specified version
-     */
-    public static final String FLAG_VERSION = "-version";
-    /**
-     * -c flag -- comment to attach to the element
-     */
-    public static final String FLAG_COMMENT = "-c";
-    /**
-     * -cfile flag -- file containing a comment to attach to the file
-     */
-    public static final String FLAG_COMMENTFILE = "-cfile";
-    /**
-     * -nc flag -- no comment is specified
-     */
-    public static final String FLAG_NOCOMMENT = "-nc";
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkbl.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkbl.java
index ac0f42b..bd597b1 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkbl.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkbl.java
@@ -81,6 +81,36 @@
  *
  */
 public class CCMkbl extends ClearCase {
+
+    /**
+     * -c flag -- comment to attach to the file
+     */
+    public static final String FLAG_COMMENT = "-c";
+    /**
+     * -cfile flag -- file containing a comment to attach to the file
+     */
+    public static final String FLAG_COMMENTFILE = "-cfile";
+    /**
+     * -nc flag -- no comment is specified
+     */
+    public static final String FLAG_NOCOMMENT = "-nc";
+    /**
+     * -identical flag -- allows the file to be checked in even if it is identical to the original
+     */
+    public static final String FLAG_IDENTICAL = "-identical";
+    /**
+     * -incremental flag -- baseline to be created is incremental
+     */
+    public static final String FLAG_INCREMENTAL = "-incremental";
+    /**
+     * -full flag -- baseline to be created is full
+     */
+    public static final String FLAG_FULL = "-full";
+    /**
+     * -nlabel -- baseline to be created without a label
+     */
+    public static final String FLAG_NLABEL = "-nlabel";
+
     private String mComment = null;
     private String mCfile = null;
     private String mBaselineRootName = null;
@@ -89,7 +119,6 @@
     private boolean mFull = false;
     private boolean mNlabel = false;
 
-
     /**
      * Executes the task.
      * <p>
@@ -97,10 +126,10 @@
      * to execute the command line.
      * @throws BuildException if the command fails and failonerr is set to true
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
         Project aProj = getProject();
-        int result = 0;
 
         // Default the viewpath to basedir if it is not specified
         if (getViewPath() == null) {
@@ -119,14 +148,13 @@
             getProject().log("Ignoring any errors that occur for: "
                     + getBaselineRootName(), Project.MSG_VERBOSE);
         }
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result) && getFailOnErr()) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
-
     /**
      * Check the command line options.
      */
@@ -134,13 +162,11 @@
         if (getComment() != null) {
             // -c
             getCommentCommand(cmd);
+        } else if (getCommentFile() != null) {
+            // -cfile
+            getCommentFileCommand(cmd);
         } else {
-            if (getCommentFile() != null) {
-                // -cfile
-                getCommentFileCommand(cmd);
-            } else {
-                cmd.createArgument().setValue(FLAG_NOCOMMENT);
-            }
+            cmd.createArgument().setValue(FLAG_NOCOMMENT);
         }
 
         if (getIdentical()) {
@@ -163,10 +189,8 @@
 
        // baseline_root_name
         cmd.createArgument().setValue(getBaselineRootName());
-
     }
 
-
     /**
      * Set comment string
      *
@@ -222,8 +246,6 @@
     }
 
     /**
-
-    /**
      * Set the nowarn flag
      *
      * @param nwarn the status to set the flag to
@@ -295,7 +317,6 @@
         return mNlabel;
     }
 
-
     /**
      * Get the 'comment' command
      *
@@ -332,35 +353,4 @@
         }
     }
 
-
-        /**
-     * -c flag -- comment to attach to the file
-     */
-    public static final String FLAG_COMMENT = "-c";
-        /**
-     * -cfile flag -- file containing a comment to attach to the file
-     */
-    public static final String FLAG_COMMENTFILE = "-cfile";
-        /**
-     * -nc flag -- no comment is specified
-     */
-    public static final String FLAG_NOCOMMENT = "-nc";
-        /**
-     * -identical flag -- allows the file to be checked in even if it is identical to the original
-     */
-    public static final String FLAG_IDENTICAL = "-identical";
-       /**
-     * -incremental flag -- baseline to be created is incremental
-     */
-    public static final String FLAG_INCREMENTAL = "-incremental";
-       /**
-     * -full flag -- baseline to be created is full
-     */
-    public static final String FLAG_FULL = "-full";
-       /**
-     * -nlabel -- baseline to be created without a label
-     */
-    public static final String FLAG_NLABEL = "-nlabel";
-
-
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkdir.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkdir.java
index 441ff52..c37e82c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkdir.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkdir.java
@@ -64,6 +64,23 @@
  *
  */
 public class CCMkdir extends ClearCase {
+    /**
+     * -c flag -- comment to attach to the directory
+     */
+    public static final String FLAG_COMMENT = "-c";
+    /**
+     * -cfile flag -- file containing a comment to attach to the directory
+     */
+    public static final String FLAG_COMMENTFILE = "-cfile";
+    /**
+     * -nc flag -- no comment is specified
+     */
+    public static final String FLAG_NOCOMMENT = "-nc";
+    /**
+     * -nco flag -- do not checkout element after creation
+     */
+    public static final String FLAG_NOCHECKOUT = "-nco";
+
     private String  mComment = null;
     private String  mCfile   = null;
     private boolean mNoco    = false;
@@ -75,10 +92,10 @@
      * to execute the command line.
      * @throws BuildException if the command fails and failonerr is set to true
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
         Project aProj = getProject();
-        int result = 0;
 
         // Default the viewpath to basedir if it is not specified
         if (getViewPath() == null) {
@@ -97,10 +114,10 @@
             getProject().log("Ignoring any errors that occur for: "
                     + getViewPathBasename(), Project.MSG_VERBOSE);
         }
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result) && getFailOnErr()) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
@@ -111,13 +128,11 @@
         if (getComment() != null) {
             // -c
             getCommentCommand(cmd);
+        } else if (getCommentFile() != null) {
+            // -cfile
+            getCommentFileCommand(cmd);
         } else {
-            if (getCommentFile() != null) {
-                // -cfile
-                getCommentFileCommand(cmd);
-            } else {
-                cmd.createArgument().setValue(FLAG_NOCOMMENT);
-            }
+            cmd.createArgument().setValue(FLAG_NOCOMMENT);
         }
         if (getNoCheckout()) {
             // -nco
@@ -181,7 +196,6 @@
         return mNoco;
     }
 
-
     /**
      * Get the 'comment' command
      *
@@ -218,21 +232,4 @@
         }
     }
 
-    /**
-     * -c flag -- comment to attach to the directory
-     */
-    public static final String FLAG_COMMENT = "-c";
-    /**
-     * -cfile flag -- file containing a comment to attach to the directory
-     */
-    public static final String FLAG_COMMENTFILE = "-cfile";
-    /**
-     * -nc flag -- no comment is specified
-     */
-    public static final String FLAG_NOCOMMENT = "-nc";
-    /**
-     * -nco flag -- do not checkout element after creation
-     */
-    public static final String FLAG_NOCHECKOUT = "-nco";
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkelem.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkelem.java
index 53d2f0b..bdab620 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkelem.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkelem.java
@@ -89,6 +89,43 @@
  *
  */
 public class CCMkelem extends ClearCase {
+    /**
+     * -c flag -- comment to attach to the file
+     */
+    public static final String FLAG_COMMENT = "-c";
+    /**
+     * -cfile flag -- file containing a comment to attach to the file
+     */
+    public static final String FLAG_COMMENTFILE = "-cfile";
+    /**
+     * -nc flag -- no comment is specified
+     */
+    public static final String FLAG_NOCOMMENT = "-nc";
+    /**
+     * -nwarn flag -- suppresses warning messages
+     */
+    public static final String FLAG_NOWARN = "-nwarn";
+    /**
+     * -ptime flag -- preserves the modification time on checkin
+     */
+    public static final String FLAG_PRESERVETIME = "-ptime";
+    /**
+     * -nco flag -- do not checkout element after creation
+     */
+    public static final String FLAG_NOCHECKOUT = "-nco";
+    /**
+     * -ci flag -- checkin element after creation
+     */
+    public static final String FLAG_CHECKIN = "-ci";
+    /**
+     * -master flag -- change mastership of main branch to current site
+     */
+    public static final String FLAG_MASTER = "-master";
+    /**
+     * -eltype flag -- element type to use during creation
+     */
+    public static final String FLAG_ELTYPE = "-eltype";
+
     private String  mComment = null;
     private String  mCfile   = null;
     private boolean mNwarn   = false;
@@ -105,10 +142,10 @@
      * to execute the command line.
      * @throws BuildException if the command fails and failonerr is set to true
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
         Project aProj = getProject();
-        int result = 0;
 
         // Default the viewpath to basedir if it is not specified
         if (getViewPath() == null) {
@@ -127,14 +164,13 @@
             getProject().log("Ignoring any errors that occur for: "
                     + getViewPathBasename(), Project.MSG_VERBOSE);
         }
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result) && getFailOnErr()) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
-
     /**
      * Check the command line options.
      */
@@ -142,13 +178,11 @@
         if (getComment() != null) {
             // -c
             getCommentCommand(cmd);
+        } else if (getCommentFile() != null) {
+            // -cfile
+            getCommentFileCommand(cmd);
         } else {
-            if (getCommentFile() != null) {
-                // -cfile
-                getCommentFileCommand(cmd);
-            } else {
-                cmd.createArgument().setValue(FLAG_NOCOMMENT);
-            }
+            cmd.createArgument().setValue(FLAG_NOCOMMENT);
         }
 
         if (getNoWarn()) {
@@ -330,7 +364,6 @@
         return mEltype;
     }
 
-
     /**
      * Get the 'comment' command
      *
@@ -385,41 +418,4 @@
         }
     }
 
-    /**
-     * -c flag -- comment to attach to the file
-     */
-    public static final String FLAG_COMMENT = "-c";
-    /**
-     * -cfile flag -- file containing a comment to attach to the file
-     */
-    public static final String FLAG_COMMENTFILE = "-cfile";
-    /**
-     * -nc flag -- no comment is specified
-     */
-    public static final String FLAG_NOCOMMENT = "-nc";
-    /**
-     * -nwarn flag -- suppresses warning messages
-     */
-    public static final String FLAG_NOWARN = "-nwarn";
-    /**
-     * -ptime flag -- preserves the modification time on checkin
-     */
-    public static final String FLAG_PRESERVETIME = "-ptime";
-    /**
-     * -nco flag -- do not checkout element after creation
-     */
-    public static final String FLAG_NOCHECKOUT = "-nco";
-    /**
-     * -ci flag -- checkin element after creation
-     */
-    public static final String FLAG_CHECKIN = "-ci";
-    /**
-     * -master flag -- change mastership of main branch to current site
-     */
-    public static final String FLAG_MASTER = "-master";
-    /**
-     * -eltype flag -- element type to use during creation
-     */
-    public static final String FLAG_ELTYPE = "-eltype";
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklabel.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklabel.java
index b1a9686..d873e90 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklabel.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklabel.java
@@ -83,6 +83,31 @@
  *
  */
 public class CCMklabel extends ClearCase {
+    /**
+     * -replace flag -- replace another label of the same type
+     */
+    public static final String FLAG_REPLACE = "-replace";
+    /**
+     * -recurse flag -- process all subdirectories
+     */
+    public static final String FLAG_RECURSE = "-recurse";
+    /**
+     * -version flag -- attach label to specified version
+     */
+    public static final String FLAG_VERSION = "-version";
+    /**
+     * -c flag -- comment to attach to the file
+     */
+    public static final String FLAG_COMMENT = "-c";
+    /**
+     * -cfile flag -- file containing a comment to attach to the file
+     */
+    public static final String FLAG_COMMENTFILE = "-cfile";
+    /**
+     * -nc flag -- no comment is specified
+     */
+    public static final String FLAG_NOCOMMENT = "-nc";
+
     private boolean mReplace = false;
     private boolean mRecurse = false;
     private String mVersion = null;
@@ -98,10 +123,10 @@
      * to execute the command line.
      * @throws BuildException if the command fails and failonerr is set to true
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
         Project aProj = getProject();
-        int result = 0;
 
         // Check for required attributes
         if (getTypeName() == null) {
@@ -125,10 +150,10 @@
             getProject().log("Ignoring any errors that occur for: "
                     + getViewPathBasename(), Project.MSG_VERBOSE);
         }
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result) && getFailOnErr()) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
@@ -155,13 +180,11 @@
         if (getComment() != null) {
             // -c
             getCommentCommand(cmd);
+        } else if (getCommentFile() != null) {
+            // -cfile
+            getCommentFileCommand(cmd);
         } else {
-            if (getCommentFile() != null) {
-                // -cfile
-                getCommentFileCommand(cmd);
-            } else {
-                cmd.createArgument().setValue(FLAG_NOCOMMENT);
-            }
+            cmd.createArgument().setValue(FLAG_NOCOMMENT);
         }
 
         if (getTypeName() != null) {
@@ -173,7 +196,6 @@
         cmd.createArgument().setValue(getViewPath());
     }
 
-
     /**
      * Set the replace flag
      *
@@ -300,7 +322,6 @@
         return mVOB;
     }
 
-
     /**
      * Get the 'version' command
      *
@@ -362,10 +383,9 @@
      *        without the type-name
      */
     private void getTypeCommand(Commandline cmd) {
-        String typenm = null;
 
         if (getTypeName() != null) {
-            typenm = getTypeName();
+            String typenm = getTypeName();
             if (getVOB() != null) {
                 typenm += "@" + getVOB();
             }
@@ -373,31 +393,4 @@
         }
     }
 
-
-    /**
-     * -replace flag -- replace another label of the same type
-     */
-    public static final String FLAG_REPLACE = "-replace";
-    /**
-     * -recurse flag -- process all subdirectories
-     */
-    public static final String FLAG_RECURSE = "-recurse";
-    /**
-     * -version flag -- attach label to specified version
-     */
-    public static final String FLAG_VERSION = "-version";
-    /**
-     * -c flag -- comment to attach to the file
-     */
-    public static final String FLAG_COMMENT = "-c";
-    /**
-     * -cfile flag -- file containing a comment to attach to the file
-     */
-    public static final String FLAG_COMMENTFILE = "-cfile";
-    /**
-     * -nc flag -- no comment is specified
-     */
-    public static final String FLAG_NOCOMMENT = "-nc";
-
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklbtype.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklbtype.java
index 04db9cd..eb07458 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklbtype.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklbtype.java
@@ -95,6 +95,39 @@
  *
  */
 public class CCMklbtype extends ClearCase {
+    /**
+     * -replace flag -- replace existing label definition of the same type
+     */
+    public static final String FLAG_REPLACE = "-replace";
+    /**
+     * -global flag -- creates a label type that is global to the VOB or to VOBs that use this VOB
+     */
+    public static final String FLAG_GLOBAL = "-global";
+    /**
+     * -ordinary flag -- creates a label type that can be used only in the current VOB
+     */
+    public static final String FLAG_ORDINARY = "-ordinary";
+    /**
+     * -pbranch flag -- allows label type to be used once per branch
+     */
+    public static final String FLAG_PBRANCH = "-pbranch";
+    /**
+     * -shared flag -- sets the way mastership is checked by ClearCase
+     */
+    public static final String FLAG_SHARED = "-shared";
+    /**
+     * -c flag -- comment to attach to the file
+     */
+    public static final String FLAG_COMMENT = "-c";
+    /**
+     * -cfile flag -- file containing a comment to attach to the file
+     */
+    public static final String FLAG_COMMENTFILE = "-cfile";
+    /**
+     * -nc flag -- no comment is specified
+     */
+    public static final String FLAG_NOCOMMENT = "-nc";
+
     private String mTypeName = null;
     private String mVOB = null;
     private String mComment = null;
@@ -112,9 +145,9 @@
      * to execute the command line.
      * @throws BuildException if the command fails and failonerr is set to true
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
-        int result = 0;
 
         // Check for required attributes
         if (getTypeName() == null) {
@@ -133,14 +166,13 @@
             getProject().log("Ignoring any errors that occur for: "
                     + getTypeSpecifier(), Project.MSG_VERBOSE);
         }
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result) && getFailOnErr()) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
-
     /**
      * Check the command line options.
      */
@@ -153,11 +185,9 @@
         if (getOrdinary()) {
             // -ordinary
             cmd.createArgument().setValue(FLAG_ORDINARY);
-        } else {
-            if (getGlobal()) {
-                // -global
-                cmd.createArgument().setValue(FLAG_GLOBAL);
-            }
+        } else if (getGlobal()) {
+            // -global
+            cmd.createArgument().setValue(FLAG_GLOBAL);
         }
 
         if (getPbranch()) {
@@ -173,20 +203,17 @@
         if (getComment() != null) {
             // -c
             getCommentCommand(cmd);
+        } else if (getCommentFile() != null) {
+            // -cfile
+            getCommentFileCommand(cmd);
         } else {
-            if (getCommentFile() != null) {
-                // -cfile
-                getCommentFileCommand(cmd);
-            } else {
-                cmd.createArgument().setValue(FLAG_NOCOMMENT);
-            }
+            cmd.createArgument().setValue(FLAG_NOCOMMENT);
         }
 
         // type-name@vob
         cmd.createArgument().setValue(getTypeSpecifier());
     }
 
-
     /**
      * Set type-name string
      *
@@ -349,7 +376,6 @@
         return mCfile;
     }
 
-
     /**
      * Get the 'comment' command
      *
@@ -393,49 +419,11 @@
      *         specified, otherwise an empty string
      */
     private String getTypeSpecifier() {
-        String typenm = null;
-
-        typenm = getTypeName();
+        String typenm = getTypeName();
         if (getVOB() != null) {
             typenm += "@" + getVOB();
         }
-
         return typenm;
     }
 
-
-    /**
-     * -replace flag -- replace existing label definition of the same type
-     */
-    public static final String FLAG_REPLACE = "-replace";
-    /**
-     * -global flag -- creates a label type that is global to the VOB or to VOBs that use this VOB
-     */
-    public static final String FLAG_GLOBAL = "-global";
-    /**
-     * -ordinary flag -- creates a label type that can be used only in the current VOB
-     */
-    public static final String FLAG_ORDINARY = "-ordinary";
-    /**
-     * -pbranch flag -- allows label type to be used once per branch
-     */
-    public static final String FLAG_PBRANCH = "-pbranch";
-    /**
-     * -shared flag -- sets the way mastership is checked by ClearCase
-     */
-    public static final String FLAG_SHARED = "-shared";
-    /**
-     * -c flag -- comment to attach to the file
-     */
-    public static final String FLAG_COMMENT = "-c";
-    /**
-     * -cfile flag -- file containing a comment to attach to the file
-     */
-    public static final String FLAG_COMMENTFILE = "-cfile";
-    /**
-     * -nc flag -- no comment is specified
-     */
-    public static final String FLAG_NOCOMMENT = "-nc";
-
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCRmtype.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCRmtype.java
index 82a9e63..1cf0804 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCRmtype.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCRmtype.java
@@ -87,6 +87,31 @@
  *
  */
 public class CCRmtype extends ClearCase {
+    /**
+     * -ignore flag -- ignore pre-trigger operations when removing a trigger type
+     */
+    public static final String FLAG_IGNORE = "-ignore";
+    /**
+     * -rmall flag -- removes all instances of a type and the type object itself
+     */
+    public static final String FLAG_RMALL = "-rmall";
+    /**
+     * -force flag -- suppresses confirmation prompts
+     */
+    public static final String FLAG_FORCE = "-force";
+    /**
+     * -c flag -- comment to attach to the file
+     */
+    public static final String FLAG_COMMENT = "-c";
+    /**
+     * -cfile flag -- file containing a comment to attach to the file
+     */
+    public static final String FLAG_COMMENTFILE = "-cfile";
+    /**
+     * -nc flag -- no comment is specified
+     */
+    public static final String FLAG_NOCOMMENT = "-nc";
+
     private String mTypeKind = null;
     private String mTypeName = null;
     private String mVOB = null;
@@ -102,9 +127,9 @@
      * to execute the command line.
      * @throws BuildException if the command fails and failonerr is set to true
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
-        int result = 0;
 
         // Check for required attributes
         if (getTypeKind() == null) {
@@ -126,14 +151,13 @@
             getProject().log("Ignoring any errors that occur for: "
                     + getTypeSpecifier(), Project.MSG_VERBOSE);
         }
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result) && getFailOnErr()) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
-
     /**
      * Check the command line options.
      */
@@ -150,13 +174,11 @@
         if (getComment() != null) {
             // -c
             getCommentCommand(cmd);
+        } else if (getCommentFile() != null) {
+            // -cfile
+            getCommentFileCommand(cmd);
         } else {
-            if (getCommentFile() != null) {
-                // -cfile
-                getCommentFileCommand(cmd);
-            } else {
-                cmd.createArgument().setValue(FLAG_NOCOMMENT);
-            }
+            cmd.createArgument().setValue(FLAG_NOCOMMENT);
         }
 
         // type-kind:type-name
@@ -298,10 +320,9 @@
     private String getTypeSpecifier() {
         String tkind = getTypeKind();
         String tname = getTypeName();
-        String typeSpec = null;
 
         // Return the type-selector
-        typeSpec = tkind + ":" + tname;
+        String typeSpec = tkind + ":" + tname;
         if (getVOB() != null) {
             typeSpec += "@" + getVOB();
         }
@@ -344,31 +365,4 @@
         }
     }
 
-
-    /**
-     * -ignore flag -- ignore pre-trigger operations when removing a trigger type
-     */
-    public static final String FLAG_IGNORE = "-ignore";
-    /**
-     * -rmall flag -- removes all instances of a type and the type object itself
-     */
-    public static final String FLAG_RMALL = "-rmall";
-    /**
-     * -force flag -- suppresses confirmation prompts
-     */
-    public static final String FLAG_FORCE = "-force";
-    /**
-     * -c flag -- comment to attach to the file
-     */
-    public static final String FLAG_COMMENT = "-c";
-    /**
-     * -cfile flag -- file containing a comment to attach to the file
-     */
-    public static final String FLAG_COMMENTFILE = "-cfile";
-    /**
-     * -nc flag -- no comment is specified
-     */
-    public static final String FLAG_NOCOMMENT = "-nc";
-
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnCheckout.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnCheckout.java
index 6d7e488..b7ee573 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnCheckout.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnCheckout.java
@@ -54,6 +54,15 @@
  *
  */
 public class CCUnCheckout extends ClearCase {
+    /**
+     *  -keep flag -- keep a copy of the file with .keep extension
+     */
+    public static final String FLAG_KEEPCOPY = "-keep";
+    /**
+     *  -rm flag -- remove the copy of the file
+     */
+    public static final String FLAG_RM = "-rm";
+
     private boolean mKeep = false;
 
     /**
@@ -63,10 +72,10 @@
      * to execute the command line.
      * @throws BuildException if the command fails and failonerr is set to true
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
         Project aProj = getProject();
-        int result = 0;
 
         // Default the viewpath to basedir if it is not specified
         if (getViewPath() == null) {
@@ -85,14 +94,13 @@
             getProject().log("Ignoring any errors that occur for: "
                     + getViewPathBasename(), Project.MSG_VERBOSE);
         }
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result) && getFailOnErr()) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
-
     /**
      * Check the command line options.
      */
@@ -128,15 +136,4 @@
         return mKeep;
     }
 
-
-    /**
-     *  -keep flag -- keep a copy of the file with .keep extension
-     */
-    public static final String FLAG_KEEPCOPY = "-keep";
-    /**
-     *  -rm flag -- remove the copy of the file
-     */
-    public static final String FLAG_RM = "-rm";
-
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnlock.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnlock.java
index 7d72726..4da01f6 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnlock.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnlock.java
@@ -18,12 +18,14 @@
 
 package org.apache.tools.ant.taskdefs.optional.clearcase;
 
+import java.util.Optional;
+
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.taskdefs.Execute;
 import org.apache.tools.ant.types.Commandline;
 
-/**
+/*
  * TODO:
  * comment field doesn't include all options yet
  */
@@ -69,6 +71,15 @@
  *
  */
 public class CCUnlock extends ClearCase {
+    /**
+     * -comment flag -- method to use for commenting events
+     */
+    public static final String FLAG_COMMENT = "-comment";
+    /**
+     * -pname flag -- pathname to lock
+     */
+    public static final String FLAG_PNAME = "-pname";
+
     private String mComment = null;
     private String mPname = null;
 
@@ -79,10 +90,10 @@
      * to execute the command line.
      * @throws BuildException if the command fails and failonerr is set to true
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
         Project aProj = getProject();
-        int result = 0;
 
         // Default the viewpath to basedir if it is not specified
         if (getViewPath() == null) {
@@ -105,10 +116,10 @@
             getProject().log("Ignoring any errors that occur for: "
                     + getOpType(), Project.MSG_VERBOSE);
         }
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result) && getFailOnErr()) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
@@ -120,8 +131,8 @@
         getCommentCommand(cmd);
 
         if (getObjSelect() == null && getPname() == null) {
-            throw new BuildException("Should select either an element "
-            + "(pname) or an object (objselect)");
+            throw new BuildException(
+                "Should select either an element (pname) or an object (objselect)");
         }
         getPnameCommand(cmd);
         // object selector
@@ -204,15 +215,14 @@
     private void getCommentCommand(Commandline cmd) {
         if (getComment() == null) {
             return;
-        } else {
-            /* Had to make two separate commands here because if a space is
-               inserted between the flag and the value, it is treated as a
-               Windows filename with a space and it is enclosed in double
-               quotes ("). This breaks clearcase.
-            */
-            cmd.createArgument().setValue(FLAG_COMMENT);
-            cmd.createArgument().setValue(getComment());
         }
+        /* Had to make two separate commands here because if a space is
+           inserted between the flag and the value, it is treated as a
+           Windows filename with a space and it is enclosed in double
+           quotes ("). This breaks clearcase.
+        */
+        cmd.createArgument().setValue(FLAG_COMMENT);
+        cmd.createArgument().setValue(getComment());
     }
 
     /**
@@ -224,15 +234,14 @@
     private void getPnameCommand(Commandline cmd) {
         if (getPname() == null) {
             return;
-        } else {
-            /* Had to make two separate commands here because if a space is
-               inserted between the flag and the value, it is treated as a
-               Windows filename with a space and it is enclosed in double
-               quotes ("). This breaks clearcase.
-            */
-            cmd.createArgument().setValue(FLAG_PNAME);
-            cmd.createArgument().setValue(getPname());
         }
+        /* Had to make two separate commands here because if a space is
+           inserted between the flag and the value, it is treated as a
+           Windows filename with a space and it is enclosed in double
+           quotes ("). This breaks clearcase.
+        */
+        cmd.createArgument().setValue(FLAG_PNAME);
+        cmd.createArgument().setValue(getPname());
     }
 
     /**
@@ -241,21 +250,7 @@
      * @return String containing the object/pname being worked on
      */
     private String getOpType() {
-
-        if (getPname() != null) {
-            return getPname();
-        } else {
-            return getObjSelect();
-        }
+        return Optional.ofNullable(getPname()).orElseGet(this::getObjSelect);
     }
 
-    /**
-     * -comment flag -- method to use for commenting events
-     */
-    public static final String FLAG_COMMENT = "-comment";
-    /**
-     * -pname flag -- pathname to lock
-     */
-    public static final String FLAG_PNAME = "-pname";
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUpdate.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUpdate.java
index a8ee850..6fd91f4 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUpdate.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUpdate.java
@@ -81,6 +81,35 @@
  *
  */
 public class CCUpdate extends ClearCase {
+    /**
+     *  -graphical flag -- display graphical dialog during update operation
+     */
+    public static final String FLAG_GRAPHICAL = "-graphical";
+    /**
+     * -log flag -- file to log status to
+     */
+    public static final String FLAG_LOG = "-log";
+    /**
+     * -overwrite flag -- overwrite hijacked files
+     */
+    public static final String FLAG_OVERWRITE = "-overwrite";
+    /**
+     * -noverwrite flag -- do not overwrite hijacked files
+     */
+    public static final String FLAG_NOVERWRITE = "-noverwrite";
+    /**
+     * -rename flag -- rename hijacked files with .keep extension
+     */
+    public static final String FLAG_RENAME = "-rename";
+    /**
+     * -ctime flag -- modified time is written as the current time
+     */
+    public static final String FLAG_CURRENTTIME = "-ctime";
+    /**
+     * -ptime flag -- modified time is written as the VOB time
+     */
+    public static final String FLAG_PRESERVETIME = "-ptime";
+
     private boolean mGraphical = false;
     private boolean mOverwrite = false;
     private boolean mRename = false;
@@ -95,10 +124,10 @@
      * to execute the command line.
      * @throws BuildException if the command fails and failonerr is set to true
      */
+    @Override
     public void execute() throws BuildException {
         Commandline commandLine = new Commandline();
         Project aProj = getProject();
-        int result = 0;
 
         // Default the viewpath to basedir if it is not specified
         if (getViewPath() == null) {
@@ -121,10 +150,10 @@
             getProject().log("Ignoring any errors that occur for: "
                     + getViewPathBasename(), Project.MSG_VERBOSE);
         }
-        result = run(commandLine);
+        int result = run(commandLine);
         if (Execute.isFailure(result) && getFailOnErr()) {
-            String msg = "Failed executing: " + commandLine.toString();
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("Failed executing: " + commandLine,
+                getLocation());
         }
     }
 
@@ -140,24 +169,20 @@
             if (getOverwrite()) {
                 // -overwrite
                 cmd.createArgument().setValue(FLAG_OVERWRITE);
+            } else if (getRename()) {
+                // -rename
+                cmd.createArgument().setValue(FLAG_RENAME);
             } else {
-                if (getRename()) {
-                    // -rename
-                    cmd.createArgument().setValue(FLAG_RENAME);
-                } else {
-                    // -noverwrite
-                    cmd.createArgument().setValue(FLAG_NOVERWRITE);
-                }
+                // -noverwrite
+                cmd.createArgument().setValue(FLAG_NOVERWRITE);
             }
 
             if (getCurrentTime()) {
                 // -ctime
                 cmd.createArgument().setValue(FLAG_CURRENTTIME);
-            } else {
-                if (getPreserveTime()) {
-                    // -ptime
-                    cmd.createArgument().setValue(FLAG_PRESERVETIME);
-                }
+            } else if (getPreserveTime()) {
+                // -ptime
+                cmd.createArgument().setValue(FLAG_PRESERVETIME);
             }
 
             // -log logname
@@ -279,7 +304,6 @@
         return mLog;
     }
 
-
     /**
      * Get the 'log' command
      *
@@ -288,45 +312,14 @@
     private void getLogCommand(Commandline cmd) {
         if (getLog() == null) {
             return;
-        } else {
-            /* Had to make two separate commands here because if a space is
-               inserted between the flag and the value, it is treated as a
-               Windows filename with a space and it is enclosed in double
-               quotes ("). This breaks clearcase.
-            */
-            cmd.createArgument().setValue(FLAG_LOG);
-            cmd.createArgument().setValue(getLog());
         }
+        /* Had to make two separate commands here because if a space is
+           inserted between the flag and the value, it is treated as a
+           Windows filename with a space and it is enclosed in double
+           quotes ("). This breaks clearcase.
+        */
+        cmd.createArgument().setValue(FLAG_LOG);
+        cmd.createArgument().setValue(getLog());
     }
 
-    /**
-     *  -graphical flag -- display graphical dialog during update operation
-     */
-    public static final String FLAG_GRAPHICAL = "-graphical";
-    /**
-     * -log flag -- file to log status to
-     */
-    public static final String FLAG_LOG = "-log";
-    /**
-     * -overwrite flag -- overwrite hijacked files
-     */
-    public static final String FLAG_OVERWRITE = "-overwrite";
-    /**
-     * -noverwrite flag -- do not overwrite hijacked files
-     */
-    public static final String FLAG_NOVERWRITE = "-noverwrite";
-    /**
-     * -rename flag -- rename hijacked files with .keep extension
-     */
-    public static final String FLAG_RENAME = "-rename";
-    /**
-     * -ctime flag -- modified time is written as the current time
-     */
-    public static final String FLAG_CURRENTTIME = "-ctime";
-    /**
-     * -ptime flag -- modified time is written as the VOB time
-     */
-    public static final String FLAG_PRESERVETIME = "-ptime";
-
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/ClearCase.java b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/ClearCase.java
index 5a537eb..eba0e9a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/ClearCase.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/ClearCase.java
@@ -19,6 +19,7 @@
 package org.apache.tools.ant.taskdefs.optional.clearcase;
 
 import java.io.File;
+import java.io.IOException;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -29,8 +30,6 @@
 import org.apache.tools.ant.types.Commandline;
 import org.apache.tools.ant.util.FileUtils;
 
-
-
 /**
  * A base class for creating tasks for executing commands on ClearCase.
  * <p>
@@ -46,137 +45,6 @@
  *
  */
 public abstract class ClearCase extends Task {
-    private String mClearToolDir = "";
-    private String mviewPath = null;
-    private String mobjSelect = null;
-    private int pcnt = 0;
-    private boolean mFailonerr = true;
-    /**
-     * Set the directory where the cleartool executable is located.
-     *
-     * @param dir the directory containing the cleartool executable
-     */
-    public final void setClearToolDir(String dir) {
-        mClearToolDir = FileUtils.translatePath(dir);
-    }
-
-    /**
-     * Builds and returns the command string to execute cleartool
-     *
-     * @return String containing path to the executable
-     */
-    protected final String getClearToolCommand() {
-        String toReturn = mClearToolDir;
-        if (!toReturn.equals("") && !toReturn.endsWith("/")) {
-            toReturn += "/";
-        }
-
-        toReturn += CLEARTOOL_EXE;
-
-        return toReturn;
-    }
-
-    /**
-     * Set the path to the item in a ClearCase view to operate on.
-     *
-     * @param viewPath Path to the view directory or file
-     */
-    public final void setViewPath(String viewPath) {
-        mviewPath = viewPath;
-    }
-
-    /**
-     * Get the path to the item in a clearcase view
-     *
-     * @return mviewPath
-     */
-    public String getViewPath() {
-        return mviewPath;
-    }
-
-    /**
-     * Get the basename path of the item in a clearcase view
-     *
-     * @return basename
-     */
-    public String getViewPathBasename() {
-        return (new File(mviewPath)).getName();
-    }
-
-    /**
-     * Set the object to operate on.
-     *
-     * @param objSelect object to operate on
-     */
-    public final void setObjSelect(String objSelect) {
-        mobjSelect = objSelect;
-    }
-
-    /**
-     * Get the object to operate on
-     *
-     * @return mobjSelect
-     */
-    public String getObjSelect() {
-        return mobjSelect;
-    }
-
-    /**
-     * Execute the given command are return success or failure
-     * @param cmd command line to execute
-     * @return the exit status of the subprocess or <code>INVALID</code>
-     */
-    protected int run(Commandline cmd) {
-        try {
-            Project aProj = getProject();
-            Execute exe
-                = new Execute(new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN));
-            exe.setAntRun(aProj);
-            exe.setWorkingDirectory(aProj.getBaseDir());
-            exe.setCommandline(cmd.getCommandline());
-            return exe.execute();
-        } catch (java.io.IOException e) {
-            throw new BuildException(e, getLocation());
-        }
-    }
-
-    /**
-     * Execute the given command, and return it's output
-     * @param cmdline command line to execute
-     * @return output of the command line
-     */
-    protected String runS(Commandline cmdline) {
-        String   outV  = "opts.cc.runS.output" + pcnt++;
-        ExecTask exe   = new ExecTask(this);
-        Commandline.Argument arg = exe.createArg();
-
-        exe.setExecutable(cmdline.getExecutable());
-        arg.setLine(Commandline.toString(cmdline.getArguments()));
-        exe.setOutputproperty(outV);
-        exe.execute();
-
-        return getProject().getProperty(outV);
-    }
-    /**
-     * If true, command will throw an exception on failure.
-     *
-     * @param failonerr the status to set the flag to
-     * @since ant 1.6.1
-     */
-    public void setFailOnErr(boolean failonerr) {
-        mFailonerr = failonerr;
-    }
-
-    /**
-     * Get failonerr flag status
-     *
-     * @return boolean containing status of failonerr flag
-     * @since ant 1.6.1
-     */
-    public boolean getFailOnErr() {
-        return mFailonerr;
-    }
-
     /**
      * Constant for the thing to execute
      */
@@ -238,5 +106,137 @@
      */
     public static final String COMMAND_MKDIR = "mkdir";
 
-}
+    private String mClearToolDir = "";
+    private String mviewPath = null;
+    private String mobjSelect = null;
+    private int pcnt = 0;
+    private boolean mFailonerr = true;
 
+    /**
+     * Set the directory where the cleartool executable is located.
+     *
+     * @param dir the directory containing the cleartool executable
+     */
+    public final void setClearToolDir(String dir) {
+        mClearToolDir = FileUtils.translatePath(dir);
+    }
+
+    /**
+     * Builds and returns the command string to execute cleartool
+     *
+     * @return String containing path to the executable
+     */
+    protected final String getClearToolCommand() {
+        String toReturn = mClearToolDir;
+        if (!("".equals(toReturn) || toReturn.endsWith("/"))) {
+            toReturn += "/";
+        }
+
+        toReturn += CLEARTOOL_EXE;
+
+        return toReturn;
+    }
+
+    /**
+     * Set the path to the item in a ClearCase view to operate on.
+     *
+     * @param viewPath Path to the view directory or file
+     */
+    public final void setViewPath(String viewPath) {
+        mviewPath = viewPath;
+    }
+
+    /**
+     * Get the path to the item in a clearcase view
+     *
+     * @return mviewPath
+     */
+    public String getViewPath() {
+        return mviewPath;
+    }
+
+    /**
+     * Get the basename path of the item in a clearcase view
+     *
+     * @return basename
+     */
+    public String getViewPathBasename() {
+        return (new File(mviewPath)).getName();
+    }
+
+    /**
+     * Set the object to operate on.
+     *
+     * @param objSelect object to operate on
+     */
+    public final void setObjSelect(String objSelect) {
+        mobjSelect = objSelect;
+    }
+
+    /**
+     * Get the object to operate on
+     *
+     * @return mobjSelect
+     */
+    public String getObjSelect() {
+        return mobjSelect;
+    }
+
+    /**
+     * Execute the given command are return success or failure
+     * @param cmd command line to execute
+     * @return the exit status of the subprocess or <code>INVALID</code>
+     */
+    protected int run(Commandline cmd) {
+        try {
+            Project aProj = getProject();
+            Execute exe = new Execute(
+                new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN));
+            exe.setAntRun(aProj);
+            exe.setWorkingDirectory(aProj.getBaseDir());
+            exe.setCommandline(cmd.getCommandline());
+            return exe.execute();
+        } catch (IOException e) {
+            throw new BuildException(e, getLocation());
+        }
+    }
+
+    /**
+     * Execute the given command, and return it's output
+     * @param cmdline command line to execute
+     * @return output of the command line
+     */
+    protected String runS(Commandline cmdline) {
+        String   outV  = "opts.cc.runS.output" + pcnt++;
+        ExecTask exe   = new ExecTask(this);
+        Commandline.Argument arg = exe.createArg();
+
+        exe.setExecutable(cmdline.getExecutable());
+        arg.setLine(Commandline.toString(cmdline.getArguments()));
+        exe.setOutputproperty(outV);
+        exe.execute();
+
+        return getProject().getProperty(outV);
+    }
+
+    /**
+     * If true, command will throw an exception on failure.
+     *
+     * @param failonerr the status to set the flag to
+     * @since ant 1.6.1
+     */
+    public void setFailOnErr(boolean failonerr) {
+        mFailonerr = failonerr;
+    }
+
+    /**
+     * Get failonerr flag status
+     *
+     * @return boolean containing status of failonerr flag
+     * @since ant 1.6.1
+     */
+    public boolean getFailOnErr() {
+        return mFailonerr;
+    }
+
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/AntAnalyzer.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/AntAnalyzer.java
index 341f670..3c8d82b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/AntAnalyzer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/AntAnalyzer.java
@@ -18,11 +18,13 @@
 package org.apache.tools.ant.taskdefs.optional.depend;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.Vector;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
@@ -36,11 +38,6 @@
  *
  */
 public class AntAnalyzer extends AbstractAnalyzer {
-    /**
-     * Default constructor
-     */
-    public AntAnalyzer() {
-    }
 
     /**
      * Determine the dependencies of the configured root classes.
@@ -50,37 +47,33 @@
      * @param classes a vector to be populated with the names of the
      *      dependency classes.
      */
+    @Override
     protected void determineDependencies(Vector<File> files, Vector<String> classes) {
         // we get the root classes and build up a set of
         // classes upon which they depend
-        Hashtable<String, String> dependencies = new Hashtable<String, String>();
-        Hashtable<File, File> containers = new Hashtable<File, File>();
-        Hashtable<String, String> toAnalyze = new Hashtable<String, String>();
-        for (Enumeration<String> e = getRootClasses(); e.hasMoreElements();) {
-            String classname = e.nextElement();
-            toAnalyze.put(classname, classname);
-        }
+        Set<String> toAnalyze = new HashSet<>(Collections.list(getRootClasses()));
 
         int count = 0;
         int maxCount = isClosureRequired() ? MAX_LOOPS : 1;
-        Hashtable<String, String> analyzedDeps = null;
-        while (toAnalyze.size() != 0 && count++ < maxCount) {
-            analyzedDeps = new Hashtable<String, String>();
-            for (Enumeration<String> e = toAnalyze.keys(); e.hasMoreElements();) {
-                String classname = e.nextElement();
-                dependencies.put(classname, classname);
+        Set<String> dependencies = new HashSet<>();
+        Set<File> containers = new HashSet<>();
+        Set<String> analyzedDeps = null;
+        while (!toAnalyze.isEmpty() && count++ < maxCount) {
+            analyzedDeps = new HashSet<>();
+            for (String classname : toAnalyze) {
+                dependencies.add(classname);
                 try {
                     File container = getClassContainer(classname);
                     if (container == null) {
                         continue;
                     }
-                    containers.put(container, container);
+                    containers.add(container);
 
                     ZipFile zipFile = null;
                     InputStream inStream = null;
                     try {
                         if (container.getName().endsWith(".class")) {
-                            inStream = new FileInputStream(container.getPath());
+                            inStream = Files.newInputStream(Paths.get(container.getPath()));
                         } else {
                             zipFile = new ZipFile(container.getPath());
                             String entryName
@@ -92,13 +85,11 @@
                         ClassFile classFile = new ClassFile();
                         classFile.read(inStream);
                         for (String dependency : classFile.getClassRefs()) {
-                            analyzedDeps.put(dependency, dependency);
+                            analyzedDeps.add(dependency);
                         }
                     } finally {
                         FileUtils.close(inStream);
-                        if (zipFile != null) {
-                            zipFile.close();
-                        }
+                        FileUtils.close(zipFile);
                     }
                 } catch (IOException ioe) {
                     // ignore
@@ -108,27 +99,20 @@
             toAnalyze.clear();
 
             // now recover all the dependencies collected and add to the list.
-            for (String className : analyzedDeps.values()) {
-                if (!dependencies.containsKey(className)) {
-                    toAnalyze.put(className, className);
+            for (String className : analyzedDeps) {
+                if (!dependencies.contains(className)) {
+                    toAnalyze.add(className);
                 }
             }
         }
 
         // pick up the last round of dependencies that were determined
-        for (String className : analyzedDeps.values()) {
-            dependencies.put(className, className);
-        }
+        dependencies.addAll(analyzedDeps);
 
         files.removeAllElements();
-        for (File f : containers.keySet()) {
-            files.add(f);
-        }
-
+        files.addAll(containers);
         classes.removeAllElements();
-        for (String dependency :dependencies.keySet()) {
-            classes.add(dependency);
-        }
+        classes.addAll(dependencies);
     }
 
     /**
@@ -136,9 +120,9 @@
      *
      * @return true if the analyzer provides dependency file information.
      */
+    @Override
     protected boolean supportsFileDependencies() {
         return true;
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFile.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFile.java
index 858ce03..49f8a27 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFile.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFile.java
@@ -59,8 +59,8 @@
         DataInputStream classStream = new DataInputStream(stream);
 
         if (classStream.readInt() != CLASS_MAGIC) {
-            throw new ClassFormatError("No Magic Code Found "
-                + "- probably not a Java class file.");
+            throw new ClassFormatError(
+                "No Magic Code Found - probably not a Java class file.");
         }
 
         // right we have a good looking class file.
@@ -81,7 +81,6 @@
         className  = classInfo.getClassName();
     }
 
-
     /**
      * Get the classes which this class references.
      *
@@ -89,7 +88,7 @@
      */
     public Vector<String> getClassRefs() {
 
-        Vector<String> classRefs = new Vector<String>();
+        Vector<String> classRefs = new Vector<>();
 
         final int size = constantPool.size();
         for (int i = 0; i < size; ++i) {
@@ -118,4 +117,3 @@
         return ClassFileUtils.convertSlashName(className);
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileIterator.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileIterator.java
index 92fc191..48c1f45 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileIterator.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileIterator.java
@@ -17,11 +17,14 @@
  */
 package org.apache.tools.ant.taskdefs.optional.depend;
 
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
 /**
  * Iterator interface for iterating over a set of class files
  *
  */
-public interface ClassFileIterator {
+public interface ClassFileIterator extends Iterable<ClassFile> {
 
     /**
      * Get the next class file in the iteration
@@ -29,5 +32,33 @@
      * @return the next class file in the iteration
      */
     ClassFile getNextClassFile();
-}
 
+    @Override
+    default Iterator<ClassFile> iterator() {
+
+        return new Iterator<ClassFile>() {
+            ClassFile next;
+            {
+                next = getNextClassFile();
+            }
+
+            @Override
+            public boolean hasNext() {
+                return next != null;
+            }
+
+            @Override
+            public ClassFile next() {
+                if (next == null) {
+                    throw new NoSuchElementException();
+                }
+                try {
+                    return next;
+                } finally {
+                    next = getNextClassFile();
+                }
+            }
+
+        };
+    }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileUtils.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileUtils.java
index c6eec6c..273b563 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileUtils.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileUtils.java
@@ -49,4 +49,3 @@
         return dotName.replace('.', '/');
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java
index 7b51133..3b6d341 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java
@@ -23,10 +23,18 @@
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.AntClassLoader;
 import org.apache.tools.ant.BuildException;
@@ -37,6 +45,9 @@
 import org.apache.tools.ant.taskdefs.rmic.WLRmic;
 import org.apache.tools.ant.types.Path;
 import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.Difference;
+import org.apache.tools.ant.types.resources.FileProvider;
 import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.depend.DependencyAnalyzer;
 
@@ -74,26 +85,23 @@
     /** The directory which contains the dependency cache. */
     private File cache;
 
-    /** The list of source paths derived from the srcPath field. */
-    private String[] srcPathList;
-
     /**
      * A map which gives for every class a list of the class which it
      * affects.
      */
-    private Hashtable affectedClassMap;
+    private Map<String, Map<String, ClassFileInfo>> affectedClassMap;
 
     /** A map which gives information about a class */
-    private Hashtable classFileInfoMap;
+    private Map<String, ClassFileInfo> classFileInfoMap;
 
     /**
      * A map which gives the list of jars and classes from the classpath
      * that a class depends upon
      */
-    private Hashtable classpathDependencies;
+    private Map<String, Set<File>> classpathDependencies;
 
     /** The list of classes which are out of date. */
-    private Hashtable outOfDateClasses;
+    private Map<String, String> outOfDateClasses;
 
     /**
      * indicates that the dependency relationships should be extended beyond
@@ -182,29 +190,24 @@
      * @return a collection of class dependencies
      * @exception IOException if the dependency file cannot be read
      */
-    private Hashtable readCachedDependencies(File depFile) throws IOException {
-        Hashtable dependencyMap = new Hashtable();
+    private Map<String, List<String>> readCachedDependencies(File depFile) throws IOException {
+        Map<String, List<String>> dependencyMap = new HashMap<>();
 
-        BufferedReader in = null;
-        try {
-            in = new BufferedReader(new FileReader(depFile));
-            String line = null;
-            Vector dependencyList = null;
-            String className = null;
-            int prependLength = CLASSNAME_PREPEND.length();
+        int prependLength = CLASSNAME_PREPEND.length();
+
+        try (BufferedReader in = new BufferedReader(new FileReader(depFile))) {
+            List<String> dependencyList = null;
+            String line;
             while ((line = in.readLine()) != null) {
                 if (line.startsWith(CLASSNAME_PREPEND)) {
-                    dependencyList = new Vector();
-                    className = line.substring(prependLength);
-                    dependencyMap.put(className, dependencyList);
+                    String className = line.substring(prependLength);
+                    dependencyList = dependencyMap.computeIfAbsent(className,
+                        k -> new ArrayList<>());
                 } else if (dependencyList != null) {
-                    dependencyList.addElement(line);
+                    dependencyList.add(line);
                 }
             }
-        } finally {
-            FileUtils.close(in);
         }
-
         return dependencyMap;
     }
 
@@ -214,32 +217,18 @@
      * @param dependencyMap the map of dependencies to be written out.
      * @exception IOException if the dependency file cannot be written out.
      */
-    private void writeCachedDependencies(Hashtable dependencyMap)
+    private void writeCachedDependencies(Map<String, List<String>> dependencyMap)
         throws IOException {
         if (cache != null) {
-            BufferedWriter pw = null;
-            try {
-                cache.mkdirs();
-                File depFile = new File(cache, CACHE_FILE_NAME);
-
-                pw = new BufferedWriter(new FileWriter(depFile));
-                Enumeration e = dependencyMap.keys();
-                while (e.hasMoreElements()) {
-                    String className = (String) e.nextElement();
-
-                    pw.write(CLASSNAME_PREPEND + className);
-                    pw.newLine();
-
-                    Vector dependencyList
-                        = (Vector) dependencyMap.get(className);
-                    int size = dependencyList.size();
-                    for (int x = 0; x < size; x++) {
-                        pw.write(String.valueOf(dependencyList.elementAt(x)));
-                        pw.newLine();
-                    }
+            cache.mkdirs();
+            File depFile = new File(cache, CACHE_FILE_NAME);
+            try (PrintWriter pw =
+                new PrintWriter(new BufferedWriter(new FileWriter(depFile)))) {
+                for (Map.Entry<String, List<String>> e : dependencyMap
+                    .entrySet()) {
+                    pw.printf("%s%s%n", CLASSNAME_PREPEND, e.getKey());
+                    e.getValue().forEach(pw::println);
                 }
-            } finally {
-                FileUtils.close(pw);
             }
         }
     }
@@ -253,28 +242,16 @@
         if (dependClasspath == null) {
             return null;
         }
+        Difference diff = new Difference();
+        diff.add(destPath);
+        diff.add(dependClasspath);
 
-        String[] destPathElements = destPath.list();
-        String[] classpathElements = dependClasspath.list();
-        String checkPath = "";
-        for (int i = 0; i < classpathElements.length; ++i) {
-            String element = classpathElements[i];
-            boolean inDestPath = false;
-            for (int j = 0; j < destPathElements.length && !inDestPath; ++j) {
-                inDestPath = destPathElements[j].equals(element);
-            }
-            if (!inDestPath) {
-                if (checkPath.length() == 0) {
-                    checkPath = element;
-                } else {
-                    checkPath += ":" + element;
-                }
-            }
-        }
-
-        Path p = null;
-        if (checkPath.length() > 0) {
-            p = new Path(getProject(), checkPath);
+        Path p;
+        if (diff.isEmpty()) {
+            p = null;
+        } else {
+            p = new Path(getProject());
+            p.add(diff);
         }
 
         log("Classpath without dest dir is " + p, Project.MSG_DEBUG);
@@ -300,11 +277,11 @@
      *      files cannot be read or written
      */
     private void determineDependencies() throws IOException {
-        affectedClassMap = new Hashtable();
-        classFileInfoMap = new Hashtable();
+        affectedClassMap = new HashMap<>();
+        classFileInfoMap = new HashMap<>();
         boolean cacheDirty = false;
 
-        Hashtable dependencyMap = new Hashtable();
+        Map<String, List<String>> dependencyMap = new HashMap<>();
         File cacheFile = null;
         boolean cacheFileExists = true;
         long cacheLastModified = Long.MAX_VALUE;
@@ -318,13 +295,11 @@
                 dependencyMap = readCachedDependencies(cacheFile);
             }
         }
-        Enumeration classfileEnum = getClassFiles(destPath).elements();
-        while (classfileEnum.hasMoreElements()) {
-            ClassFileInfo info = (ClassFileInfo) classfileEnum.nextElement();
+        for (ClassFileInfo info : getClassFiles()) {
             log("Adding class info for " + info.className, Project.MSG_DEBUG);
             classFileInfoMap.put(info.className, info);
 
-            Vector dependencyList = null;
+            List<String> dependencyList = null;
 
             if (cache != null) {
                 // try to read the dependency info from the map if it is
@@ -333,7 +308,7 @@
                     && cacheLastModified > info.absoluteFile.lastModified()) {
                     // depFile exists and is newer than the class file
                     // need to get dependency list from the map.
-                    dependencyList = (Vector) dependencyMap.get(info.className);
+                    dependencyList = dependencyMap.get(info.className);
                 }
             }
 
@@ -343,11 +318,11 @@
                 analyzer.addRootClass(info.className);
                 analyzer.addClassPath(destPath);
                 analyzer.setClosure(false);
-                dependencyList = new Vector();
-                Enumeration depEnum = analyzer.getClassDependencies();
+                dependencyList = new ArrayList<>();
+                Enumeration<String> depEnum = analyzer.getClassDependencies();
                 while (depEnum.hasMoreElements()) {
-                    Object o = depEnum.nextElement();
-                    dependencyList.addElement(o);
+                    String o = depEnum.nextElement();
+                    dependencyList.add(o);
                     log("Class " + info.className + " depends on " + o,
                         Project.MSG_DEBUG);
                 }
@@ -357,18 +332,10 @@
 
             // This class depends on each class in the dependency list. For each
             // one of those, add this class into their affected classes list
-            Enumeration depEnum = dependencyList.elements();
-            while (depEnum.hasMoreElements()) {
-                String dependentClass = (String) depEnum.nextElement();
-
-                Hashtable affectedClasses
-                    = (Hashtable) affectedClassMap.get(dependentClass);
-                if (affectedClasses == null) {
-                    affectedClasses = new Hashtable();
-                    affectedClassMap.put(dependentClass, affectedClasses);
-                }
-
-                affectedClasses.put(info.className, info);
+            for (String dependentClass : dependencyList) {
+                affectedClassMap
+                    .computeIfAbsent(dependentClass, k -> new HashMap<>())
+                    .put(info.className, info);
                 log(dependentClass + " affects " + info.className,
                     Project.MSG_DEBUG);
             }
@@ -378,23 +345,19 @@
         Path checkPath = getCheckClassPath();
         if (checkPath != null) {
             // now determine which jars each class depends upon
-            classpathDependencies = new Hashtable();
-            AntClassLoader loader = null;
-            try {
-                loader = getProject().createClassLoader(checkPath);
+            classpathDependencies = new HashMap<>();
+            try (AntClassLoader loader = getProject().createClassLoader(checkPath)) {
 
-                Hashtable classpathFileCache = new Hashtable();
+                Map<String, Object> classpathFileCache = new HashMap<>();
                 Object nullFileMarker = new Object();
-                for (Enumeration e = dependencyMap.keys(); e.hasMoreElements();) {
-                    String className = (String) e.nextElement();
+                for (Map.Entry<String, List<String>> e : dependencyMap.entrySet()) {
+                    String className = e.getKey();
                     log("Determining classpath dependencies for " + className,
                         Project.MSG_DEBUG);
-                    Vector dependencyList = (Vector) dependencyMap.get(className);
-                    Hashtable dependencies = new Hashtable();
+                    List<String> dependencyList = e.getValue();
+                    Set<File> dependencies = new HashSet<>();
                     classpathDependencies.put(className, dependencies);
-                    Enumeration e2 = dependencyList.elements();
-                    while (e2.hasMoreElements()) {
-                        String dependency = (String) e2.nextElement();
+                    for (String dependency : dependencyList) {
                         log("Looking for " + dependency, Project.MSG_DEBUG);
                         Object classpathFileObject
                             = classpathFileCache.get(dependency);
@@ -407,22 +370,23 @@
                                     = loader.getResource(dependency.replace('.', '/') + ".class");
                                 log("URL is " + classURL, Project.MSG_DEBUG);
                                 if (classURL != null) {
-                                    if (classURL.getProtocol().equals("jar")) {
+                                    if ("jar".equals(classURL.getProtocol())) {
                                         String jarFilePath = classURL.getFile();
                                         int classMarker = jarFilePath.indexOf('!');
                                         jarFilePath = jarFilePath.substring(0, classMarker);
                                         if (jarFilePath.startsWith("file:")) {
                                             classpathFileObject = new File(
-                                                                           FileUtils.getFileUtils().fromURI(jarFilePath));
+                                                FileUtils.getFileUtils()
+                                                    .fromURI(jarFilePath));
                                         } else {
                                             throw new IOException(
-                                                                  "Bizarre nested path in jar: protocol: "
-                                                                  + jarFilePath);
+                                                "Bizarre nested path in jar: protocol: "
+                                                    + jarFilePath);
                                         }
-                                    } else if (classURL.getProtocol().equals("file")) {
+                                    } else if ("file".equals(classURL.getProtocol())) {
                                         classpathFileObject = new File(
-                                                                       FileUtils.getFileUtils()
-                                                                       .fromURI(classURL.toExternalForm()));
+                                            FileUtils.getFileUtils().fromURI(
+                                                classURL.toExternalForm()));
                                     }
                                     log("Class " + className
                                         + " depends on " + classpathFileObject
@@ -439,14 +403,10 @@
                             File jarFile = (File) classpathFileObject;
                             log("Adding a classpath dependency on " + jarFile,
                                 Project.MSG_DEBUG);
-                            dependencies.put(jarFile, jarFile);
+                            dependencies.add(jarFile);
                         }
                     }
                 }
-            } finally {
-                if (loader != null) {
-                    loader.cleanup();
-                }
             }
         } else {
             log("No classpath to check", Project.MSG_DEBUG);
@@ -466,11 +426,9 @@
      */
     private int deleteAllAffectedFiles() {
         int count = 0;
-        for (Enumeration e = outOfDateClasses.elements(); e.hasMoreElements();) {
-            String className = (String) e.nextElement();
+        for (String className : outOfDateClasses.keySet()) {
             count += deleteAffectedFiles(className);
-            ClassFileInfo classInfo
-                = (ClassFileInfo) classFileInfoMap.get(className);
+            ClassFileInfo classInfo = classFileInfoMap.get(className);
             if (classInfo != null && classInfo.absoluteFile.exists()) {
                 if (classInfo.sourceFile == null) {
                     warnOutOfDateButNotDeleted(classInfo, className, className);
@@ -493,14 +451,13 @@
     private int deleteAffectedFiles(String className) {
         int count = 0;
 
-        Hashtable affectedClasses = (Hashtable) affectedClassMap.get(className);
+        Map<String, ClassFileInfo> affectedClasses = affectedClassMap.get(className);
         if (affectedClasses == null) {
             return count;
         }
-        for (Enumeration e = affectedClasses.keys(); e.hasMoreElements();) {
-            String affectedClass = (String) e.nextElement();
-            ClassFileInfo affectedClassInfo
-                = (ClassFileInfo) affectedClasses.get(affectedClass);
+        for (Map.Entry<String, ClassFileInfo> e : affectedClasses.entrySet()) {
+            String affectedClass = e.getKey();
+            ClassFileInfo affectedClassInfo = e.getValue();
 
             if (!affectedClassInfo.absoluteFile.exists()) {
                 continue;
@@ -522,16 +479,16 @@
                 // without closure we may delete an inner class but not the
                 // top level class which would not trigger a recompile.
 
-                if (affectedClass.indexOf("$") == -1) {
+                if (affectedClass.indexOf('$') == -1) {
                     continue;
                 }
                 // need to delete the main class
                 String topLevelClassName
-                    = affectedClass.substring(0, affectedClass.indexOf("$"));
+                    = affectedClass.substring(0, affectedClass.indexOf('$'));
                 log("Top level class = " + topLevelClassName,
                     Project.MSG_VERBOSE);
                 ClassFileInfo topLevelClassInfo
-                    = (ClassFileInfo) classFileInfoMap.get(topLevelClassName);
+                    = classFileInfoMap.get(topLevelClassName);
                 if (topLevelClassInfo != null
                     && topLevelClassInfo.absoluteFile.exists()) {
                     log("Deleting file "
@@ -575,8 +532,8 @@
         log("The class " + affectedClass + " in file "
             + affectedClassInfo.absoluteFile.getPath()
             + " is out of date due to " + className
-            + " but has not been deleted because its source file"
-            + " could not be determined", level);
+            + " but has not been deleted because its source file could not be determined",
+            level);
         affectedClassInfo.isUserWarned = true;
     }
 
@@ -604,75 +561,48 @@
         log("Reverse Dependency Dump for " + affectedClassMap.size()
             + " classes:", Project.MSG_DEBUG);
 
-        Enumeration classEnum = affectedClassMap.keys();
-        while (classEnum.hasMoreElements()) {
-            String className = (String) classEnum.nextElement();
+        affectedClassMap.forEach((className, affectedClasses) -> {
             log(" Class " + className + " affects:", Project.MSG_DEBUG);
-            Hashtable affectedClasses
-                = (Hashtable) affectedClassMap.get(className);
-            Enumeration affectedClassEnum = affectedClasses.keys();
-            while (affectedClassEnum.hasMoreElements()) {
-                String affectedClass = (String) affectedClassEnum.nextElement();
-                ClassFileInfo info
-                    = (ClassFileInfo) affectedClasses.get(affectedClass);
-                log("    " + affectedClass + " in "
-                    + info.absoluteFile.getPath(), Project.MSG_DEBUG);
-            }
-        }
+            affectedClasses.forEach((affectedClass, info) -> log(
+                "    " + affectedClass + " in " + info.absoluteFile.getPath(),
+                Project.MSG_DEBUG));
+        });
 
         if (classpathDependencies != null) {
             log("Classpath file dependencies (Forward):", Project.MSG_DEBUG);
 
-            Enumeration classpathEnum = classpathDependencies.keys();
-            while (classpathEnum.hasMoreElements()) {
-                String className = (String) classpathEnum.nextElement();
+            classpathDependencies.forEach((className, dependencies) -> {
                 log(" Class " + className + " depends on:", Project.MSG_DEBUG);
-                Hashtable dependencies
-                    = (Hashtable) classpathDependencies.get(className);
-
-                Enumeration classpathFileEnum = dependencies.elements();
-                while (classpathFileEnum.hasMoreElements()) {
-                    File classpathFile = (File) classpathFileEnum.nextElement();
-                    log("    " + classpathFile.getPath(), Project.MSG_DEBUG);
-                }
-            }
+                dependencies.forEach(f -> log("    " + f.getPath(), Project.MSG_DEBUG));
+            });
         }
     }
 
     private void determineOutOfDateClasses() {
-        outOfDateClasses = new Hashtable();
-        for (int i = 0; i < srcPathList.length; i++) {
-            File srcDir = getProject().resolveFile(srcPathList[i]);
-            if (srcDir.exists()) {
-                DirectoryScanner ds = this.getDirectoryScanner(srcDir);
-                String[] files = ds.getIncludedFiles();
-                scanDir(srcDir, files);
-            }
-        }
+        outOfDateClasses = new HashMap<>();
+        directories(srcPath).forEach(srcDir -> {
+            DirectoryScanner ds = this.getDirectoryScanner(srcDir);
+            scanDir(srcDir, ds.getIncludedFiles());
+        });
 
         // now check classpath file dependencies
         if (classpathDependencies == null) {
             return;
         }
 
-        Enumeration classpathDepsEnum = classpathDependencies.keys();
-        while (classpathDepsEnum.hasMoreElements()) {
-            String className = (String) classpathDepsEnum.nextElement();
+        for (Map.Entry<String, Set<File>> e : classpathDependencies.entrySet()) {
+            String className = e.getKey();
             if (outOfDateClasses.containsKey(className)) {
                 continue;
             }
-            ClassFileInfo info
-                = (ClassFileInfo) classFileInfoMap.get(className);
+            ClassFileInfo info = classFileInfoMap.get(className);
 
             // if we have no info about the class - it may have been deleted already and we
             // are using cached info.
             if (info != null) {
-                Hashtable dependencies
-                    = (Hashtable) classpathDependencies.get(className);
-                for (Enumeration e2 = dependencies.elements(); e2.hasMoreElements();) {
-                    File classpathFile = (File) e2.nextElement();
-                    if (classpathFile.lastModified()
-                        > info.absoluteFile.lastModified()) {
+                for (File classpathFile : e.getValue()) {
+                    if (classpathFile.lastModified() > info.absoluteFile
+                        .lastModified()) {
                         log("Class " + className
                             + " is out of date with respect to "
                             + classpathFile, Project.MSG_DEBUG);
@@ -689,6 +619,7 @@
      *
      * @exception BuildException Thrown in case of an unrecoverable error.
      */
+    @Override
     public void execute() throws BuildException {
         try {
             long start = System.currentTimeMillis();
@@ -697,8 +628,7 @@
                                          getLocation());
             }
 
-            srcPathList = srcPath.list();
-            if (srcPathList.length == 0) {
+            if (!directories(srcPath).findAny().isPresent()) {
                 throw new BuildException("srcdir attribute must be non-empty",
                                          getLocation());
             }
@@ -708,8 +638,8 @@
             }
 
             if (cache != null && cache.exists() && !cache.isDirectory()) {
-                throw new BuildException("The cache, if specified, must "
-                                         + "point to a directory");
+                throw new BuildException(
+                    "The cache, if specified, must point to a directory");
             }
 
             if (cache != null && !cache.exists()) {
@@ -749,50 +679,38 @@
      *      checked.
      */
     protected void scanDir(File srcDir, String[] files) {
-
-        for (int i = 0; i < files.length; i++) {
-            File srcFile = new File(srcDir, files[i]);
-            if (files[i].endsWith(".java")) {
+        for (String f : files) {
+            File srcFile = new File(srcDir, f);
+            if (f.endsWith(".java")) {
                 String filePath = srcFile.getPath();
                 String className
                     = filePath.substring(srcDir.getPath().length() + 1,
                                          filePath.length() - ".java".length());
                 className = ClassFileUtils.convertSlashName(className);
                 ClassFileInfo info
-                    = (ClassFileInfo) classFileInfoMap.get(className);
+                    = classFileInfoMap.get(className);
                 if (info == null) {
                     // there was no class file. add this class to the list
                     outOfDateClasses.put(className, className);
-                } else {
-                    if (srcFile.lastModified()
-                        > info.absoluteFile.lastModified()) {
-                        outOfDateClasses.put(className, className);
-                    }
+                } else if (srcFile.lastModified() > info.absoluteFile
+                    .lastModified()) {
+                    outOfDateClasses.put(className, className);
                 }
             }
         }
     }
 
-
     /**
      * Get the list of class files we are going to analyse.
      *
-     * @param classLocations a path structure containing all the directories
-     *      where classes can be found.
      * @return a vector containing the classes to analyse.
      */
-    private Vector getClassFiles(Path classLocations) {
+    private List<ClassFileInfo> getClassFiles() {
         // break the classLocations into its components.
-        String[] classLocationsList = classLocations.list();
+        List<ClassFileInfo> classFileList = new ArrayList<>();
 
-        Vector classFileList = new Vector();
-
-        for (int i = 0; i < classLocationsList.length; ++i) {
-            File dir = new File(classLocationsList[i]);
-            if (dir.isDirectory()) {
-                addClassFiles(classFileList, dir, dir);
-            }
-        }
+        directories(destPath)
+            .forEach(dir -> addClassFiles(classFileList, dir, dir));
 
         return classFileList;
     }
@@ -806,21 +724,17 @@
      */
     private File findSourceFile(String classname, File sourceFileKnownToExist) {
         String sourceFilename;
-        int innerIndex = classname.indexOf("$");
+        int innerIndex = classname.indexOf('$');
         if (innerIndex != -1) {
             sourceFilename = classname.substring(0, innerIndex) + ".java";
         } else {
             sourceFilename = classname + ".java";
         }
-
         // search the various source path entries
-        for (int i = 0; i < srcPathList.length; ++i) {
-            File sourceFile = new File(srcPathList[i], sourceFilename);
-            if (sourceFile.equals(sourceFileKnownToExist) || sourceFile.exists()) {
-                return sourceFile;
-            }
-        }
-        return null;
+        return directories(srcPath)
+            .map(d -> new File(d, sourceFilename)).filter(Predicate
+                .<File> isEqual(sourceFileKnownToExist).or(File::exists))
+            .findFirst().orElse(null);
     }
 
     /**
@@ -835,36 +749,34 @@
      *      the absolute class name from the relative position in the
      *      source tree
      */
-    private void addClassFiles(Vector classFileList, File dir, File root) {
-        String[] filesInDir = dir.list();
+    private void addClassFiles(List<ClassFileInfo> classFileList, File dir, File root) {
+        File[] children = dir.listFiles();
 
-        if (filesInDir == null) {
+        if (children == null) {
             return;
         }
-        int length = filesInDir.length;
 
         int rootLength = root.getPath().length();
         File sourceFileKnownToExist = null; // speed optimization
-        for (int i = 0; i < length; ++i) {
-            File file = new File(dir, filesInDir[i]);
-            if (filesInDir[i].endsWith(".class")) {
+        for (File file : children) {
+            if (file.getName().endsWith(".class")) {
                 ClassFileInfo info = new ClassFileInfo();
                 info.absoluteFile = file;
-                String relativeName = file.getPath().substring(
-                                                               rootLength + 1,
-                                                               file.getPath().length() - ".class".length());
+
+                String relativeName = file.getPath().substring(rootLength + 1,
+                    file.getPath().length() - ".class".length());
+
                 info.className
                     = ClassFileUtils.convertSlashName(relativeName);
-                info.sourceFile = sourceFileKnownToExist = findSourceFile(
-                                                                          relativeName, sourceFileKnownToExist);
-                classFileList.addElement(info);
+                info.sourceFile = sourceFileKnownToExist =
+                    findSourceFile(relativeName, sourceFileKnownToExist);
+                classFileList.add(info);
             } else {
                 addClassFiles(classFileList, file, root);
             }
         }
     }
 
-
     /**
      * Set the directories path to find the Java source files.
      *
@@ -913,5 +825,10 @@
     public void setDump(boolean dump) {
         this.dump = dump;
     }
-}
 
+    private Stream<File> directories(ResourceCollection rc) {
+        return rc.stream().map(r -> r.as(FileProvider.class))
+            .filter(Objects::nonNull).map(FileProvider::getFile)
+            .filter(File::isDirectory);
+    }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/DirectoryIterator.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/DirectoryIterator.java
index af28c96..98c91a9 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/DirectoryIterator.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/DirectoryIterator.java
@@ -18,11 +18,15 @@
 package org.apache.tools.ant.taskdefs.optional.depend;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
-import java.util.Enumeration;
-import java.util.Stack;
-import java.util.Vector;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.util.ArrayDeque;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.List;
 
 /**
  * An iterator which iterates through the contents of a java directory. The
@@ -36,7 +40,7 @@
      * This is a stack of current iterators supporting the depth first
      * traversal of the directory tree.
      */
-    private Stack enumStack;
+    private Deque<Iterator<File>> enumStack;
 
     /**
      * The current directory iterator. As directories encounter lower level
@@ -45,7 +49,7 @@
      * directory. This implements a depth first traversal of the directory
      * namespace.
      */
-    private Enumeration currentEnum;
+    private Iterator<File> currentIterator;
 
     /**
      * Creates a directory iterator. The directory iterator is created to
@@ -63,12 +67,8 @@
     public DirectoryIterator(File rootDirectory, boolean changeInto)
          throws IOException {
         super();
-
-        enumStack = new Stack();
-
-        Vector filesInRoot = getDirectoryEntries(rootDirectory);
-
-        currentEnum = filesInRoot.elements();
+        enumStack = new ArrayDeque<>();
+        currentIterator = getDirectoryEntries(rootDirectory).iterator();
     }
 
     /**
@@ -79,21 +79,12 @@
      * @return a vector containing File objects for each entry in the
      *      directory.
      */
-    private Vector getDirectoryEntries(File directory) {
-        Vector files = new Vector();
-
-        // File[] filesInDir = directory.listFiles();
-        String[] filesInDir = directory.list();
-
-        if (filesInDir != null) {
-            int length = filesInDir.length;
-
-            for (int i = 0; i < length; ++i) {
-                files.addElement(new File(directory, filesInDir[i]));
-            }
+    private List<File> getDirectoryEntries(File directory) {
+        File[] filesInDir = directory.listFiles();
+        if (filesInDir == null) {
+            return Collections.emptyList();
         }
-
-        return files;
+        return Arrays.asList(filesInDir);
     }
 
     /**
@@ -110,30 +101,28 @@
      *
      * @return the next ClassFile in the iteration.
      */
+    @Override
     public ClassFile getNextClassFile() {
         ClassFile nextElement = null;
 
         try {
             while (nextElement == null) {
-                if (currentEnum.hasMoreElements()) {
-                    File element = (File) currentEnum.nextElement();
+                if (currentIterator.hasNext()) {
+                    File element = currentIterator.next();
 
                     if (element.isDirectory()) {
 
                         // push the current iterator onto the stack and then
                         // iterate through this directory.
-                        enumStack.push(currentEnum);
+                        enumStack.push(currentIterator);
 
-                        Vector files = getDirectoryEntries(element);
+                        List<File> files = getDirectoryEntries(element);
 
-                        currentEnum = files.elements();
+                        currentIterator = files.iterator();
                     } else {
-
                         // we have a file. create a stream for it
-                        FileInputStream inFileStream
-                            = new FileInputStream(element);
-
-                        try {
+                        try (InputStream inFileStream
+                             = Files.newInputStream(element.toPath())) {
                             if (element.getName().endsWith(".class")) {
 
                                 // create a data input stream from the jar
@@ -144,17 +133,13 @@
 
                                 nextElement = javaClass;
                             }
-                        } finally {
-                            inFileStream.close();
                         }
                     }
+                } else // this iterator is exhausted. Can we pop one off the stack
+                if (enumStack.isEmpty()) {
+                    break;
                 } else {
-                    // this iterator is exhausted. Can we pop one off the stack
-                    if (enumStack.empty()) {
-                        break;
-                    } else {
-                        currentEnum = (Enumeration) enumStack.pop();
-                    }
+                    currentIterator = enumStack.pop();
                 }
             }
         } catch (IOException e) {
@@ -165,4 +150,3 @@
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/JarFileIterator.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/JarFileIterator.java
index c468b95..cc2d60d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/JarFileIterator.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/JarFileIterator.java
@@ -41,7 +41,6 @@
      */
     public JarFileIterator(InputStream stream) throws IOException {
         super();
-
         jarStream = new ZipInputStream(stream);
     }
 
@@ -50,6 +49,7 @@
      *
      * @return a ClassFile object describing the class from the jar
      */
+    @Override
     public ClassFile getNextClassFile() {
         ZipEntry jarEntry;
         ClassFile nextElement = null;
@@ -69,7 +69,6 @@
 
                     nextElement = javaClass;
                 } else {
-
                     jarEntry = jarStream.getNextEntry();
                 }
             }
@@ -83,9 +82,7 @@
 
             throw new BuildException("Problem reading JAR file: " + text);
         }
-
         return nextElement;
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ClassCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ClassCPInfo.java
index 8abbfc8..a870fc7 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ClassCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ClassCPInfo.java
@@ -54,6 +54,7 @@
      * @exception IOException thrown if there is a problem reading the entry
      *      from the stream.
      */
+    @Override
     public void read(DataInputStream cpStream) throws IOException {
         index = cpStream.readUnsignedShort();
         className = "unresolved";
@@ -64,6 +65,7 @@
      *
      * @return string representation of this constant pool entry
      */
+    @Override
     public String toString() {
         return "Class Constant Pool Entry for " + className + "[" + index + "]";
     }
@@ -74,6 +76,7 @@
      * @param constantPool the constant pool with which to resolve the
      *      class.
      */
+    @Override
     public void resolve(ConstantPool constantPool) {
         className = ((Utf8CPInfo) constantPool.getEntry(index)).getValue();
 
@@ -90,4 +93,3 @@
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantCPInfo.java
index 6103422..1865c07 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantCPInfo.java
@@ -60,4 +60,3 @@
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPool.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPool.java
index fe35a4f..3a5f69c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPool.java
@@ -23,6 +23,8 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 /**
  * The constant pool of a Java class. The constant pool is a collection of
@@ -343,16 +345,11 @@
      *
      * @return the constant pool entries as strings
      */
+    @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder("\n");
-        final int size = entries.size();
-
-        for (int i = 0; i < size; ++i) {
-            sb.append('[').append(i).append("] = ").append(getEntry(i)).append('\n');
-        }
-
-        return sb.toString();
+        return IntStream.range(0, entries.size())
+            .mapToObj(i -> String.format("[%d] = %s", i, getEntry(i)))
+            .collect(Collectors.joining("\n", "\n", "\n"));
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPoolEntry.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPoolEntry.java
index 26a0d09..b639fa9 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPoolEntry.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPoolEntry.java
@@ -115,72 +115,57 @@
      */
     public static ConstantPoolEntry readEntry(DataInputStream cpStream)
          throws IOException {
-        ConstantPoolEntry cpInfo = null;
         int cpTag = cpStream.readUnsignedByte();
 
+        ConstantPoolEntry cpInfo;
         switch (cpTag) {
 
             case CONSTANT_UTF8:
                 cpInfo = new Utf8CPInfo();
-
                 break;
             case CONSTANT_INTEGER:
                 cpInfo = new IntegerCPInfo();
-
                 break;
             case CONSTANT_FLOAT:
                 cpInfo = new FloatCPInfo();
-
                 break;
             case CONSTANT_LONG:
                 cpInfo = new LongCPInfo();
-
                 break;
             case CONSTANT_DOUBLE:
                 cpInfo = new DoubleCPInfo();
-
                 break;
             case CONSTANT_CLASS:
                 cpInfo = new ClassCPInfo();
-
                 break;
             case CONSTANT_STRING:
                 cpInfo = new StringCPInfo();
-
                 break;
             case CONSTANT_FIELDREF:
                 cpInfo = new FieldRefCPInfo();
-
                 break;
             case CONSTANT_METHODREF:
                 cpInfo = new MethodRefCPInfo();
-
                 break;
             case CONSTANT_INTERFACEMETHODREF:
                 cpInfo = new InterfaceMethodRefCPInfo();
-
                 break;
             case CONSTANT_NAMEANDTYPE:
                 cpInfo = new NameAndTypeCPInfo();
-
                 break;
             case CONSTANT_METHODHANDLE:
                 cpInfo = new MethodHandleCPInfo();
-
                 break;
             case CONSTANT_METHODTYPE:
                 cpInfo = new MethodTypeCPInfo();
-
                 break;
             case CONSTANT_INVOKEDYNAMIC:
                 cpInfo = new InvokeDynamicCPInfo();
-
                 break;
             default:
                 throw new ClassFormatError("Invalid Constant Pool entry Type "
                      + cpTag);
         }
-
         cpInfo.read(cpStream);
 
         return cpInfo;
@@ -239,4 +224,3 @@
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/DoubleCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/DoubleCPInfo.java
index a21c0d6..5f28999 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/DoubleCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/DoubleCPInfo.java
@@ -41,8 +41,9 @@
      * @exception IOException if there is a problem reading the entry from the
      *      stream.
      */
+    @Override
     public void read(DataInputStream cpStream) throws IOException {
-        setValue(new Double(cpStream.readDouble()));
+        setValue(Double.valueOf(cpStream.readDouble()));
     }
 
     /**
@@ -50,9 +51,9 @@
      *
      * @return the string representation of this constant pool entry.
      */
+    @Override
     public String toString() {
         return "Double Constant Pool Entry: " + getValue();
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FieldRefCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FieldRefCPInfo.java
index 06c0925..1367b62 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FieldRefCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FieldRefCPInfo.java
@@ -49,6 +49,7 @@
      * @exception IOException if there is a problem reading the entry from
      *      the stream.
      */
+    @Override
     public void read(DataInputStream cpStream) throws IOException {
         classIndex = cpStream.readUnsignedShort();
         nameAndTypeIndex = cpStream.readUnsignedShort();
@@ -61,6 +62,7 @@
      * @param constantPool the constant pool of which this entry is a member
      *      and against which this entry is to be resolved.
      */
+    @Override
     public void resolve(ConstantPool constantPool) {
         ClassCPInfo fieldClass
             = (ClassCPInfo) constantPool.getEntry(classIndex);
@@ -85,18 +87,14 @@
      *
      * @return the string representation of this constant pool entry.
      */
+    @Override
     public String toString() {
-        String value;
-
         if (isResolved()) {
-            value = "Field : Class = " + fieldClassName + ", name = "
-                + fieldName + ", type = " + fieldType;
-        } else {
-            value = "Field : Class index = " + classIndex
-                + ", name and type index = " + nameAndTypeIndex;
+            return "Field : Class = " + fieldClassName + ", name = " + fieldName
+                + ", type = " + fieldType;
         }
-
-        return value;
+        return "Field : Class index = " + classIndex
+            + ", name and type index = " + nameAndTypeIndex;
     }
 
     /**
@@ -127,4 +125,3 @@
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FloatCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FloatCPInfo.java
index 532b672..d9bf465 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FloatCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FloatCPInfo.java
@@ -39,8 +39,9 @@
      * @exception IOException if there is a problem reading the entry from
      *      the stream.
      */
+    @Override
     public void read(DataInputStream cpStream) throws IOException {
-        setValue(new Float(cpStream.readFloat()));
+        setValue(Float.valueOf(cpStream.readFloat()));
     }
 
     /**
@@ -48,9 +49,9 @@
      *
      * @return the string representation of this constant pool entry.
      */
+    @Override
     public String toString() {
         return "Float Constant Pool Entry: " + getValue();
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/IntegerCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/IntegerCPInfo.java
index 3beaa8c..a3ecdaa 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/IntegerCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/IntegerCPInfo.java
@@ -39,8 +39,9 @@
      * @exception IOException if there is a problem reading the entry from
      *      the stream.
      */
+    @Override
     public void read(DataInputStream cpStream) throws IOException {
-        setValue(new Integer(cpStream.readInt()));
+        setValue(Integer.valueOf(cpStream.readInt()));
     }
 
     /**
@@ -48,9 +49,9 @@
      *
      * @return the string representation of this constant pool entry.
      */
+    @Override
     public String toString() {
         return "Integer Constant Pool Entry: " + getValue();
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InterfaceMethodRefCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InterfaceMethodRefCPInfo.java
index fbc23c1..5a3ba0f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InterfaceMethodRefCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InterfaceMethodRefCPInfo.java
@@ -55,6 +55,7 @@
      * @exception IOException if there is a problem reading the entry from
      *      the stream.
      */
+    @Override
     public void read(DataInputStream cpStream) throws IOException {
         classIndex = cpStream.readUnsignedShort();
         nameAndTypeIndex = cpStream.readUnsignedShort();
@@ -67,6 +68,7 @@
      * @param constantPool the constant pool of which this entry is a member
      *      and against which this entry is to be resolved.
      */
+    @Override
     public void resolve(ConstantPool constantPool) {
         ClassCPInfo interfaceMethodClass
              = (ClassCPInfo) constantPool.getEntry(classIndex);
@@ -91,19 +93,16 @@
      *
      * @return the string representation of this constant pool entry.
      */
+    @Override
     public String toString() {
-        String value;
-
         if (isResolved()) {
-            value = "InterfaceMethod : Class = " + interfaceMethodClassName
+            return "InterfaceMethod : Class = " + interfaceMethodClassName
                  + ", name = " + interfaceMethodName + ", type = "
                  + interfaceMethodType;
-        } else {
-            value = "InterfaceMethod : Class index = " + classIndex
-                 + ", name and type index = " + nameAndTypeIndex;
         }
+        return "InterfaceMethod : Class index = " + classIndex
+             + ", name and type index = " + nameAndTypeIndex;
 
-        return value;
     }
 
     /**
@@ -134,4 +133,3 @@
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InvokeDynamicCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InvokeDynamicCPInfo.java
index 3795db7..176b99a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InvokeDynamicCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InvokeDynamicCPInfo.java
@@ -32,7 +32,7 @@
     private int nameAndTypeIndex;
     /** the name and type CP info pointed to */
     private NameAndTypeCPInfo nameAndTypeCPInfo;
-    /** */
+
     /** Constructor.  */
     public InvokeDynamicCPInfo() {
         super(CONSTANT_INVOKEDYNAMIC, 1);
@@ -46,6 +46,7 @@
      * @exception java.io.IOException if there is a problem reading the entry from
      *      the stream.
      */
+    @Override
     public void read(DataInputStream cpStream) throws IOException {
         bootstrapMethodAttrIndex = cpStream.readUnsignedShort();
         nameAndTypeIndex = cpStream.readUnsignedShort();
@@ -56,16 +57,14 @@
      *
      * @return the string representation of this constant pool entry.
      */
+    @Override
     public String toString() {
-        String value;
         if (isResolved()) {
-            value = "Name = " + nameAndTypeCPInfo.getName() + ", type = " + nameAndTypeCPInfo.getType();
-        } else {
-            value = "BootstrapMethodAttrIndex inx = " + bootstrapMethodAttrIndex
-            + "NameAndType index = " + nameAndTypeIndex;
+            return "Name = " + nameAndTypeCPInfo.getName() + ", type = "
+                + nameAndTypeCPInfo.getType();
         }
-
-        return value;
+        return "BootstrapMethodAttrIndex inx = " + bootstrapMethodAttrIndex
+            + "NameAndType index = " + nameAndTypeIndex;
     }
     /**
      * Resolve this constant pool entry with respect to its dependents in
@@ -74,6 +73,7 @@
      * @param constantPool the constant pool of which this entry is a member
      *      and against which this entry is to be resolved.
      */
+    @Override
     public void resolve(ConstantPool constantPool) {
         nameAndTypeCPInfo
                 = (NameAndTypeCPInfo) constantPool.getEntry(nameAndTypeIndex);
@@ -82,4 +82,3 @@
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/LongCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/LongCPInfo.java
index e854f04..9e57a39 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/LongCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/LongCPInfo.java
@@ -39,8 +39,9 @@
      * @exception IOException if there is a problem reading the entry from
      *      the stream.
      */
+    @Override
     public void read(DataInputStream cpStream) throws IOException {
-        setValue(new Long(cpStream.readLong()));
+        setValue(Long.valueOf(cpStream.readLong()));
     }
 
     /**
@@ -48,9 +49,9 @@
      *
      * @return the string representation of this constant pool entry.
      */
+    @Override
     public String toString() {
         return "Long Constant Pool Entry: " + getValue();
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodHandleCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodHandleCPInfo.java
index a5906c7..f8fbbdb 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodHandleCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodHandleCPInfo.java
@@ -36,22 +36,23 @@
      * signature of the method
      */
     private int nameAndTypeIndex;
-    public enum ReferenceKind {
-        REF_getField(1),
-        REF_getStatic(2),
-        REF_putField(3),
-        REF_putStatic(4),
-        REF_invokeVirtual(5),
-        REF_invokeStatic(6),
-        REF_invokeSpecial(7),
-        REF_newInvokeSpecial(8),
-        REF_invokeInterface(9);
-        private final int referenceKind;
-        ReferenceKind(int referenceKind) {
-            this.referenceKind = referenceKind;
-        }
 
+    public enum ReferenceKind {
+        REF_getField,
+        REF_getStatic,
+        REF_putField,
+        REF_putStatic,
+        REF_invokeVirtual,
+        REF_invokeStatic,
+        REF_invokeSpecial,
+        REF_newInvokeSpecial,
+        REF_invokeInterface;
+
+        public int value() {
+            return ordinal() + 1;
+        }
     }
+
     /** Constructor. */
     public MethodHandleCPInfo() {
         super(CONSTANT_METHODHANDLE, 1);
@@ -65,9 +66,9 @@
      * @exception java.io.IOException if there is a problem reading the entry from
      *      the stream.
      */
+    @Override
     public void read(DataInputStream cpStream) throws IOException {
         referenceKind = ReferenceKind.values()[cpStream.readUnsignedByte() - 1];
-
         referenceIndex = cpStream.readUnsignedShort();
     }
 
@@ -76,17 +77,13 @@
      *
      * @return the string representation of this constant pool entry.
      */
+    @Override
     public String toString() {
-        String value;
-
         if (isResolved()) {
-            value = "MethodHandle : " + reference.toString();
-        } else {
-            value = "MethodHandle : Reference kind = " + referenceKind
-                 +  "Reference index = " + referenceIndex;
+            return "MethodHandle : " + reference.toString();
         }
-
-        return value;
+        return "MethodHandle : Reference kind = " + referenceKind
+            + "Reference index = " + referenceIndex;
     }
 
     /**
@@ -96,12 +93,11 @@
      * @param constantPool the constant pool of which this entry is a member
      *      and against which this entry is to be resolved.
      */
+    @Override
     public void resolve(ConstantPool constantPool) {
         reference = constantPool.getEntry(referenceIndex);
         reference.resolve(constantPool);
         super.resolve(constantPool);
     }
 
-
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodRefCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodRefCPInfo.java
index 6b33521..b90169f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodRefCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodRefCPInfo.java
@@ -52,6 +52,7 @@
      * @exception IOException if there is a problem reading the entry from
      *      the stream.
      */
+    @Override
     public void read(DataInputStream cpStream) throws IOException {
         classIndex = cpStream.readUnsignedShort();
         nameAndTypeIndex = cpStream.readUnsignedShort();
@@ -62,18 +63,14 @@
      *
      * @return the string representation of this constant pool entry.
      */
+    @Override
     public String toString() {
-        String value;
-
         if (isResolved()) {
-            value = "Method : Class = " + methodClassName + ", name = "
-                 + methodName + ", type = " + methodType;
-        } else {
-            value = "Method : Class index = " + classIndex
-                 + ", name and type index = " + nameAndTypeIndex;
+            return "Method : Class = " + methodClassName + ", name = "
+                + methodName + ", type = " + methodType;
         }
-
-        return value;
+        return "Method : Class index = " + classIndex
+            + ", name and type index = " + nameAndTypeIndex;
     }
 
     /**
@@ -83,6 +80,7 @@
      * @param constantPool the constant pool of which this entry is a member
      *      and against which this entry is to be resolved.
      */
+    @Override
     public void resolve(ConstantPool constantPool) {
         ClassCPInfo methodClass
              = (ClassCPInfo) constantPool.getEntry(classIndex);
@@ -130,4 +128,3 @@
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodTypeCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodTypeCPInfo.java
index d3c35ce..7b6f9a6 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodTypeCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodTypeCPInfo.java
@@ -30,6 +30,7 @@
     private int methodDescriptorIndex;
     /** the value of the method descriptor pointed to */
     private String methodDescriptor;
+
     /** Constructor.  */
     public MethodTypeCPInfo() {
         super(CONSTANT_METHODTYPE, 1);
@@ -63,6 +64,7 @@
         methodDescriptor = methodClass.getValue();
         super.resolve(constantPool);
     }
+
     /**
      * Print a readable version of the constant pool entry.
      *
@@ -70,13 +72,10 @@
      */
     @Override
     public String toString() {
-        if (!isResolved()) {
-            return "MethodDescriptorIndex: " + methodDescriptorIndex;
-        } else {
+        if (isResolved()) {
             return "MethodDescriptor: " + methodDescriptor;
-
         }
+        return "MethodDescriptorIndex: " + methodDescriptorIndex;
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/NameAndTypeCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/NameAndTypeCPInfo.java
index 47f454d..761808b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/NameAndTypeCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/NameAndTypeCPInfo.java
@@ -25,6 +25,20 @@
  *
  */
 public class NameAndTypeCPInfo extends ConstantPoolEntry {
+    /** the name component of this entry */
+    private String name;
+    /** the type component of this entry */
+    private String type;
+    /**
+     * the index into the constant pool at which the name component's string
+     * value is stored
+     */
+    private int nameIndex;
+    /**
+     * the index into the constant pool where the type descriptor string is
+     * stored.
+     */
+    private int descriptorIndex;
 
     /** Constructor. */
     public NameAndTypeCPInfo() {
@@ -39,6 +53,7 @@
      * @exception IOException if there is a problem reading the entry from
      *      the stream.
      */
+    @Override
     public void read(DataInputStream cpStream) throws IOException {
         nameIndex = cpStream.readUnsignedShort();
         descriptorIndex = cpStream.readUnsignedShort();
@@ -49,17 +64,13 @@
      *
      * @return the string representation of this constant pool entry.
      */
+    @Override
     public String toString() {
-        String value;
-
         if (isResolved()) {
-            value = "Name = " + name + ", type = " + type;
-        } else {
-            value = "Name index = " + nameIndex
-                 + ", descriptor index = " + descriptorIndex;
+            return "Name = " + name + ", type = " + type;
         }
-
-        return value;
+        return "Name index = " + nameIndex + ", descriptor index = "
+            + descriptorIndex;
     }
 
     /**
@@ -69,6 +80,7 @@
      * @param constantPool the constant pool of which this entry is a member
      *      and against which this entry is to be resolved.
      */
+    @Override
     public void resolve(ConstantPool constantPool) {
         name = ((Utf8CPInfo) constantPool.getEntry(nameIndex)).getValue();
         type = ((Utf8CPInfo) constantPool.getEntry(descriptorIndex)).getValue();
@@ -94,19 +106,4 @@
         return type;
     }
 
-    /** the name component of this entry */
-    private String name;
-    /** the type component of this entry */
-    private String type;
-    /**
-     * the index into the constant pool at which the name component's string
-     * value is stored
-     */
-    private int nameIndex;
-    /**
-     * the index into the constant pool where the type descriptor string is
-     * stored.
-     */
-    private int descriptorIndex;
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/StringCPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/StringCPInfo.java
index bc9ee24..7503403 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/StringCPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/StringCPInfo.java
@@ -26,6 +26,8 @@
  *
  */
 public class StringCPInfo extends ConstantCPInfo {
+    /** the index into the constant pool containing the string's content */
+    private int index;
 
     /** Constructor.  */
     public StringCPInfo() {
@@ -40,9 +42,9 @@
      * @exception IOException if there is a problem reading the entry from
      *      the stream.
      */
+    @Override
     public void read(DataInputStream cpStream) throws IOException {
         index = cpStream.readUnsignedShort();
-
         setValue("unresolved");
     }
 
@@ -51,6 +53,7 @@
      *
      * @return the string representation of this constant pool entry.
      */
+    @Override
     public String toString() {
         return "String Constant Pool Entry for "
             + getValue() + "[" + index + "]";
@@ -63,12 +66,11 @@
      * @param constantPool the constant pool of which this entry is a member
      *      and against which this entry is to be resolved.
      */
+    @Override
     public void resolve(ConstantPool constantPool) {
         setValue(((Utf8CPInfo) constantPool.getEntry(index)).getValue());
         super.resolve(constantPool);
     }
 
-    /** the index into the constant pool containing the string's content */
-    private int index;
 }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/Utf8CPInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/Utf8CPInfo.java
index 5471ccd..724bc9f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/Utf8CPInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/Utf8CPInfo.java
@@ -41,6 +41,7 @@
      * @exception IOException if there is a problem reading the entry from
      *      the stream.
      */
+    @Override
     public void read(DataInputStream cpStream) throws IOException {
         value = cpStream.readUTF();
     }
@@ -50,6 +51,7 @@
      *
      * @return the string representation of this constant pool entry.
      */
+    @Override
     public String toString() {
         return "UTF8 Value = " + value;
     }
@@ -64,4 +66,3 @@
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java
index 99694f6..7a60589 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java
@@ -26,16 +26,18 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Vector;
-
+import java.util.List;
+import java.util.Map;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.taskdefs.ExecTask;
 import org.apache.tools.ant.taskdefs.Execute;
 import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
 import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.taskdefs.optional.ejb.EjbJar.DTDLocation;
 import org.apache.tools.ant.types.Commandline;
 import org.apache.tools.ant.types.Path;
 
@@ -78,19 +80,18 @@
 public class BorlandDeploymentTool extends GenericDeploymentTool
                                    implements ExecuteStreamHandler {
     /** Borland 1.1 ejb id */
-    public static final String PUBLICID_BORLAND_EJB
-    = "-//Inprise Corporation//DTD Enterprise JavaBeans 1.1//EN";
+    public static final String PUBLICID_BORLAND_EJB =
+        "-//Inprise Corporation//DTD Enterprise JavaBeans 1.1//EN";
 
-    protected static final String DEFAULT_BAS45_EJB11_DTD_LOCATION
-    = "/com/inprise/j2ee/xml/dtds/ejb-jar.dtd";
+    protected static final String DEFAULT_BAS45_EJB11_DTD_LOCATION =
+        "/com/inprise/j2ee/xml/dtds/ejb-jar.dtd";
 
-    protected static final String DEFAULT_BAS_DTD_LOCATION
-    = "/com/inprise/j2ee/xml/dtds/ejb-inprise.dtd";
+    protected static final String DEFAULT_BAS_DTD_LOCATION =
+        "/com/inprise/j2ee/xml/dtds/ejb-inprise.dtd";
 
     protected static final String BAS_DD = "ejb-inprise.xml";
     protected static final String BES_DD = "ejb-borland.xml";
 
-
     /** Java2iiop executable **/
     protected static final String JAVA2IIOP = "java2iiop";
 
@@ -114,13 +115,13 @@
 
     /** Borland Enterprise Server = version 5 */
     static final int    BES       = 5;
+
     /** Borland Application Server or Inprise Application Server  = version 4 */
     static final int    BAS       = 4;
 
     /** borland appserver version 4 or 5 */
     private int version = BAS;
 
-
     /**
      * Instance variable that determines whether it is necessary to verify the
      * produced jar
@@ -128,7 +129,7 @@
     private boolean verify     = true;
     private String  verifyArgs = "";
 
-    private Hashtable genfiles = new Hashtable();
+    private Map<String, File> genfiles = new Hashtable<>();
 
     /**
      * set the debug mode for java2iiop (default false)
@@ -146,7 +147,6 @@
         this.verify = verify;
     }
 
-
     /**
      * Setter used to store the suffix for the generated borland jar file.
      * @param inString the string to use as the suffix.
@@ -155,7 +155,6 @@
         this.jarSuffix = inString;
     }
 
-
     /**
      * sets some additional args to send to verify command
      * @param args additional command line parameters
@@ -173,7 +172,6 @@
         this.borlandDTD = inString;
     }
 
-
     /**
      * setter used to store whether the task will include the generate client task.
      * (see : BorlandGenerateClient task)
@@ -200,7 +198,6 @@
         this.java2iioparams = params;
     }
 
-
     /**
      * Get the borland descriptor handler.
      * @param srcDir the source directory.
@@ -209,8 +206,9 @@
     protected DescriptorHandler getBorlandDescriptorHandler(final File srcDir) {
         DescriptorHandler handler =
             new DescriptorHandler(getTask(), srcDir) {
+                    @Override
                     protected void processElement() {
-                        if (currentElement.equals("type-storage")) {
+                        if ("type-storage".equals(currentElement)) {
                             // Get the filename of vendor specific descriptor
                             String fileNameWithMETA = currentText;
                             //trim the META_INF\ off of the file name
@@ -226,8 +224,7 @@
         handler.registerDTD(PUBLICID_BORLAND_EJB,
                             borlandDTD == null ? DEFAULT_BAS_DTD_LOCATION : borlandDTD);
 
-        for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
-            EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
+        for (DTDLocation dtdLocation : getConfig().dtdLocations) {
             handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
         }
         return handler;
@@ -239,14 +236,15 @@
      * @param ejbFiles the map to add the files to.
      * @param ddPrefix the prefix to use.
      */
-    protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+    @Override
+    protected void addVendorFiles(Hashtable<String, File> ejbFiles, String ddPrefix) {
 
         //choose the right vendor DD
         if (!(version == BES || version == BAS)) {
             throw new BuildException("version " + version + " is not supported");
         }
 
-        String dd = (version == BES ? BES_DD : BAS_DD);
+        String dd = (version == BES) ? BES_DD : BAS_DD;
 
         log("vendor file : " + ddPrefix + dd, Project.MSG_DEBUG);
 
@@ -265,6 +263,7 @@
      * Get the vendor specific name of the Jar that will be output. The modification date
      * of this jar will be checked against the dependent bean classes.
      */
+    @Override
     File getVendorOutputJarFile(String baseName) {
         return new File(getDestDir(), baseName +  jarSuffix);
     }
@@ -293,8 +292,7 @@
     private void verifyBorlandJarV5(File sourceJar) {
         log("verify BES " + sourceJar, Project.MSG_INFO);
         try {
-            ExecTask execTask = null;
-            execTask = new ExecTask(getTask());
+            ExecTask execTask = new ExecTask(getTask());
             execTask.setDir(new File("."));
             execTask.setExecutable("iastool");
             //classpath
@@ -314,9 +312,7 @@
             execTask.execute();
         } catch (Exception e) {
             // Have to catch this because of the semantics of calling main()
-            String msg = "Exception while calling generateclient Details: "
-                + e.toString();
-            throw new BuildException(msg, e);
+            throw new BuildException("Exception while calling generateclient Details: ", e);
         }
     }
 
@@ -353,7 +349,6 @@
         }
     }
 
-
     /**
      * Generate the client jar corresponding to the jar file passed as parameter
      * the method uses the BorlandGenerateClient task.
@@ -363,7 +358,7 @@
         getTask().getProject().addTaskDefinition("internal_bas_generateclient",
             org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient.class);
 
-        org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient gentask = null;
+        BorlandGenerateClient gentask;
         log("generate client for " + sourceJar, Project.MSG_INFO);
         try {
             Project project = getTask().getProject();
@@ -380,9 +375,7 @@
             gentask.execute();
         } catch (Exception e) {
             //TO DO : delete the file if it is not a valid file.
-            String msg = "Exception while calling " + VERIFY + " Details: "
-                + e.toString();
-            throw new BuildException(msg, e);
+            throw new BuildException("Exception while calling " + VERIFY, e);
         }
     }
 
@@ -391,10 +384,8 @@
      * Add all the generate class file into the ejb files
      * @param ithomes : iterator on home class
      */
-    private void buildBorlandStubs(Iterator ithomes) {
-        Execute execTask = null;
-
-        execTask = new Execute(this);
+    private void buildBorlandStubs(Collection<String> ithomes) {
+        Execute execTask = new Execute(this);
         Project project = getTask().getProject();
         execTask.setAntRun(project);
         execTask.setWorkingDirectory(project.getBaseDir());
@@ -418,16 +409,14 @@
             commandline.createArgument().setLine(java2iioparams);
         }
 
-
         //root dir
         commandline.createArgument().setValue("-root_dir");
         commandline.createArgument().setValue(getConfig().srcDir.getAbsolutePath());
         //compiling order
         commandline.createArgument().setValue("-compile");
         //add the home class
-        while (ithomes.hasNext()) {
-            commandline.createArgument().setValue(ithomes.next().toString());
-        }
+        ithomes.stream().map(Object::toString)
+            .forEach(v -> commandline.createArgument().setValue(v));
 
         try {
             log("Calling java2iiop", Project.MSG_VERBOSE);
@@ -435,11 +424,11 @@
             execTask.setCommandline(commandline.getCommandline());
             int result = execTask.execute();
             if (Execute.isFailure(result)) {
-                String msg = "Failed executing java2iiop (ret code is "
-                    + result + ")";
-                throw new BuildException(msg, getTask().getLocation());
+                throw new BuildException(
+                    "Failed executing java2iiop (ret code is " + result + ")",
+                    getTask().getLocation());
             }
-        } catch (java.io.IOException e) {
+        } catch (IOException e) {
             log("java2iiop exception :" + e.getMessage(), Project.MSG_ERR);
             throw new BuildException(e, getTask().getLocation());
         }
@@ -455,13 +444,13 @@
      * @param publicId the id to use.
      * @throws BuildException if there is an error.
      */
-    protected void writeJar(String baseName, File jarFile, Hashtable files, String publicId)
+    @Override
+    protected void writeJar(String baseName, File jarFile, Hashtable<String, File> files, String publicId)
         throws BuildException {
         //build the home classes list.
-        Vector homes = new Vector();
-        Iterator it = files.keySet().iterator();
-        while (it.hasNext()) {
-            String clazz = (String) it.next();
+        List<String> homes = new ArrayList<>();
+
+        for (String clazz : files.keySet()) {
             if (clazz.endsWith("Home.class")) {
                 //remove .class extension
                 String home = toClass(clazz);
@@ -470,7 +459,7 @@
             }
         }
 
-        buildBorlandStubs(homes.iterator());
+        buildBorlandStubs(homes);
 
         //add the gen files to the collection
         files.putAll(genfiles);
@@ -493,9 +482,8 @@
      */
     private String toClass(String filename) {
         //remove the .class
-        String classname = filename.substring(0, filename.lastIndexOf(".class"));
-        classname = classname.replace('\\', '.');
-        return classname;
+        return filename.substring(0, filename.lastIndexOf(".class"))
+            .replace('\\', '.').replace('/', '.');
     }
 
     /**
@@ -504,28 +492,35 @@
      */
     private  String toClassFile(String filename) {
         //remove the .class
-        String classfile = filename.substring(0, filename.lastIndexOf(".java"));
-        classfile = classfile + ".class";
-        return classfile;
+        return filename.replaceFirst("\\.java$", ".class");
     }
 
     // implementation of org.apache.tools.ant.taskdefs.ExecuteStreamHandler interface
 
     /** {@inheritDoc}. */
-    public void start() throws IOException  { }
+    @Override
+    public void start() throws IOException {
+    }
+
     /** {@inheritDoc}. */
-    public void stop()  {  }
+    @Override
+    public void stop() {
+    }
+
     /** {@inheritDoc}. */
-    public void setProcessInputStream(OutputStream param1) throws IOException   { }
+    @Override
+    public void setProcessInputStream(OutputStream param1) throws IOException {
+    }
 
     /**
      * Set the output stream of the process.
      * @param is the input stream.
      * @throws IOException if there is an error.
      */
+    @Override
     public void setProcessOutputStream(InputStream is) throws IOException {
-        try {
-            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+        try (BufferedReader reader =
+            new BufferedReader(new InputStreamReader(is))) {
             String javafile;
             while ((javafile = reader.readLine()) != null) {
                 if (javafile.endsWith(".java")) {
@@ -535,10 +530,8 @@
                     genfiles.put(key, new File(classfile));
                 }
             }
-            reader.close();
         } catch (Exception e) {
-            String msg = "Exception while parsing  java2iiop output. Details: " + e.toString();
-            throw new BuildException(msg, e);
+            throw new BuildException("Exception while parsing java2iiop output.", e);
         }
     }
 
@@ -547,6 +540,7 @@
      * @param is the input stream.
      * @throws IOException if there is an error.
      */
+    @Override
     public void setProcessErrorStream(InputStream is) throws IOException {
         BufferedReader reader = new BufferedReader(new InputStreamReader(is));
         String s = reader.readLine();
@@ -555,4 +549,3 @@
         }
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandGenerateClient.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandGenerateClient.java
index dd46269..87925e4 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandGenerateClient.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandGenerateClient.java
@@ -133,7 +133,6 @@
         createClasspath().setRefid(r);
     }
 
-
     /**
      * Do the work.
      *
@@ -141,6 +140,7 @@
      *
      * @exception BuildException if something goes wrong with the build
      */
+    @Override
     public void execute() throws BuildException {
         if (ejbjarfile == null || ejbjarfile.isDirectory()) {
             throw new BuildException("invalid ejb jar file.");
@@ -162,13 +162,12 @@
 
         if (!(version == BorlandDeploymentTool.BES
             || version == BorlandDeploymentTool.BAS)) {
-            throw new BuildException("version " + version
-                                      + " is not supported");
+            throw new BuildException("version %d is not supported", version);
         }
 
         log("client jar file is " + clientjarfile);
 
-        if (mode.equalsIgnoreCase(FORK_MODE)) {
+        if (FORK_MODE.equalsIgnoreCase(mode)) {
             executeFork();
         } else {
             executeJava();
@@ -182,15 +181,14 @@
     protected void executeJava() throws BuildException {
         try {
             if (version == BorlandDeploymentTool.BES)  {
-                throw new BuildException("java mode is supported only for "
-                    + "previous version <=" + BorlandDeploymentTool.BAS);
+                throw new BuildException(
+                    "java mode is supported only for previous version <= %d",
+                    BorlandDeploymentTool.BAS);
             }
 
             log("mode : java");
 
-            Java execTask = null;
-            execTask = new Java(this);
-
+            Java execTask = new Java(this);
             execTask.setDir(new File("."));
             execTask.setClassname("com.inprise.server.commandline.EJBUtilities");
             //classpath
@@ -218,8 +216,7 @@
 
         } catch (Exception e) {
             // Have to catch this because of the semantics of calling main()
-            String msg = "Exception while calling generateclient Details: " + e.toString();
-            throw new BuildException(msg, e);
+            throw new BuildException("Exception while calling generateclient", e);
         }
     }
 
@@ -227,7 +224,7 @@
      * launch the generate client using system api.
      * @throws BuildException if there is an error.
      */
-    protected  void executeFork() throws BuildException {
+    protected void executeFork() throws BuildException {
         if (version == BorlandDeploymentTool.BAS) {
             executeForkV4();
         }
@@ -240,13 +237,11 @@
      * launch the generate client using system api.
      * @throws BuildException if there is an error.
      */
-    protected  void executeForkV4() throws BuildException {
+    protected void executeForkV4() throws BuildException {
         try {
-
             log("mode : fork " + BorlandDeploymentTool.BAS, Project.MSG_DEBUG);
 
             ExecTask execTask = new ExecTask(this);
-
             execTask.setDir(new File("."));
             execTask.setExecutable("iastool");
             execTask.createArg().setValue("generateclient");
@@ -267,24 +262,19 @@
             execTask.execute();
         } catch (Exception e) {
             // Have to catch this because of the semantics of calling main()
-            String msg = "Exception while calling generateclient Details: "
-                + e.toString();
-            throw new BuildException(msg, e);
+            throw new BuildException("Exception while calling generateclient", e);
         }
-
     }
 
     /**
      * launch the generate client using system api.
      * @throws BuildException if there is an error.
      */
-    protected  void executeForkV5() throws BuildException {
+    protected void executeForkV5() throws BuildException {
         try {
             log("mode : fork " + BorlandDeploymentTool.BES, Project.MSG_DEBUG);
             ExecTask execTask = new ExecTask(this);
-
             execTask.setDir(new File("."));
-
             execTask.setExecutable("iastool");
             if (debug) {
                 execTask.createArg().setValue("-debug");
@@ -303,11 +293,8 @@
             execTask.execute();
         } catch (Exception e) {
             // Have to catch this because of the semantics of calling main()
-            String msg = "Exception while calling generateclient Details: "
-                + e.toString();
-            throw new BuildException(msg, e);
+            throw new BuildException("Exception while calling generateclient", e);
         }
-
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java
index 9ae0e67..eaef78c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java
@@ -19,12 +19,12 @@
 package org.apache.tools.ant.taskdefs.optional.ejb;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.nio.file.Files;
 import java.util.Hashtable;
+import java.util.Map;
 
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
@@ -96,20 +96,20 @@
      * put into the jar file, mapped to File objects  Accessed by the SAX
      * parser call-back method characters().
      */
-    protected Hashtable ejbFiles = null;
+    protected Hashtable<String, File> ejbFiles = null;
 
     /**
      * Instance variable that stores the value found in the &lt;ejb-name&gt; element
      */
     protected String ejbName = null;
 
-    private Hashtable fileDTDs = new Hashtable();
+    private Map<String, File> fileDTDs = new Hashtable<>();
 
-    private Hashtable resourceDTDs = new Hashtable();
+    private Map<String, String> resourceDTDs = new Hashtable<>();
 
     private boolean inEJBRef = false;
 
-    private Hashtable urlDTDs = new Hashtable();
+    private Map<String, URL> urlDTDs = new Hashtable<>();
     // CheckStyle:VisibilityModifier OFF - bc
 
     /**
@@ -184,22 +184,23 @@
      * @return an inputsource for this identifier
      * @throws SAXException if there is a problem.
      */
+    @Override
     public InputSource resolveEntity(String publicId, String systemId)
         throws SAXException {
         this.publicId = publicId;
 
-        File dtdFile = (File) fileDTDs.get(publicId);
+        File dtdFile = fileDTDs.get(publicId);
         if (dtdFile != null) {
             try {
                 owningTask.log("Resolved " + publicId + " to local file "
                     + dtdFile, Project.MSG_VERBOSE);
-                return new InputSource(new FileInputStream(dtdFile));
-            } catch (FileNotFoundException ex) {
+                return new InputSource(Files.newInputStream(dtdFile.toPath()));
+            } catch (IOException ex) {
                 // ignore
             }
         }
 
-        String dtdResourceName = (String) resourceDTDs.get(publicId);
+        String dtdResourceName = resourceDTDs.get(publicId);
         if (dtdResourceName != null) {
             InputStream is = this.getClass().getResourceAsStream(dtdResourceName);
             if (is != null) {
@@ -209,7 +210,7 @@
             }
         }
 
-        URL dtdUrl = (URL) urlDTDs.get(publicId);
+        URL dtdUrl = urlDTDs.get(publicId);
         if (dtdUrl != null) {
             try {
                 InputStream is = dtdUrl.openStream();
@@ -231,8 +232,8 @@
      * Getter method that returns the set of files to include in the EJB jar.
      * @return the map of files
      */
-    public Hashtable getFiles() {
-        return (ejbFiles == null) ? new Hashtable() : ejbFiles;
+    public Hashtable<String, File> getFiles() {
+        return ejbFiles == null ? new Hashtable<>() : ejbFiles;
     }
 
     /**
@@ -256,13 +257,13 @@
      * instance variables to ensure safe operation.
      * @throws SAXException on error
      */
+    @Override
     public void startDocument() throws SAXException {
-        this.ejbFiles = new Hashtable(DEFAULT_HASH_TABLE_SIZE, 1);
+        this.ejbFiles = new Hashtable<>(DEFAULT_HASH_TABLE_SIZE, 1);
         this.currentElement = null;
         inEJBRef = false;
     }
 
-
     /**
      * SAX parser call-back method that is invoked when a new element is entered
      * into.  Used to store the context (attribute name) in the currentAttribute
@@ -271,26 +272,26 @@
      * @param attrs Attributes associated to the element.
      * @throws SAXException on error
      */
+    @Override
     public void startElement(String name, AttributeList attrs)
         throws SAXException {
         this.currentElement = name;
         currentText = "";
-        if (name.equals(EJB_REF) || name.equals(EJB_LOCAL_REF)) {
+        if (EJB_REF.equals(name) || EJB_LOCAL_REF.equals(name)) {
             inEJBRef = true;
-        } else if (parseState == STATE_LOOKING_EJBJAR && name.equals(EJB_JAR)) {
+        } else if (parseState == STATE_LOOKING_EJBJAR && EJB_JAR.equals(name)) {
             parseState = STATE_IN_EJBJAR;
-        } else if (parseState == STATE_IN_EJBJAR && name.equals(ENTERPRISE_BEANS)) {
+        } else if (parseState == STATE_IN_EJBJAR && ENTERPRISE_BEANS.equals(name)) {
             parseState = STATE_IN_BEANS;
-        } else if (parseState == STATE_IN_BEANS && name.equals(SESSION_BEAN)) {
+        } else if (parseState == STATE_IN_BEANS && SESSION_BEAN.equals(name)) {
             parseState = STATE_IN_SESSION;
-        } else if (parseState == STATE_IN_BEANS && name.equals(ENTITY_BEAN)) {
+        } else if (parseState == STATE_IN_BEANS && ENTITY_BEAN.equals(name)) {
             parseState = STATE_IN_ENTITY;
-        } else if (parseState == STATE_IN_BEANS && name.equals(MESSAGE_BEAN)) {
+        } else if (parseState == STATE_IN_BEANS && MESSAGE_BEAN.equals(name)) {
             parseState = STATE_IN_MESSAGE;
         }
     }
 
-
     /**
      * SAX parser call-back method that is invoked when an element is exited.
      * Used to blank out (set to the empty string, not nullify) the name of
@@ -301,6 +302,7 @@
      *        in this implementation.
      * @throws SAXException on error
      */
+    @Override
     public void endElement(String name) throws SAXException {
         processElement();
         currentText = "";
@@ -336,13 +338,12 @@
      *        char array where the current data terminates.
      * @throws SAXException on error
      */
+    @Override
     public void characters(char[] ch, int start, int length)
         throws SAXException {
-
         currentText += new String(ch, start, length);
     }
 
-
     /**
      * Called when an endelement is seen.
      * This may be overridden in derived classes.
@@ -357,15 +358,14 @@
             return;
         }
 
-        if (currentElement.equals(HOME_INTERFACE)
-            || currentElement.equals(REMOTE_INTERFACE)
-            || currentElement.equals(LOCAL_INTERFACE)
-            || currentElement.equals(LOCAL_HOME_INTERFACE)
-            || currentElement.equals(BEAN_CLASS)
-            || currentElement.equals(PK_CLASS)) {
+        if (HOME_INTERFACE.equals(currentElement)
+            || REMOTE_INTERFACE.equals(currentElement)
+            || LOCAL_INTERFACE.equals(currentElement)
+            || LOCAL_HOME_INTERFACE.equals(currentElement)
+            || BEAN_CLASS.equals(currentElement)
+            || PK_CLASS.equals(currentElement)) {
 
             // Get the filename into a String object
-            File classFile = null;
             String className = currentText.trim();
 
             // If it's a primitive wrapper then we shouldn't try and put
@@ -376,8 +376,7 @@
                 // name, create the File object and add it to the Hashtable.
                 className = className.replace('.', File.separatorChar);
                 className += ".class";
-                classFile = new File(srcDir, className);
-                ejbFiles.put(className, classFile);
+                ejbFiles.put(className, new File(srcDir, className));
             }
         }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java
index 6ed8e34..2a1d70d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java
@@ -18,14 +18,11 @@
 
 package org.apache.tools.ant.taskdefs.optional.ejb;
 
-
-
 import javax.xml.parsers.SAXParser;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Task;
 
-
 /**
  * The interface to implement for deployment tools.
  */
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java
index 0728b75..afd440d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java
@@ -21,7 +21,6 @@
 // Standard java imports
 import java.io.File;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 import javax.xml.parsers.ParserConfigurationException;
@@ -103,12 +102,12 @@
         /**
          * A Fileset of support classes
          */
-        public List supportFileSets = new ArrayList();
+        public List<FileSet> supportFileSets = new ArrayList<>();
 
         /**
          * The list of configured DTD locations
          */
-        public ArrayList dtdLocations = new ArrayList();
+        public ArrayList<DTDLocation> dtdLocations = new ArrayList<>();
 
         /**
          * The naming scheme used to determine the generated jar name
@@ -162,6 +161,7 @@
          *
          * @return an array of the values of this attribute class.
          */
+        @Override
         public String[] getValues() {
             return new String[] {EJB_NAME, DIRECTORY, DESCRIPTOR, BASEJARNAME};
         }
@@ -178,20 +178,21 @@
         /** 2.0 value */
         public static final String CMP2_0 = "2.0";
         /** {@inheritDoc}. */
+        @Override
         public String[] getValues() {
-            return new String[]{
+            return new String[] {
                 CMP1_0,
                 CMP2_0,
             };
         }
     }
+
     /**
      * The config which is built by this task and used by the various deployment
      * tools to access the configuration of the ejbjar task
      */
     private Config config = new Config();
 
-
     /**
      * Stores a handle to the directory to put the Jar files in. This is
      * only used by the generic deployment descriptor tool which is created
@@ -207,7 +208,7 @@
     private String cmpVersion = CMPVersion.CMP1_0;
 
     /** The list of deployment tools we are going to run. */
-    private ArrayList deploymentTools = new ArrayList();
+    private List<EJBDeploymentTool> deploymentTools = new ArrayList<>();
 
     /**
      * Add a deployment tool to the list of deployment tools that will be
@@ -226,7 +227,7 @@
      * deployment tool for Orion server.
      *
      * @return the deployment tool instance to be configured.
-     * @since Ant 1.9.10
+     * @since Ant 1.10.2
      */
     public OrionDeploymentTool createOrion() {
         OrionDeploymentTool tool = new OrionDeploymentTool();
@@ -361,7 +362,6 @@
         return supportFileSet;
     }
 
-
     /**
      * Set the Manifest file to use when jarring. As of EJB 1.1, manifest
      * files are no longer used to configure the EJB. However, they still
@@ -422,10 +422,10 @@
         if (config.namingScheme == null) {
             config.namingScheme = new NamingScheme();
             config.namingScheme.setValue(NamingScheme.BASEJARNAME);
-        } else if (!config.namingScheme.getValue().equals(NamingScheme.BASEJARNAME)) {
-            throw new BuildException("The basejarname attribute is not "
-                + "compatible with the "
-                + config.namingScheme.getValue() + " naming scheme");
+        } else if (!NamingScheme.BASEJARNAME.equals(config.namingScheme.getValue())) {
+            throw new BuildException(
+                "The basejarname attribute is not compatible with the %s naming scheme",
+                config.namingScheme.getValue());
         }
     }
 
@@ -437,11 +437,11 @@
      */
     public void setNaming(NamingScheme namingScheme) {
         config.namingScheme = namingScheme;
-        if (!config.namingScheme.getValue().equals(NamingScheme.BASEJARNAME)
+        if (!NamingScheme.BASEJARNAME.equals(config.namingScheme.getValue())
             && config.baseJarName != null) {
-            throw new BuildException("The basejarname attribute is not "
-                + "compatible with the "
-                + config.namingScheme.getValue() + " naming scheme");
+            throw new BuildException(
+                "The basejarname attribute is not compatible with the %s naming scheme",
+                config.namingScheme.getValue());
         }
     }
 
@@ -559,10 +559,10 @@
         if (config.namingScheme == null) {
             config.namingScheme = new NamingScheme();
             config.namingScheme.setValue(NamingScheme.DESCRIPTOR);
-        } else if (config.namingScheme.getValue().equals(NamingScheme.BASEJARNAME)
+        } else if (NamingScheme.BASEJARNAME.equals(config.namingScheme.getValue())
                     && config.baseJarName == null) {
-            throw new BuildException("The basejarname attribute must "
-                + "be specified with the basejarname naming scheme");
+            throw new BuildException(
+                "The basejarname attribute must be specified with the basejarname naming scheme");
         }
     }
 
@@ -581,10 +581,11 @@
      *            encountered that cannot be recovered from, to signal to ant
      *            that a major problem occurred within this task.
      */
+    @Override
     public void execute() throws BuildException {
         validateConfig();
 
-        if (deploymentTools.size() == 0) {
+        if (deploymentTools.isEmpty()) {
             GenericDeploymentTool genericTool = new GenericDeploymentTool();
             genericTool.setTask(this);
             genericTool.setDestdir(destDir);
@@ -592,8 +593,7 @@
             deploymentTools.add(genericTool);
         }
 
-        for (Iterator i = deploymentTools.iterator(); i.hasNext();) {
-            EJBDeploymentTool tool = (EJBDeploymentTool) i.next();
+        for (EJBDeploymentTool tool : deploymentTools) {
             tool.configure(config);
             tool.validateConfigured();
         }
@@ -604,7 +604,6 @@
             saxParserFactory.setValidating(true);
             SAXParser saxParser = saxParserFactory.newSAXParser();
 
-
             DirectoryScanner ds = getDirectoryScanner(config.descriptorDir);
             ds.scan();
             String[] files = ds.getIncludedFiles();
@@ -614,30 +613,18 @@
 
             // Loop through the files. Each file represents one deployment
             // descriptor, and hence one bean in our model.
-            for (int index = 0; index < files.length; ++index) {
+            for (String file : files) {
                 // process the deployment descriptor in each tool
-                for (Iterator i = deploymentTools.iterator(); i.hasNext();) {
-                    EJBDeploymentTool tool = (EJBDeploymentTool) i.next();
-                    tool.processDescriptor(files[index], saxParser);
+                for (EJBDeploymentTool tool : deploymentTools) {
+                    tool.processDescriptor(file, saxParser);
                 }
             }
         } catch (SAXException se) {
-            String msg = "SAXException while creating parser."
-                + "  Details: "
-                + se.getMessage();
-            throw new BuildException(msg, se);
+            throw new BuildException("SAXException while creating parser.", se);
         } catch (ParserConfigurationException pce) {
-            String msg = "ParserConfigurationException while creating parser. "
-                       + "Details: " + pce.getMessage();
-            throw new BuildException(msg, pce);
+            throw new BuildException(
+                "ParserConfigurationException while creating parser. ", pce);
         }
     } // end of execute()
 
 }
-
-
-
-
-
-
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java
index 3329a8b..64672c9 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java
@@ -18,14 +18,13 @@
 package org.apache.tools.ant.taskdefs.optional.ejb;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Hashtable;
-import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
@@ -38,9 +37,9 @@
 import org.apache.tools.ant.Location;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.optional.ejb.EjbJar.DTDLocation;
 import org.apache.tools.ant.types.FileSet;
 import org.apache.tools.ant.types.Path;
-import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.depend.DependencyAnalyzer;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -119,7 +118,7 @@
      /**
      * Set of files have been loaded into the EJB jar
      */
-    private Set addedfiles;
+    private Set<String> addedfiles;
 
     /**
      * Handler used to parse the EJB XML descriptor
@@ -131,11 +130,6 @@
      */
     private DependencyAnalyzer dependencyAnalyzer;
 
-    /** No arg constructor */
-    public GenericDeploymentTool() {
-    }
-
-
     /**
      * Set the destination directory; required.
      * @param inDir the destination directory.
@@ -153,12 +147,12 @@
         return destDir;
     }
 
-
     /**
      * Set the task which owns this tool
      *
      * @param task the Task to which this deployment tool is associated.
      */
+    @Override
     public void setTask(Task task) {
         this.task = task;
     }
@@ -235,7 +229,6 @@
                 combinedPath.append(config.classpath);
             }
         }
-
         return combinedPath;
     }
 
@@ -278,9 +271,10 @@
         }
 
         try {
-            Class analyzerClass = Class.forName(analyzerClassName);
-            dependencyAnalyzer
-                = (DependencyAnalyzer) analyzerClass.newInstance();
+            Class<? extends DependencyAnalyzer> analyzerClass =
+                Class.forName(analyzerClassName)
+                    .asSubclass(DependencyAnalyzer.class);
+            dependencyAnalyzer = analyzerClass.newInstance();
             dependencyAnalyzer.addClassPath(new Path(task.getProject(),
                 config.srcDir.getPath()));
             dependencyAnalyzer.addClassPath(config.classpath);
@@ -297,12 +291,12 @@
         }
     }
 
-
     /**
      * Configure this tool for use in the ejbjar task.
      *
      * @param config the configuration from the surrounding ejbjar task.
      */
+    @Override
     public void configure(EjbJar.Config config) {
         this.config = config;
 
@@ -327,12 +321,11 @@
                                 File inputFile,
                                 String logicalFilename)
         throws BuildException {
-        FileInputStream iStream = null;
-        try {
-            if (!addedfiles.contains(logicalFilename)) {
-                iStream = new FileInputStream(inputFile);
+        if (!addedfiles.contains(logicalFilename)) {
+            try (InputStream iStream = Files.newInputStream(inputFile.toPath())) {
                 // Create the zip entry and add it to the jar file
-                ZipEntry zipEntry = new ZipEntry(logicalFilename.replace('\\', '/'));
+                ZipEntry zipEntry =
+                    new ZipEntry(logicalFilename.replace('\\', '/'));
                 jStream.putNextEntry(zipEntry);
 
                 // Create the file input stream, and buffer everything over
@@ -346,15 +339,12 @@
 
                 //add it to list of files in jar
                 addedfiles.add(logicalFilename);
-           }
-        } catch (IOException ioe) {
-            log("WARNING: IOException while adding entry "
-                + logicalFilename + " to jarfile from "
-                + inputFile.getPath() + " "  + ioe.getClass().getName()
-                + "-" + ioe.getMessage(), Project.MSG_WARN);
-        } finally {
-            // Close up the file input stream for the class file
-            FileUtils.close(iStream);
+            } catch (IOException ioe) {
+                log("WARNING: IOException while adding entry " + logicalFilename
+                    + " to jarfile from " + inputFile.getPath() + " "
+                    + ioe.getClass().getName() + "-" + ioe.getMessage(),
+                    Project.MSG_WARN);
+            }
         }
     }
 
@@ -369,8 +359,7 @@
         registerKnownDTDs(h);
 
         // register any DTDs supplied by the user
-        for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
-            EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
+        for (DTDLocation dtdLocation : getConfig().dtdLocations) {
             h.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
         }
         return h;
@@ -388,6 +377,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void processDescriptor(String descriptorFileName, SAXParser saxParser) {
 
         checkConfiguration(descriptorFileName, saxParser);
@@ -396,7 +386,7 @@
             handler = getDescriptorHandler(config.srcDir);
 
             // Retreive the files to be added to JAR from EJB descriptor
-            Hashtable ejbFiles = parseEjbFiles(descriptorFileName, saxParser);
+            Hashtable<String, File> ejbFiles = parseEjbFiles(descriptorFileName, saxParser);
 
             // Add any support classes specified in the build file
             addSupportClasses(ejbFiles);
@@ -411,8 +401,6 @@
                 ejbFiles.put(MANIFEST, manifestFile);
             }
 
-
-
             // First the regular deployment descriptor
             ejbFiles.put(META_DIR + EJB_DD,
                          new File(config.descriptorDir, descriptorFileName));
@@ -437,7 +425,6 @@
 
             File jarFile = getVendorOutputJarFile(baseName);
 
-
             // Check to see if we need a build and start doing the work!
             if (needToRebuild(ejbFiles, jarFile)) {
                 // Log that we are going to build...
@@ -451,27 +438,23 @@
                 // Use helper method to write the jarfile
                 String publicId = getPublicId();
                 writeJar(baseName, jarFile, ejbFiles, publicId);
-
             } else {
                 // Log that the file is up to date...
                 log(jarFile.toString() + " is up to date.",
                               Project.MSG_VERBOSE);
             }
-
         } catch (SAXException se) {
-            String msg = "SAXException while parsing '"
-                + descriptorFileName
-                + "'. This probably indicates badly-formed XML."
-                + "  Details: "
-                + se.getMessage();
-            throw new BuildException(msg, se);
+            throw new BuildException(
+                "SAXException while parsing '" + descriptorFileName
+                    + "'. This probably indicates badly-formed XML."
+                    + "  Details: " + se.getMessage(),
+                se);
         } catch (IOException ioe) {
-            String msg = "IOException while parsing'"
-                + descriptorFileName
-                + "'.  This probably indicates that the descriptor"
-                + " doesn't exist. Details: "
-                + ioe.getMessage();
-            throw new BuildException(msg, ioe);
+            throw new BuildException(
+                "IOException while parsing'" + descriptorFileName
+                    + "'.  This probably indicates that the descriptor"
+                    + " doesn't exist. Details: " + ioe.getMessage(),
+                ioe);
         }
     }
 
@@ -489,7 +472,6 @@
      */
     protected void checkConfiguration(String descriptorFileName,
                                     SAXParser saxParser) throws BuildException {
-
         /*
          * For the GenericDeploymentTool, do nothing.  Vendor specific
          * subclasses should throw a BuildException if the configuration is
@@ -512,28 +494,17 @@
      * @throws IOException       An IOException from the parser, possibly from a
      *                           the byte stream or character stream
      */
-    protected Hashtable parseEjbFiles(String descriptorFileName, SAXParser saxParser)
+    protected Hashtable<String, File> parseEjbFiles(String descriptorFileName, SAXParser saxParser)
                             throws IOException, SAXException {
-        FileInputStream descriptorStream = null;
-        Hashtable ejbFiles = null;
-
-        try {
-
-            /* Parse the ejb deployment descriptor.  While it may not
-             * look like much, we use a SAXParser and an inner class to
-             * get hold of all the classfile names for the descriptor.
-             */
-            descriptorStream
-                = new FileInputStream(new File(config.descriptorDir, descriptorFileName));
+        /* Parse the ejb deployment descriptor.  While it may not
+         * look like much, we use a SAXParser and an inner class to
+         * get hold of all the classfile names for the descriptor.
+         */
+        try (InputStream descriptorStream = Files.newInputStream(
+            new File(config.descriptorDir, descriptorFileName).toPath())) {
             saxParser.parse(new InputSource(descriptorStream), handler);
-
-            ejbFiles = handler.getFiles();
-
-        } finally {
-            FileUtils.close(descriptorStream);
+            return handler.getFiles();
         }
-
-        return ejbFiles;
     }
 
     /**
@@ -543,22 +514,18 @@
      * @param ejbFiles Hashtable of EJB classes (and other) files that will be
      *                 added to the completed JAR file
      */
-    protected void addSupportClasses(Hashtable ejbFiles) {
+    protected void addSupportClasses(Hashtable<String, File> ejbFiles) {
         // add in support classes if any
         Project project = task.getProject();
-        for (Iterator i = config.supportFileSets.iterator(); i.hasNext();) {
-            FileSet supportFileSet = (FileSet) i.next();
+        for (FileSet supportFileSet : config.supportFileSets) {
             File supportBaseDir = supportFileSet.getDir(project);
             DirectoryScanner supportScanner = supportFileSet.getDirectoryScanner(project);
-            supportScanner.scan();
-            String[] supportFiles = supportScanner.getIncludedFiles();
-            for (int j = 0; j < supportFiles.length; ++j) {
-                ejbFiles.put(supportFiles[j], new File(supportBaseDir, supportFiles[j]));
+            for (String supportFile : supportScanner.getIncludedFiles()) {
+                ejbFiles.put(supportFile, new File(supportBaseDir, supportFile));
             }
         }
     }
 
-
     /**
      * Using the EJB descriptor file name passed from the <code>ejbjar</code>
      * task, this method returns the "basename" which will be used to name the
@@ -574,14 +541,14 @@
         String baseName = "";
 
         // Work out what the base name is
-        if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.BASEJARNAME)) {
+        if (EjbJar.NamingScheme.BASEJARNAME.equals(config.namingScheme.getValue())) {
             String canonicalDescriptor = descriptorFileName.replace('\\', '/');
             int index = canonicalDescriptor.lastIndexOf('/');
             if (index != -1) {
                 baseName = descriptorFileName.substring(0, index + 1);
             }
             baseName += config.baseJarName;
-        } else if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.DESCRIPTOR)) {
+        } else if (EjbJar.NamingScheme.DESCRIPTOR.equals(config.namingScheme.getValue())) {
             int lastSeparatorIndex = descriptorFileName.lastIndexOf(File.separator);
             int endBaseName = -1;
             if (lastSeparatorIndex != -1) {
@@ -594,10 +561,11 @@
             if (endBaseName != -1) {
                 baseName = descriptorFileName.substring(0, endBaseName);
             } else {
-                throw new BuildException("Unable to determine jar name "
-                    + "from descriptor \"" + descriptorFileName + "\"");
+                throw new BuildException(
+                    "Unable to determine jar name from descriptor \"%s\"",
+                    descriptorFileName);
             }
-        } else if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.DIRECTORY)) {
+        } else if (EjbJar.NamingScheme.DIRECTORY.equals(config.namingScheme.getValue())) {
             File descriptorFile = new File(config.descriptorDir, descriptorFileName);
             String path = descriptorFile.getAbsolutePath();
             int lastSeparatorIndex
@@ -610,9 +578,8 @@
             if (dirSeparatorIndex != -1) {
                 dirName = dirName.substring(dirSeparatorIndex + 1);
             }
-
             baseName = dirName;
-        } else if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.EJB_NAME)) {
+        } else if (EjbJar.NamingScheme.EJB_NAME.equals(config.namingScheme.getValue())) {
             baseName = handler.getEjbName();
         }
         return baseName;
@@ -652,11 +619,10 @@
      * @param ejbFiles a hashtable entryname -&gt; file.
      * @param ddPrefix a prefix to use.
      */
-    protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+    protected void addVendorFiles(Hashtable<String, File> ejbFiles, String ddPrefix) {
         // nothing to add for generic tool.
     }
 
-
     /**
      * Get the vendor specific name of the Jar that will be output. The modification date
      * of this jar will be checked against the dependent bean classes.
@@ -683,16 +649,13 @@
      * @return         boolean indicating whether or not the <code>jarFile</code>
      *                 is up to date
      */
-    protected boolean needToRebuild(Hashtable ejbFiles, File jarFile) {
+    protected boolean needToRebuild(Hashtable<String, File> ejbFiles, File jarFile) {
         if (jarFile.exists()) {
             long lastBuild = jarFile.lastModified();
 
-            Iterator fileIter = ejbFiles.values().iterator();
-
             // Loop through the files seeing if any has been touched
             // more recently than the destination jar.
-            while (fileIter.hasNext()) {
-                File currentFile = (File) fileIter.next();
+            for (File currentFile : ejbFiles.values()) {
                 if (lastBuild < currentFile.lastModified()) {
                     log("Build needed because " + currentFile.getPath() + " is out of date",
                         Project.MSG_VERBOSE);
@@ -701,7 +664,6 @@
             }
             return false;
         }
-
         return true;
     }
 
@@ -733,7 +695,6 @@
         if (manifestFile.exists()) {
             return manifestFile;
         }
-
         if (config.manifest != null) {
             return config.manifest;
         }
@@ -750,17 +711,15 @@
      * @param publicId the id to use.
      * @throws BuildException if there is a problem.
      */
-    protected void writeJar(String baseName, File jarfile, Hashtable files,
+    protected void writeJar(String baseName, File jarfile, Hashtable<String, File> files,
                             String publicId) throws BuildException {
-
-        JarOutputStream jarStream = null;
+        // clean the addedfiles set
+        if (addedfiles == null) {
+            addedfiles = new HashSet<>();
+        } else {
+            addedfiles.clear();
+        }
         try {
-            // clean the addedfiles set
-            if (addedfiles == null) {
-                addedfiles = new HashSet();
-            } else {
-                addedfiles.clear();
-            }
 
             /* If the jarfile already exists then whack it and recreate it.
              * Should probably think of a more elegant way to handle this
@@ -776,18 +735,18 @@
             InputStream in = null;
             Manifest manifest = null;
             try {
-                File manifestFile = (File) files.get(MANIFEST);
+                File manifestFile = files.get(MANIFEST);
                 if (manifestFile != null && manifestFile.exists()) {
-                    in = new FileInputStream(manifestFile);
+                    in = Files.newInputStream(manifestFile.toPath());
                 } else {
                     String defaultManifest = "/org/apache/tools/ant/defaultManifest.mf";
                     in = this.getClass().getResourceAsStream(defaultManifest);
                     if (in == null) {
-                        throw new BuildException("Could not find "
-                            + "default manifest: " + defaultManifest);
+                        throw new BuildException(
+                            "Could not find default manifest: %s",
+                            defaultManifest);
                     }
                 }
-
                 manifest = new Manifest(in);
             } catch (IOException e) {
                 throw new BuildException("Unable to read manifest", e, getLocation());
@@ -799,46 +758,44 @@
 
             // Create the streams necessary to write the jarfile
 
-            jarStream = new JarOutputStream(new FileOutputStream(jarfile), manifest);
-            jarStream.setMethod(JarOutputStream.DEFLATED);
+            try (JarOutputStream jarStream = new JarOutputStream(
+                Files.newOutputStream(jarfile.toPath()), manifest)) {
+                jarStream.setMethod(JarOutputStream.DEFLATED);
 
-            // Loop through all the class files found and add them to the jar
-            for (Iterator entryIterator = files.keySet().iterator(); entryIterator.hasNext();) {
-                String entryName = (String) entryIterator.next();
-                if (entryName.equals(MANIFEST)) {
-                    continue;
-                }
+                // Loop through all the class files found and add them to the jar
+                for (Map.Entry<String, File> entryFiles : files.entrySet()) {
+                    String entryName = entryFiles.getKey();
+                    if (entryName.equals(MANIFEST)) {
+                        continue;
+                    }
+                    File entryFile = entryFiles.getValue();
+                    log("adding file '" + entryName + "'", Project.MSG_VERBOSE);
+                    addFileToJar(jarStream, entryFile, entryName);
 
-                File entryFile = (File) files.get(entryName);
+                    // See if there are any inner classes for this class and add them in if there are
+                    InnerClassFilenameFilter flt =
+                        new InnerClassFilenameFilter(entryFile.getName());
+                    File entryDir = entryFile.getParentFile();
+                    String[] innerfiles = entryDir.list(flt);
+                    if (innerfiles != null) {
+                        for (String innerfile : innerfiles) {
+                            //get and clean up innerclass name
+                            int entryIndex =
+                                entryName.lastIndexOf(entryFile.getName()) - 1;
+                            if (entryIndex < 0) {
+                                entryName = innerfile;
+                            } else {
+                                entryName = entryName.substring(0, entryIndex)
+                                    + File.separatorChar + innerfile;
+                            }
+                            // link the file
+                            entryFile = new File(config.srcDir, entryName);
 
-                log("adding file '" + entryName + "'",
-                              Project.MSG_VERBOSE);
-
-                addFileToJar(jarStream, entryFile, entryName);
-
-                // See if there are any inner classes for this class and add them in if there are
-                InnerClassFilenameFilter flt = new InnerClassFilenameFilter(entryFile.getName());
-                File entryDir = entryFile.getParentFile();
-                String[] innerfiles = entryDir.list(flt);
-                if (innerfiles != null) {
-                    for (int i = 0, n = innerfiles.length; i < n; i++) {
-
-                        //get and clean up innerclass name
-                        int entryIndex = entryName.lastIndexOf(entryFile.getName()) - 1;
-                        if (entryIndex < 0) {
-                            entryName = innerfiles[i];
-                        } else {
-                            entryName = entryName.substring(0, entryIndex)
-                                + File.separatorChar + innerfiles[i];
-                        }
-                        // link the file
-                        entryFile = new File(config.srcDir, entryName);
-
-                        log("adding innerclass file '" + entryName + "'",
+                            log("adding innerclass file '" + entryName + "'",
                                 Project.MSG_VERBOSE);
 
-                        addFileToJar(jarStream, entryFile, entryName);
-
+                            addFileToJar(jarStream, entryFile, entryName);
+                        }
                     }
                 }
             }
@@ -848,8 +805,6 @@
                 + "'. Details: "
                 + ioe.getMessage();
             throw new BuildException(msg, ioe);
-        } finally {
-            FileUtils.close(jarStream);
         }
     } // end of writeJar
 
@@ -859,7 +814,7 @@
      * @param checkEntries files, that are extracted from the deployment descriptor
      * @throws BuildException if there is a problem.
      */
-    protected void checkAndAddDependants(Hashtable checkEntries)
+    protected void checkAndAddDependants(Hashtable<String, File> checkEntries)
         throws BuildException {
 
         if (dependencyAnalyzer == null) {
@@ -868,9 +823,7 @@
 
         dependencyAnalyzer.reset();
 
-        Iterator i = checkEntries.keySet().iterator();
-        while (i.hasNext()) {
-            String entryName = (String) i.next();
+        for (String entryName : checkEntries.keySet()) {
             if (entryName.endsWith(".class")) {
                 String className = entryName.substring(0,
                     entryName.length() - ".class".length());
@@ -881,10 +834,10 @@
             }
         }
 
-        Enumeration e = dependencyAnalyzer.getClassDependencies();
+        Enumeration<String> e = dependencyAnalyzer.getClassDependencies();
 
         while (e.hasMoreElements()) {
-            String classname = (String) e.nextElement();
+            String classname = e.nextElement();
             String location
                 = classname.replace('.', File.separatorChar) + ".class";
             File classFile = new File(config.srcDir, location);
@@ -896,7 +849,6 @@
         }
     }
 
-
     /**
      * Returns a Classloader object which parses the passed in generic EjbJar classpath.
      * The loader is used to dynamically load classes from javax.ejb.* and the classes
@@ -907,7 +859,6 @@
         if (classpathLoader != null) {
             return classpathLoader;
         }
-
         Path combinedClasspath = getCombinedClasspath();
 
         // only generate a new ClassLoader if we have a classpath
@@ -918,7 +869,6 @@
             classpathLoader
                 = getTask().getProject().createClassLoader(combinedClasspath);
         }
-
         return classpathLoader;
     }
 
@@ -928,11 +878,12 @@
      * @throws BuildException If the Deployment Tool's configuration isn't
      *                        valid
      */
+    @Override
     public void validateConfigured() throws BuildException {
         if ((destDir == null) || (!destDir.isDirectory())) {
-            String msg = "A valid destination directory must be specified "
-                            + "using the \"destdir\" attribute.";
-            throw new BuildException(msg, getLocation());
+            throw new BuildException(
+                "A valid destination directory must be specified using the \"destdir\" attribute.",
+                getLocation());
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetDeploymentTool.java
index 790cad6..fd7517f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetDeploymentTool.java
@@ -21,12 +21,12 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.Hashtable;
-import java.util.Iterator;
 
 import javax.xml.parsers.SAXParser;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.optional.ejb.EjbJar.DTDLocation;
 import org.xml.sax.SAXException;
 
 /**
@@ -105,7 +105,7 @@
      * we may determine the name of the EJB JAR file using this display-name,
      * but this has not be implemented yet.
      */
-    private String  displayName;
+    private String displayName;
 
     /*
      * Regardless of the name of the iAS-specific EJB descriptor file, it will
@@ -200,25 +200,26 @@
         int startOfName = descriptorFileName.lastIndexOf(File.separatorChar) + 1;
         String stdXml = descriptorFileName.substring(startOfName);
         if (stdXml.equals(EJB_DD) && (getConfig().baseJarName == null)) {
-            String msg = "No name specified for the completed JAR file.  The EJB"
-                            + " descriptor should be prepended with the JAR "
-                            + "name or it should be specified using the "
-                            + "attribute \"basejarname\" in the \"ejbjar\" task.";
-            throw new BuildException(msg, getLocation());
+            throw new BuildException(
+                "No name specified for the completed JAR file.  The EJB"
+                    + " descriptor should be prepended with the JAR "
+                    + "name or it should be specified using the "
+                    + "attribute \"basejarname\" in the \"ejbjar\" task.",
+                getLocation());
         }
 
         File iasDescriptor = new File(getConfig().descriptorDir,
                                         getIasDescriptorName());
         if ((!iasDescriptor.exists()) || (!iasDescriptor.isFile())) {
-            String msg = "The iAS-specific EJB descriptor ("
-                            + iasDescriptor + ") was not found.";
-            throw new BuildException(msg, getLocation());
+            throw new BuildException("The iAS-specific EJB descriptor ("
+                + iasDescriptor + ") was not found.", getLocation());
         }
 
         if ((iashome != null) && (!iashome.isDirectory())) {
-            String msg = "If \"iashome\" is specified, it must be a valid "
-                            + "directory (it was set to " + iashome + ").";
-            throw new BuildException(msg, getLocation());
+            throw new BuildException(
+                "If \"iashome\" is specified, it must be a valid directory (it was set to "
+                    + iashome + ").",
+                getLocation());
         }
     }
 
@@ -238,10 +239,10 @@
      *                           exception
      */
     @Override
-    protected Hashtable parseEjbFiles(String descriptorFileName,
+    protected Hashtable<String, File> parseEjbFiles(String descriptorFileName,
                          SAXParser saxParser) throws IOException, SAXException {
 
-        Hashtable files;
+        Hashtable<String, File> files;
 
         /* Build and populate an instance of the ejbc utility */
         IPlanetEjbc ejbc = new IPlanetEjbc(
@@ -258,12 +259,9 @@
             ejbc.setIasHomeDir(iashome);
         }
         if (getConfig().dtdLocations != null) {
-            for (Iterator i = getConfig().dtdLocations.iterator();
-                 i.hasNext();) {
-                EjbJar.DTDLocation dtdLocation =
-                    (EjbJar.DTDLocation) i.next();
+            for (DTDLocation dtdLocation : getConfig().dtdLocations) {
                 ejbc.registerDTD(dtdLocation.getPublicId(),
-                                 dtdLocation.getLocation());
+                    dtdLocation.getLocation());
             }
         }
 
@@ -290,7 +288,7 @@
                 int endOfCmp = cmpDescriptors[i].lastIndexOf('/');
                 String cmpDescriptor = cmpDescriptors[i].substring(endOfCmp + 1);
 
-                File   cmpFile = new File(baseDir, relativePath + cmpDescriptor);
+                File cmpFile = new File(baseDir, relativePath + cmpDescriptor);
                 if (!cmpFile.exists()) {
                     throw new BuildException("The CMP descriptor file ("
                             + cmpFile + ") could not be found.", getLocation());
@@ -298,7 +296,6 @@
                 files.put(cmpDescriptors[i], cmpFile);
             }
         }
-
         return files;
     }
 
@@ -311,7 +308,7 @@
      * @param ddPrefix not used
      */
     @Override
-    protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+    protected void addVendorFiles(Hashtable<String, File> ejbFiles, String ddPrefix) {
         ejbFiles.put(META_DIR + IAS_DD, new File(getConfig().descriptorDir,
                      getIasDescriptorName()));
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbc.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbc.java
index 447a288..df0f0ee 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbc.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbc.java
@@ -20,12 +20,15 @@
 
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.time.Instant;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.ArrayList;
-import java.util.Date;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Iterator;
@@ -33,6 +36,8 @@
 import java.util.Map;
 import java.util.Properties;
 import java.util.StringTokenizer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
@@ -41,8 +46,6 @@
 import org.xml.sax.HandlerBase;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
-
-import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.StringUtils;
 
 /**
@@ -111,7 +114,7 @@
      * (relative to the destination directory).  The value for the Hashtable is
      * a File object which reference the actual class file.
      */
-    private Hashtable   ejbFiles     = new Hashtable();
+    private Hashtable<String, File>   ejbFiles     = new Hashtable<>();
 
     /* Value of the display-name element read from the standard EJB descriptor */
     private String      displayName;
@@ -147,15 +150,11 @@
          * Parse the classpath into it's individual elements and store the
          * results in the "classpathElements" instance variable.
          */
-        List elements = new ArrayList();
         if (classpath != null) {
             StringTokenizer st = new StringTokenizer(classpath,
                                                         File.pathSeparator);
-            while (st.hasMoreTokens()) {
-                elements.add(st.nextToken());
-            }
-            classpathElements
-                    = (String[]) elements.toArray(new String[elements.size()]);
+            final int count = st.countTokens();
+            classpathElements = Collections.list(st).toArray(new String[count]);
         }
     }
 
@@ -214,7 +213,7 @@
      *
      * @return The list of EJB files processed by the ejbc utility.
      */
-    public Hashtable getEjbFiles() {
+    public Hashtable<String, File> getEjbFiles() {
         return ejbFiles;
     }
 
@@ -233,16 +232,8 @@
      * @return An array of CMP descriptors.
      */
     public String[] getCmpDescriptors() {
-        List returnList = new ArrayList();
-
-        EjbInfo[] ejbs = handler.getEjbs();
-
-        for (int i = 0; i < ejbs.length; i++) {
-            List descriptors = (List) ejbs[i].getCmpDescriptors();
-            returnList.addAll(descriptors);
-        }
-
-        return (String[]) returnList.toArray(new String[returnList.size()]);
+        return Stream.of(handler.getEjbs()).map(EjbInfo::getCmpDescriptors)
+            .flatMap(Collection::stream).toArray(String[]::new);
     }
 
     /**
@@ -271,13 +262,13 @@
         iasDescriptor = new File(args[args.length - 1]);
 
         for (int i = 0; i < args.length - 2; i++) {
-            if (args[i].equals("-classpath")) {
+            if ("-classpath".equals(args[i])) {
                 classpath = args[++i];
-            } else if (args[i].equals("-d")) {
+            } else if ("-d".equals(args[i])) {
                 destDirectory = new File(args[++i]);
-            } else if (args[i].equals("-debug")) {
+            } else if ("-debug".equals(args[i])) {
                 debug = true;
-            } else if (args[i].equals("-keepsource")) {
+            } else if ("-keepsource".equals(args[i])) {
                 retainSource = true;
             } else {
                 usage();
@@ -377,22 +368,17 @@
 
         EjbInfo[] ejbs = getEjbs(); // Returns list of EJBs for processing
 
-        for (int i = 0; i < ejbs.length; i++) {
+        for (EjbInfo ejb : ejbs) {
             log("EJBInfo...");
-            log(ejbs[i].toString());
+            log(ejb.toString());
         }
 
-        for (int i = 0; i < ejbs.length; i++) {
-            EjbInfo ejb = ejbs[i];
-
+        for (EjbInfo ejb : ejbs) {
             ejb.checkConfiguration(destDirectory);  // Throws EjbcException
 
             if (ejb.mustBeRecompiled(destDirectory)) {
                 log(ejb.getName() + " must be recompiled using ejbc.");
-
-                String[] arguments = buildArgumentList(ejb);
-                callEjbc(arguments);
-
+                callEjbc(buildArgumentList(ejb));
             } else {
                 log(ejb.getName() + " is up to date.");
             }
@@ -406,11 +392,6 @@
      */
     private void callEjbc(String[] arguments) {
 
-        /* Concatenate all of the command line arguments into a single String */
-        StringBuffer args = new StringBuffer();
-        for (int i = 0; i < arguments.length; i++) {
-            args.append(arguments[i]).append(" ");
-        }
 
         /* If an iAS home directory is specified, prepend it to the command */
         String command;
@@ -422,6 +403,9 @@
         }
         command += "ejbc ";
 
+        /* Concatenate all of the command line arguments into a single String */
+        String args = Stream.of(arguments).collect(Collectors.joining(" "));
+
         log(command + args);
 
         /*
@@ -492,18 +476,14 @@
      *                       XML descriptor (it may wrap another exception)
      */
     private EjbInfo[] getEjbs() throws IOException, SAXException {
-        EjbInfo[] ejbs = null;
 
         /*
          * The EJB information is gathered from the standard XML EJB descriptor
          * and the iAS-specific XML EJB descriptor using a SAX parser.
          */
-
         parser.parse(stdDescriptor, handler);
         parser.parse(iasDescriptor, handler);
-        ejbs = handler.getEjbs();
-
-        return ejbs;
+        return handler.getEjbs();
     }
 
     /**
@@ -516,7 +496,7 @@
      */
     private String[] buildArgumentList(EjbInfo ejb) {
 
-        List arguments = new ArrayList();
+        List<String> arguments = new ArrayList<>();
 
         /* OPTIONAL COMMAND LINE PARAMETERS */
 
@@ -560,7 +540,7 @@
         arguments.add(ejb.getImplementation().getQualifiedClassName());
 
         /* Convert the List into an Array and return it */
-        return (String[]) arguments.toArray(new String[arguments.size()]);
+        return arguments.toArray(new String[arguments.size()]);
     }
 
     /**
@@ -585,6 +565,7 @@
      *
      */
     public class EjbcException extends Exception {
+        private static final long serialVersionUID = 1L;
 
         /**
          * Constructs an exception with the given descriptive message.
@@ -625,10 +606,10 @@
          * remote copies of these DTDs cannot be accessed.  The key for the Map
          * is the DTDs public ID and the value is the local location for the DTD
          */
-        private Map       resourceDtds = new HashMap();
-        private Map       fileDtds = new HashMap();
+        private Map<String, String>       resourceDtds = new HashMap<>();
+        private Map<String, String>       fileDtds = new HashMap<>();
 
-        private Map       ejbs = new HashMap();      // List of EJBs found in XML
+        private Map<String, EjbInfo>       ejbs = new HashMap<>();      // List of EJBs found in XML
         private EjbInfo   currentEjb;             // One item within the Map
         private boolean   iasDescriptor = false;  // Is doc iAS or EJB descriptor
 
@@ -654,7 +635,7 @@
          *         parsing.
          */
         public EjbInfo[] getEjbs() {
-            return (EjbInfo[]) ejbs.values().toArray(new EjbInfo[ejbs.size()]);
+            return ejbs.values().toArray(new EjbInfo[ejbs.size()]);
         }
 
         /**
@@ -707,35 +688,30 @@
          * @param publicId The DTD's public identifier.
          * @param systemId The location of the DTD, as found in the XML document.
          */
+        @Override
         public InputSource resolveEntity(String publicId, String systemId)
                 throws SAXException {
             InputStream inputStream = null;
 
-
             try {
-
                 /* Search the resource Map and (if not found) file Map */
-
-                String location = (String) resourceDtds.get(publicId);
+                String location = resourceDtds.get(publicId);
                 if (location != null) {
                     inputStream
                         = ClassLoader.getSystemResource(location).openStream();
                 } else {
-                    location = (String) fileDtds.get(publicId);
+                    location = fileDtds.get(publicId);
                     if (location != null) {
                         // closed when the InputSource is closed
-                        inputStream = new FileInputStream(location); //NOSONAR
+                        inputStream = Files.newInputStream(Paths.get(location)); //NOSONAR
                     }
                 }
-            } catch (IOException e) {
-                return super.resolveEntity(publicId, systemId);
+            } catch (IOException ignored) {
             }
-
             if (inputStream == null) {
                 return super.resolveEntity(publicId, systemId);
-            } else {
-                return new InputSource(inputStream);
             }
+            return new InputSource(inputStream);
         }
 
         /**
@@ -746,6 +722,7 @@
          *             (if any).
          * @throws SAXException If the parser cannot process the document.
          */
+        @Override
         public void startElement(String name, AttributeList atts)
                 throws SAXException {
 
@@ -758,13 +735,13 @@
             /* A new element has started, so reset the text being captured */
             currentText = "";
 
-            if (currentLoc.equals("\\ejb-jar")) {
+            if ("\\ejb-jar".equals(currentLoc)) {
                 iasDescriptor = false;
-            } else if (currentLoc.equals("\\ias-ejb-jar")) {
+            } else if ("\\ias-ejb-jar".equals(currentLoc)) {
                 iasDescriptor = true;
             }
 
-            if ((name.equals("session")) || (name.equals("entity"))) {
+            if (("session".equals(name)) || ("entity".equals(name))) {
                 ejbType = name;
             }
         }
@@ -778,9 +755,9 @@
          * @param len The number of characters found in the document.
          * @throws SAXException If the parser cannot process the document.
          */
+        @Override
         public void characters(char[] ch, int start, int len)
                 throws SAXException {
-
             currentText += new String(ch).substring(start, start + len);
         }
 
@@ -790,6 +767,7 @@
          * @param name String name of the element.
          * @throws SAXException If the parser cannot process the document.
          */
+        @Override
         public void endElement(String name) throws SAXException {
 
             /*
@@ -825,30 +803,30 @@
          */
         private void stdCharacters(String value) {
 
-            if (currentLoc.equals("\\ejb-jar\\display-name")) {
+            if ("\\ejb-jar\\display-name".equals(currentLoc)) {
                 displayName = value;
                 return;
             }
 
             String base = "\\ejb-jar\\enterprise-beans\\" + ejbType;
 
-            if (currentLoc.equals(base + "\\ejb-name")) {
-                currentEjb = (EjbInfo) ejbs.get(value);
+            if ((base + "\\ejb-name").equals(currentLoc)) {
+                currentEjb = ejbs.get(value);
                 if (currentEjb == null) {
                     currentEjb = new EjbInfo(value);
                     ejbs.put(value, currentEjb);
                 }
-            } else if (currentLoc.equals(base + "\\home")) {
+            } else if ((base + "\\home").equals(currentLoc)) {
                 currentEjb.setHome(value);
-            } else if (currentLoc.equals(base + "\\remote")) {
+            } else if ((base + "\\remote").equals(currentLoc)) {
                 currentEjb.setRemote(value);
-            } else if (currentLoc.equals(base + "\\ejb-class")) {
+            } else if ((base + "\\ejb-class").equals(currentLoc)) {
                 currentEjb.setImplementation(value);
-            } else if (currentLoc.equals(base + "\\prim-key-class")) {
+            } else if ((base + "\\prim-key-class").equals(currentLoc)) {
                 currentEjb.setPrimaryKey(value);
-            } else if (currentLoc.equals(base + "\\session-type")) {
+            } else if ((base + "\\session-type").equals(currentLoc)) {
                 currentEjb.setBeantype(value);
-            } else if (currentLoc.equals(base + "\\persistence-type")) {
+            } else if ((base + "\\persistence-type").equals(currentLoc)) {
                 currentEjb.setCmp(value);
             }
         }
@@ -866,18 +844,19 @@
         private void iasCharacters(String value) {
             String base = "\\ias-ejb-jar\\enterprise-beans\\" + ejbType;
 
-            if (currentLoc.equals(base + "\\ejb-name")) {
-                currentEjb = (EjbInfo) ejbs.get(value);
+            if ((base + "\\ejb-name").equals(currentLoc)) {
+                currentEjb = ejbs.get(value);
                 if (currentEjb == null) {
                     currentEjb = new EjbInfo(value);
                     ejbs.put(value, currentEjb);
                 }
-            } else if (currentLoc.equals(base + "\\iiop")) {
+            } else if ((base + "\\iiop").equals(currentLoc)) {
                 currentEjb.setIiop(value);
-            } else if (currentLoc.equals(base + "\\failover-required")) {
+            } else if ((base + "\\failover-required").equals(currentLoc)) {
                 currentEjb.setHasession(value);
-            } else if (currentLoc.equals(base + "\\persistence-manager"
-                                              + "\\properties-file-location")) {
+            } else if ((base
+                + "\\persistence-manager\\properties-file-location")
+                    .equals(currentLoc)) {
                 currentEjb.addCmpDescriptor(value);
             }
         }
@@ -898,7 +877,7 @@
         private boolean cmp       = false;      // Does this EJB support CMP?
         private boolean iiop      = false;      // Does this EJB support IIOP?
         private boolean hasession = false;      // Does this EJB require failover?
-        private List cmpDescriptors = new ArrayList();  // CMP descriptor list
+        private List<String> cmpDescriptors = new ArrayList<>();  // CMP descriptor list
 
         /**
          * Construct a new EJBInfo object with the given name.
@@ -920,9 +899,8 @@
             if (name == null) {
                 if (implementation == null) {
                     return "[unnamed]";
-                } else {
-                    return implementation.getClassName();
                 }
+                return implementation.getClassName();
             }
             return name;
         }
@@ -996,7 +974,7 @@
         }
 
         public void setCmp(String cmp) {
-            setCmp(cmp.equals("Container"));
+            setCmp("Container".equals(cmp));
         }
 
         public boolean getCmp() {
@@ -1008,7 +986,7 @@
         }
 
         public void setIiop(String iiop) {
-            setIiop(iiop.equals("true"));
+            setIiop(Boolean.parseBoolean(iiop));
         }
 
         public boolean getIiop() {
@@ -1020,7 +998,7 @@
         }
 
         public void setHasession(String hasession) {
-            setHasession(hasession.equals("true"));
+            setHasession(Boolean.parseBoolean(hasession));
         }
 
         public boolean getHasession() {
@@ -1031,7 +1009,7 @@
             cmpDescriptors.add(descriptor);
         }
 
-        public List getCmpDescriptors() {
+        public List<String> getCmpDescriptors() {
             return cmpDescriptors;
         }
 
@@ -1048,53 +1026,53 @@
 
             /* Check that the specified instance variables are valid */
             if (home == null) {
-                throw new EjbcException("A home interface was not found "
-                            + "for the " + name + " EJB.");
+                throw new EjbcException(
+                    "A home interface was not found for the " + name + " EJB.");
             }
             if (remote == null) {
-                throw new EjbcException("A remote interface was not found "
-                            + "for the " + name + " EJB.");
+                throw new EjbcException(
+                    "A remote interface was not found for the " + name
+                        + " EJB.");
             }
             if (implementation == null) {
-                throw new EjbcException("An EJB implementation class was not "
-                            + "found for the " + name + " EJB.");
+                throw new EjbcException(
+                    "An EJB implementation class was not found for the " + name
+                        + " EJB.");
             }
 
             if ((!beantype.equals(ENTITY_BEAN))
-                        && (!beantype.equals(STATELESS_SESSION))
-                        && (!beantype.equals(STATEFUL_SESSION))) {
-                throw new EjbcException("The beantype found (" + beantype + ") "
-                            + "isn't valid in the " + name + " EJB.");
+                && (!beantype.equals(STATELESS_SESSION))
+                && (!beantype.equals(STATEFUL_SESSION))) {
+                throw new EjbcException("The beantype found (" + beantype
+                    + ") isn't valid in the " + name + " EJB.");
             }
 
             if (cmp && (!beantype.equals(ENTITY_BEAN))) {
-                System.out.println("CMP stubs and skeletons may not be generated"
-                    + " for a Session Bean -- the \"cmp\" attribute will be"
-                    + " ignoredfor the " + name + " EJB.");
+                System.out.println(
+                    "CMP stubs and skeletons may not be generated for a Session Bean -- the \"cmp\" attribute will be ignoredfor the "
+                        + name + " EJB.");
             }
 
             if (hasession && (!beantype.equals(STATEFUL_SESSION))) {
-                System.out.println("Highly available stubs and skeletons may "
-                    + "only be generated for a Stateful Session Bean -- the "
-                    + "\"hasession\" attribute will be ignored for the "
-                    + name + " EJB.");
+                System.out.println(
+                    "Highly available stubs and skeletons may only be generated for a Stateful Session Bean"
+                        + "-- the \"hasession\" attribute will be ignored for the "
+                        + name + " EJB.");
             }
 
             /* Check that the EJB "source" classes all exist */
             if (!remote.getClassFile(buildDir).exists()) {
                 throw new EjbcException("The remote interface "
-                            + remote.getQualifiedClassName() + " could not be "
-                            + "found.");
+                    + remote.getQualifiedClassName() + " could not be found.");
             }
             if (!home.getClassFile(buildDir).exists()) {
                 throw new EjbcException("The home interface "
-                            + home.getQualifiedClassName() + " could not be "
-                            + "found.");
+                    + home.getQualifiedClassName() + " could not be found.");
             }
             if (!implementation.getClassFile(buildDir).exists()) {
                 throw new EjbcException("The EJB implementation class "
-                            + implementation.getQualifiedClassName() + " could "
-                            + "not be found.");
+                    + implementation.getQualifiedClassName()
+                    + " could not be found.");
             }
         }
 
@@ -1140,9 +1118,8 @@
             remoteFile = remote.getClassFile(buildDir);
             modified = remoteFile.lastModified();
             if (modified == -1) {
-                System.out.println("The class "
-                                + remote.getQualifiedClassName() + " couldn't "
-                                + "be found on the classpath");
+                System.out.println("The class " + remote.getQualifiedClassName()
+                    + " couldn't be found on the classpath");
                 return -1;
             }
             latestModified = modified;
@@ -1151,9 +1128,8 @@
             homeFile = home.getClassFile(buildDir);
             modified = homeFile.lastModified();
             if (modified == -1) {
-                System.out.println("The class "
-                                + home.getQualifiedClassName() + " couldn't be "
-                                + "found on the classpath");
+                System.out.println("The class " + home.getQualifiedClassName()
+                    + " couldn't be found on the classpath");
                 return -1;
             }
             latestModified = Math.max(latestModified, modified);
@@ -1163,9 +1139,9 @@
                 pkFile = primaryKey.getClassFile(buildDir);
                 modified = pkFile.lastModified();
                 if (modified == -1) {
-                    System.out.println("The class "
-                                    + primaryKey.getQualifiedClassName() + "couldn't be "
-                                    + "found on the classpath");
+                    System.out.println(
+                        "The class " + primaryKey.getQualifiedClassName()
+                            + "couldn't be found on the classpath");
                     return -1;
                 }
                 latestModified = Math.max(latestModified, modified);
@@ -1226,7 +1202,7 @@
          */
         private long destClassesModified(File destDir) {
             String[] classnames = classesToGenerate(); // List of all stubs & skels
-            long destClassesModified = new Date().getTime(); // Earliest mod time
+            long destClassesModified = Instant.now().toEpochMilli(); // Earliest mod time
             boolean allClassesFound  = true;           // Has each been found?
 
             /*
@@ -1234,7 +1210,6 @@
              * determine (if all exist) which file has the most recent timestamp
              */
             for (int i = 0; i < classnames.length; i++) {
-
                 String pathToClass =
                         classnames[i].replace('.', File.separatorChar) + ".class";
                 File classFile = new File(destDir, pathToClass);
@@ -1255,7 +1230,7 @@
                 }
             }
 
-            return (allClassesFound) ? destClassesModified : -1;
+            return allClassesFound ? destClassesModified : -1;
         }
 
         /**
@@ -1319,6 +1294,7 @@
          *
          * @return A String representing the EjbInfo instance.
          */
+        @Override
         public String toString() {
             String s = "EJB name: " + name
                         + "\n\r              home:      " + home
@@ -1330,7 +1306,7 @@
                         + "\n\r              iiop:      " + iiop
                         + "\n\r              hasession: " + hasession;
 
-            Iterator i = cmpDescriptors.iterator();
+            Iterator<String> i = cmpDescriptors.iterator();
             while (i.hasNext()) {
                 s += "\n\r              CMP Descriptor: " + i.next();
             }
@@ -1435,6 +1411,7 @@
          *
          * @return String representing the fully qualified class name.
          */
+        @Override
         public String toString() {
             return getQualifiedClassName();
         }
@@ -1466,18 +1443,16 @@
          * Reads text from the input stream and redirects it to standard output
          * using a separate thread.
          */
+        @Override
         public void run() {
-            BufferedReader reader = new BufferedReader(
-                                            new InputStreamReader(stream));
-            String text;
-            try {
+            try (BufferedReader reader =
+                new BufferedReader(new InputStreamReader(stream))) {
+                String text;
                 while ((text = reader.readLine()) != null) {
                     System.out.println(text);
                 }
             } catch (IOException e) {
                 e.printStackTrace(); //NOSONAR
-            } finally {
-                FileUtils.close(reader);
             }
         }
     }  // End of RedirectOutput inner class
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbcTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbcTask.java
index 9aca1cb..e18c59b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbcTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbcTask.java
@@ -188,6 +188,7 @@
      * Does the work.
      * @throws BuildException if there is a problem.
      */
+    @Override
     public void execute() throws BuildException {
         checkConfiguration();
 
@@ -202,41 +203,42 @@
     private void checkConfiguration() throws BuildException {
 
         if (ejbdescriptor == null) {
-            String msg = "The standard EJB descriptor must be specified using "
-                            + "the \"ejbdescriptor\" attribute.";
+            String msg =
+                "The standard EJB descriptor must be specified using the \"ejbdescriptor\" attribute.";
             throw new BuildException(msg, getLocation());
         }
         if ((!ejbdescriptor.exists()) || (!ejbdescriptor.isFile())) {
             String msg = "The standard EJB descriptor (" + ejbdescriptor
-                            + ") was not found or isn't a file.";
+                + ") was not found or isn't a file.";
             throw new BuildException(msg, getLocation());
         }
 
         if (iasdescriptor == null) {
-            String msg = "The iAS-speific XML descriptor must be specified using"
-                            + " the \"iasdescriptor\" attribute.";
+            String msg =
+                "The iAS-speific XML descriptor must be specified using the \"iasdescriptor\" attribute.";
             throw new BuildException(msg, getLocation());
         }
         if ((!iasdescriptor.exists()) || (!iasdescriptor.isFile())) {
             String msg = "The iAS-specific XML descriptor (" + iasdescriptor
-                            + ") was not found or isn't a file.";
+                + ") was not found or isn't a file.";
             throw new BuildException(msg, getLocation());
         }
 
         if (dest == null) {
-            String msg = "The destination directory must be specified using "
-                            + "the \"dest\" attribute.";
+            String msg =
+                "The destination directory must be specified using the \"dest\" attribute.";
             throw new BuildException(msg, getLocation());
         }
         if ((!dest.exists()) || (!dest.isDirectory())) {
-            String msg = "The destination directory (" + dest + ") was not "
-                            + "found or isn't a directory.";
+            String msg = "The destination directory (" + dest
+                + ") was not found or isn't a directory.";
             throw new BuildException(msg, getLocation());
         }
 
         if ((iashome != null) && (!iashome.isDirectory())) {
-            String msg = "If \"iashome\" is specified, it must be a valid "
-                            + "directory (it was set to " + iashome + ").";
+            String msg =
+                "If \"iashome\" is specified, it must be a valid directory (it was set to "
+                    + iashome + ").";
             throw new BuildException(msg, getLocation());
         }
     }
@@ -248,21 +250,13 @@
      * @throws BuildException If the parser cannot be created or configured.
      */
     private SAXParser getParser() throws BuildException {
-
-        SAXParser saxParser = null;
         try {
             SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
             saxParserFactory.setValidating(true);
-            saxParser = saxParserFactory.newSAXParser();
-        } catch (SAXException e) {
-            String msg = "Unable to create a SAXParser: " + e.getMessage();
-            throw new BuildException(msg, e, getLocation());
-        } catch (ParserConfigurationException e) {
-            String msg = "Unable to create a SAXParser: " + e.getMessage();
-            throw new BuildException(msg, e, getLocation());
+            return saxParserFactory.newSAXParser();
+        } catch (SAXException | ParserConfigurationException e) {
+            throw new BuildException("Unable to create a SAXParser: " + e.getMessage(), e, getLocation());
         }
-
-        return saxParser;
     }
 
     /**
@@ -284,21 +278,23 @@
         if (iashome != null) {
             ejbc.setIasHomeDir(iashome);
         }
-
         try {
             ejbc.execute();
         } catch (IOException e) {
-            String msg = "An IOException occurred while trying to read the XML "
-                            + "descriptor file: " + e.getMessage();
-            throw new BuildException(msg, e, getLocation());
+            throw new BuildException(
+                "An IOException occurred while trying to read the XML descriptor file: "
+                    + e.getMessage(),
+                e, getLocation());
         } catch (SAXException e) {
-            String msg = "A SAXException occurred while trying to read the XML "
-                            + "descriptor file: " + e.getMessage();
-            throw new BuildException(msg, e, getLocation());
+            throw new BuildException(
+                "A SAXException occurred while trying to read the XML descriptor file: "
+                    + e.getMessage(),
+                e, getLocation());
         } catch (IPlanetEjbc.EjbcException e) {
-            String msg = "An exception occurred while trying to run the ejbc "
-                            + "utility: " + e.getMessage();
-            throw new BuildException(msg, e, getLocation());
+            throw new BuildException(
+                "An exception occurred while trying to run the ejbc utility: "
+                    + e.getMessage(),
+                e, getLocation());
         }
     }
 
@@ -309,13 +305,9 @@
      * @return Path The classpath to be used for EJBc.
      */
     private Path getClasspath() {
-        Path cp = null;
         if (classpath == null) {
-            cp = (new Path(getProject())).concatSystemClasspath("last");
-        } else {
-            cp = classpath.concatSystemClasspath("ignore");
+            return new Path(getProject()).concatSystemClasspath("last");
         }
-
-        return cp;
+        return classpath.concatSystemClasspath("ignore");
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/InnerClassFilenameFilter.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/InnerClassFilenameFilter.java
index e92d9879..b27eaa3 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/InnerClassFilenameFilter.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/InnerClassFilenameFilter.java
@@ -44,11 +44,9 @@
      * @param filename the filename to filter on.
      * @return true if the filename is an inner class of the base class.
      */
+    @Override
     public boolean accept(File dir, String filename) {
-        if ((filename.lastIndexOf(".") != filename.lastIndexOf(".class"))
-            || (filename.indexOf(baseClassName + "$") != 0)) {
-            return false;
-        }
-        return true;
+        return filename.lastIndexOf('.') == filename.lastIndexOf(".class")
+            && filename.indexOf(baseClassName + "$") == 0;
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JbossDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JbossDeploymentTool.java
index e6f8192..8951292 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JbossDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JbossDeploymentTool.java
@@ -53,14 +53,14 @@
      * @param ejbFiles the hashtable of files to populate.
      * @param ddPrefix the prefix to use.
      */
-    protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+    @Override
+    protected void addVendorFiles(Hashtable<String, File> ejbFiles, String ddPrefix) {
         File jbossDD = new File(getConfig().descriptorDir, ddPrefix + JBOSS_DD);
         if (jbossDD.exists()) {
             ejbFiles.put(META_DIR + JBOSS_DD, jbossDD);
         } else {
-            log("Unable to locate jboss deployment descriptor. "
-                + "It was expected to be in " + jbossDD.getPath(),
-                Project.MSG_WARN);
+            log("Unable to locate jboss deployment descriptor. It was expected to be in "
+                + jbossDD.getPath(), Project.MSG_WARN);
             return;
         }
         String descriptorFileName = JBOSS_CMP10D;
@@ -73,8 +73,7 @@
         if (jbossCMPD.exists()) {
             ejbFiles.put(META_DIR + descriptorFileName, jbossCMPD);
         } else {
-            log("Unable to locate jboss cmp descriptor. "
-                + "It was expected to be in "
+            log("Unable to locate jboss cmp descriptor. It was expected to be in "
                 + jbossCMPD.getPath(), Project.MSG_VERBOSE);
         }
     }
@@ -83,15 +82,15 @@
      * Get the vendor specific name of the Jar that will be output. The modification date
      * of this jar will be checked against the dependent bean classes.
      */
+    @Override
     File getVendorOutputJarFile(String baseName) {
         if (getDestDir() == null && getParent().getDestdir() == null) {
             throw new BuildException("DestDir not specified");
         }
         if (getDestDir() == null) {
             return new File(getParent().getDestdir(), baseName + jarSuffix);
-        } else {
-            return new File(getDestDir(), baseName + jarSuffix);
         }
+        return new File(getDestDir(), baseName + jarSuffix);
     }
 
     /**
@@ -101,6 +100,7 @@
      *                        valid
      * @since ant 1.6
      */
+    @Override
     public void validateConfigured() throws BuildException {
     }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JonasDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JonasDeploymentTool.java
index d474f8b..4f98379 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JonasDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JonasDeploymentTool.java
@@ -19,9 +19,10 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.util.Enumeration;
+import java.nio.file.Files;
+import java.util.Arrays;
 import java.util.Hashtable;
-
+import java.util.List;
 import javax.xml.parsers.SAXParser;
 
 import org.apache.tools.ant.AntClassLoader;
@@ -329,6 +330,7 @@
     /* ------------- */
 
     /** {@inheritDoc}. */
+    @Override
     public void processDescriptor(String aDescriptorName, SAXParser saxParser) {
 
         descriptorName = aDescriptorName;
@@ -346,7 +348,8 @@
     }
 
     /** {@inheritDoc}. */
-    protected void writeJar(String baseName, File jarfile, Hashtable ejbFiles, String publicId)
+    @Override
+    protected void writeJar(String baseName, File jarfile, Hashtable<String, File> ejbFiles, String publicId)
     throws BuildException {
 
         // create the generic jar first
@@ -366,10 +369,11 @@
     }
 
     /** {@inheritDoc}. */
-    protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+    @Override
+    protected void addVendorFiles(Hashtable<String, File> ejbFiles, String ddPrefix) {
 
-    // JOnAS-specific descriptor deployment
-    jonasDescriptorName = getJonasDescriptorName();
+        // JOnAS-specific descriptor deployment
+        jonasDescriptorName = getJonasDescriptorName();
         File jonasDD = new File(getConfig().descriptorDir, jonasDescriptorName);
 
         if (jonasDD.exists()) {
@@ -381,6 +385,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     protected File getVendorOutputJarFile(String baseName) {
         return new File(getDestDir(), baseName + suffix);
     }
@@ -458,6 +463,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     protected String getJarBaseName(String descriptorFileName) {
 
         String baseName = null;
@@ -499,6 +505,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     protected void registerKnownDTDs(DescriptorHandler handler) {
         handler.registerDTD(EJB_JAR_1_1_PUBLIC_ID,
                     jonasroot + File.separator + "xml" + File.separator + EJB_JAR_1_1_DTD);
@@ -518,15 +525,12 @@
      * @param ejbFiles the hashtable.
      */
     private void addGenICGeneratedFiles(
-        File genericJarFile, Hashtable ejbFiles) {
-        Java genicTask = null;    // GenIC task
-        String genicClass = null; // GenIC class (3 are supported for various
-                                  // versions
+        File genericJarFile, Hashtable<String, File> ejbFiles) {
         if (nogenic) {
             return;
         }
 
-        genicTask = new Java(getTask());
+        Java genicTask = new Java(getTask()); // GenIC task
         genicTask.setTaskName("genic");
         genicTask.setFork(true);
 
@@ -553,13 +557,8 @@
         genicTask.createArg().setValue("-d");
         genicTask.createArg().setFile(outputdir);
 
-        // work around a bug of GenIC 2.5
-        String key;
-        File f;
-        Enumeration keys = ejbFiles.keys();
-        while (keys.hasMoreElements()) {
-            key = (String) keys.nextElement();
-            f = new File(outputdir + File.separator + key);
+        for (String key : ejbFiles.keySet()) {
+            File f = new File(outputdir + File.separator + key);
             f.getParentFile().mkdirs();
         }
         log("Worked around a bug of GenIC 2.5.", Project.MSG_VERBOSE);
@@ -581,15 +580,18 @@
         log("Using classpath: " + classpath.toString(), Project.MSG_VERBOSE);
         genicTask.setClasspath(classpath);
 
+        String genicClass; // GenIC class (3 are supported for various
+        // versions
+        // work around a bug of GenIC 2.5
+
         // class name (search in the classpath provided for the ejbjar element)
         genicClass = getGenicClassName(classpath);
         if (genicClass == null) {
             log("Cannot find GenIC class in classpath.", Project.MSG_ERR);
             throw new BuildException("GenIC class not found, please check the classpath.");
-        } else {
-            log("Using '" + genicClass + "' GenIC class.", Project.MSG_VERBOSE);
-            genicTask.setClassname(genicClass);
         }
+        log("Using '" + genicClass + "' GenIC class.", Project.MSG_VERBOSE);
+        genicTask.setClassname(genicClass);
 
         // keepgenerated
         if (keepgenerated) {
@@ -613,13 +615,13 @@
         }
 
         // javacopts
-        if (javacopts != null && !javacopts.equals("")) {
+        if (javacopts != null && !javacopts.isEmpty()) {
             genicTask.createArg().setValue("-javacopts");
             genicTask.createArg().setLine(javacopts);
         }
 
         // rmicopts
-        if (rmicopts != null && !rmicopts.equals("")) {
+        if (rmicopts != null && !rmicopts.isEmpty()) {
             genicTask.createArg().setValue("-rmicopts");
             genicTask.createArg().setLine(rmicopts);
         }
@@ -681,10 +683,7 @@
         log("Looking for GenIC class in classpath: "
             + classpath.toString(), Project.MSG_VERBOSE);
 
-        AntClassLoader cl = null;
-
-        try {
-            cl = classpath.getProject().createClassLoader(classpath);
+        try (AntClassLoader cl = classpath.getProject().createClassLoader(classpath)) {
 
             try {
                 cl.loadClass(JonasDeploymentTool.GENIC_CLASS);
@@ -723,10 +722,6 @@
                     + "' not found in classpath.",
                     Project.MSG_VERBOSE);
             }
-        } finally {
-            if (cl != null) {
-                cl.cleanup();
-            }
         }
         return null;
     }
@@ -737,33 +732,38 @@
      * @param saxParser          not used.
      * @throws BuildException if there is an error.
      */
+    @Override
     protected void checkConfiguration(String descriptorFileName,
                       SAXParser saxParser) throws BuildException {
 
         // jonasroot
         if (jonasroot == null) {
-            throw new BuildException("The jonasroot attribut is not set.");
-        } else if (!jonasroot.isDirectory()) {
-            throw new BuildException("The jonasroot attribut '" + jonasroot
-                + "' is not a valid directory.");
+            throw new BuildException("The jonasroot attribute is not set.");
+        }
+        if (!jonasroot.isDirectory()) {
+            throw new BuildException(
+                "The jonasroot attribute '%s' is not a valid directory.",
+                jonasroot);
         }
 
         // orb
-        if (orb != null && !orb.equals(RMI_ORB) && !orb.equals(JEREMIE_ORB)
-            && !orb.equals(DAVID_ORB)) {
-            throw new BuildException("The orb attribut '" + orb
-                + "' is not valid (must be either "
-                + RMI_ORB + ", " + JEREMIE_ORB + " or " + DAVID_ORB + ").");
+        final List<String> validOrbs =
+            Arrays.asList(RMI_ORB, JEREMIE_ORB, DAVID_ORB);
+
+        if (orb != null && !validOrbs.contains(orb)) {
+            throw new BuildException(
+                "The orb attribute '%s' is not valid (must be one of %s.", orb,
+                validOrbs);
         }
 
         // additionalargs
-        if (additionalargs != null && additionalargs.equals("")) {
-            throw new BuildException("Empty additionalargs attribut.");
+        if (additionalargs != null && additionalargs.isEmpty()) {
+            throw new BuildException("Empty additionalargs attribute.");
         }
 
         // javac
-        if (javac != null && javac.equals("")) {
-            throw new BuildException("Empty javac attribut.");
+        if (javac != null && javac.isEmpty()) {
+            throw new BuildException("Empty javac attribute.");
         }
     }
 
@@ -778,26 +778,19 @@
      * @throws BuildException if a temp directory cannot be created.
      */
     private File createTempDir() throws IOException {
-        File tmpDir = File.createTempFile("genic", null, null);
-        tmpDir.delete();
-        if (!tmpDir.mkdir()) {
-            throw new IOException("Cannot create the temporary directory '" + tmpDir + "'.");
-        }
-        return tmpDir;
+        return Files.createTempDirectory("genic").toFile();
     }
 
     /**
-     * Delete a file. If the file is a directory, delete recursivly all the
+     * Delete a file. If the file is a directory, delete recursively all the
      * files inside.
      *
      * @param aFile file to delete.
      */
     private void deleteAllFiles(File aFile) {
         if (aFile.isDirectory()) {
-            File[] someFiles = aFile.listFiles();
-
-            for (int i = 0; i < someFiles.length; i++) {
-                deleteAllFiles(someFiles[i]);
+            for (File child : aFile.listFiles()) {
+                deleteAllFiles(child);
             }
         }
         aFile.delete();
@@ -811,22 +804,19 @@
      * @param rootDir the current sub-directory to scan.
      * @param hashtable the hashtable where to add the files.
      */
-    private void addAllFiles(File file, String rootDir, Hashtable hashtable) {
-
+    private void addAllFiles(File file, String rootDir, Hashtable<String, File> hashtable) {
         if (!file.exists()) {
             throw new IllegalArgumentException();
         }
-
         String newRootDir;
         if (file.isDirectory()) {
-            File[] files = file.listFiles();
-            for (int i = 0; i < files.length; i++) {
-                if (rootDir.length() > 0) {
-                    newRootDir = rootDir + File.separator + files[i].getName();
+            for (File child : file.listFiles()) {
+                if (rootDir.isEmpty()) {
+                    newRootDir = child.getName();
                 } else {
-                    newRootDir = files[i].getName();
+                    newRootDir = rootDir + File.separator + child.getName();
                 }
-                addAllFiles(files[i], newRootDir, hashtable);
+                addAllFiles(child, newRootDir, hashtable);
             }
         } else {
             hashtable.put(rootDir, file);
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/OrionDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/OrionDeploymentTool.java
index a737803..ab23491 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/OrionDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/OrionDeploymentTool.java
@@ -27,7 +27,7 @@
  * ejb jar file. Orion only requires one additional file orion-ejb-jar.xml
  * and does not require any additional compilation.
  *
- * @since Ant 1.9.10
+ * @since Ant 1.10.2
  * @see EjbJar#createOrion
  */
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java
index 7fae8b3..4b0116d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java
@@ -18,13 +18,12 @@
 package org.apache.tools.ant.taskdefs.optional.ejb;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.Iterator;
+import java.util.List;
 import java.util.Vector;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
@@ -37,7 +36,9 @@
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.taskdefs.optional.ejb.EjbJar.DTDLocation;
 import org.apache.tools.ant.types.Environment;
+import org.apache.tools.ant.types.Environment.Variable;
 import org.apache.tools.ant.types.Path;
 import org.apache.tools.ant.util.FileUtils;
 import org.xml.sax.InputSource;
@@ -141,7 +142,7 @@
     private Path wlClasspath = null;
 
     /** System properties for the JVM. */
-    private Vector sysprops = new Vector();
+    private List<Variable> sysprops = new Vector<>();
 
     /**
      * The weblogic.StdoutSeverityLevel to use when running the JVM that
@@ -160,7 +161,6 @@
         sysprops.add(sysp);
     }
 
-
     /**
      * Get the classpath to the weblogic classpaths.
      * @return the classpath to configure.
@@ -182,7 +182,6 @@
         this.outputDir = outputDir;
     }
 
-
     /**
      * Optional classpath to WL6.0.
      * Weblogic 6.0 will give a warning if the home and remote interfaces
@@ -197,7 +196,6 @@
         this.wlClasspath = wlClasspath;
     }
 
-
     /**
      * The compiler (switch <code>-compiler</code>) to use; optional.
      * This allows for the selection of a different compiler
@@ -214,7 +212,6 @@
         this.compiler = compiler;
     }
 
-
     /**
      * Set the rebuild flag to false to only update changes in the jar rather
      * than rerunning ejbc; optional, default true.
@@ -230,7 +227,6 @@
         this.alwaysRebuild = rebuild;
     }
 
-
     /**
      * Sets the weblogic.StdoutSeverityLevel to use when running the JVM that
      * executes ejbc; optional. Set to 16 to avoid the warnings about EJB Home and
@@ -241,7 +237,6 @@
         this.jvmDebugLevel = jvmDebugLevel;
     }
 
-
     /**
      * Get the debug level.
      * @return the jvm debug level (may be null).
@@ -250,8 +245,6 @@
         return jvmDebugLevel;
     }
 
-
-
     /**
      * Setter used to store the suffix for the generated weblogic jar file.
      *
@@ -261,7 +254,6 @@
         this.jarSuffix = inString;
     }
 
-
     /**
      * controls whether the generic file used as input to
      * ejbc is retained; defaults to false
@@ -272,7 +264,6 @@
         this.keepGeneric = inValue;
     }
 
-
     /**
      * Controls whether weblogic will keep the generated Java
      * files used to build the class files added to the
@@ -281,10 +272,9 @@
      * @param inValue either 'true' or 'false'
      */
     public void setKeepgenerated(String inValue) {
-        this.keepgenerated = Boolean.valueOf(inValue).booleanValue();
+        this.keepgenerated = Boolean.parseBoolean(inValue);
     }
 
-
     /**
      * Any optional extra arguments pass to the weblogic.ejbc
      * tool.
@@ -294,7 +284,6 @@
         this.additionalArgs = args;
     }
 
-
     /**
      * Set any additional arguments to pass to the weblogic JVM; optional.
      * @param args the arguments to be passed to the JVM
@@ -316,7 +305,6 @@
         this.ejbcClass = ejbcClass;
     }
 
-
     /**
      * Get the ejbc compiler class.
      * @return the name of the ejbc compiler class.
@@ -325,7 +313,6 @@
         return ejbcClass;
     }
 
-
     /**
      * <b>Deprecated</b>. Defines the location of the ejb-jar DTD in
      *  the weblogic class hierarchy. Should not be needed, and the
@@ -337,7 +324,6 @@
         setEJBdtd(inString);
     }
 
-
     /**
      * <b>Deprecated</b>. Defines the location of weblogic DTD in
      *  the weblogic class hierarchy. Should not be needed, and the
@@ -349,7 +335,6 @@
         this.weblogicDTD = inString;
     }
 
-
     /**
      * <b>Deprecated</b>. Defines the location of Sun's EJB DTD in
      *  the weblogic class hierarchy. Should not be needed, and the
@@ -361,7 +346,6 @@
         this.ejb11DTD = inString;
     }
 
-
     /**
      * Set the value of the oldCMP scheme. This is an antonym for newCMP
      * @ant.attribute ignore="true'
@@ -371,7 +355,6 @@
         this.newCMP = !oldCMP;
     }
 
-
     /**
      * If this is set to true, the new method for locating
      * CMP descriptors will be used; optional, default false.
@@ -388,7 +371,6 @@
         this.newCMP = newCMP;
     }
 
-
     /**
      * Do not EJBC the jar after it has been put together;
      * optional, default false
@@ -398,11 +380,11 @@
         this.noEJBC = noEJBC;
     }
 
-
     /**
      * Register the DTDs.
      * @param handler the handler to use.
      */
+    @Override
     protected void registerKnownDTDs(DescriptorHandler handler) {
         // register all the known DTDs
         handler.registerDTD(PUBLICID_EJB11, DEFAULT_WL51_EJB11_DTD_LOCATION);
@@ -411,7 +393,6 @@
         handler.registerDTD(PUBLICID_EJB20, DEFAULT_WL60_EJB20_DTD_LOCATION);
     }
 
-
     /**
      * Get the weblogic descriptor handler.
      * @param srcDir the source directory.
@@ -420,8 +401,9 @@
     protected DescriptorHandler getWeblogicDescriptorHandler(final File srcDir) {
         DescriptorHandler handler =
             new DescriptorHandler(getTask(), srcDir) {
+                @Override
                 protected void processElement() {
-                    if (currentElement.equals("type-storage")) {
+                    if ("type-storage".equals(currentElement)) {
                         // Get the filename of vendor specific descriptor
                         String fileNameWithMETA = currentText;
                         //trim the META_INF\ off of the file name
@@ -442,44 +424,39 @@
         handler.registerDTD(PUBLICID_WEBLOGIC_EJB510, weblogicDTD);
         handler.registerDTD(PUBLICID_WEBLOGIC_EJB600, weblogicDTD);
 
-        for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
-            EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
-
+        for (DTDLocation dtdLocation : getConfig().dtdLocations) {
             handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
         }
         return handler;
     }
 
-
     /**
      * Add any vendor specific files which should be included in the EJB Jar.
      * @param ejbFiles the hash table to be populated.
      * @param ddPrefix the prefix to use.
      */
-    protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+    @Override
+    protected void addVendorFiles(Hashtable<String, File> ejbFiles, String ddPrefix) {
         File weblogicDD = new File(getConfig().descriptorDir, ddPrefix + WL_DD);
 
         if (weblogicDD.exists()) {
             ejbFiles.put(META_DIR + WL_DD,
                 weblogicDD);
         } else {
-            log("Unable to locate weblogic deployment descriptor. "
-                + "It was expected to be in "
+            log("Unable to locate weblogic deployment descriptor. It was expected to be in "
                 + weblogicDD.getPath(), Project.MSG_WARN);
             return;
         }
 
         if (!newCMP) {
             log("The old method for locating CMP files has been DEPRECATED.", Project.MSG_VERBOSE);
-            log("Please adjust your weblogic descriptor and set "
-                + "newCMP=\"true\" to use the new CMP descriptor "
-                + "inclusion mechanism. ", Project.MSG_VERBOSE);
+            log("Please adjust your weblogic descriptor and set newCMP=\"true\" to use the new CMP descriptor inclusion mechanism. ",
+                Project.MSG_VERBOSE);
             // The the weblogic cmp deployment descriptor
             File weblogicCMPDD = new File(getConfig().descriptorDir, ddPrefix + WL_CMP_DD);
 
             if (weblogicCMPDD.exists()) {
-                ejbFiles.put(META_DIR + WL_CMP_DD,
-                    weblogicCMPDD);
+                ejbFiles.put(META_DIR + WL_CMP_DD, weblogicCMPDD);
             }
         } else {
             // now that we have the weblogic descriptor, we parse the file
@@ -487,7 +464,7 @@
             // this could be the weblogic-cmp-rdbms.xml or any other O/R
             // mapping tool descriptors.
             try {
-                File ejbDescriptor = (File) ejbFiles.get(META_DIR + EJB_DD);
+                File ejbDescriptor = ejbFiles.get(META_DIR + EJB_DD);
                 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
 
                 saxParserFactory.setValidating(true);
@@ -496,37 +473,29 @@
                 DescriptorHandler handler
                     = getWeblogicDescriptorHandler(ejbDescriptor.getParentFile());
 
-                saxParser.parse(new InputSource
-                    (new FileInputStream(weblogicDD)),
-                        handler);
-
-                Hashtable ht = handler.getFiles();
-                Enumeration e = ht.keys();
-
-                while (e.hasMoreElements()) {
-                    String key = (String) e.nextElement();
-
-                    ejbFiles.put(key, ht.get(key));
+                try (InputStream in = Files.newInputStream(weblogicDD.toPath())) {
+                    saxParser.parse(new InputSource(in), handler);
                 }
+                handler.getFiles().forEach(ejbFiles::put);
             } catch (Exception e) {
-                String msg = "Exception while adding Vendor specific files: " + e.toString();
-
-                throw new BuildException(msg, e);
+                throw new BuildException(
+                    "Exception while adding Vendor specific files: "
+                        + e.toString(),
+                    e);
             }
         }
     }
 
-
     /**
      * Get the vendor specific name of the Jar that will be output. The
      * modification date of this jar will be checked against the dependent
      * bean classes.
      */
+    @Override
     File getVendorOutputJarFile(String baseName) {
         return new File(getDestDir(), baseName + jarSuffix);
     }
 
-
     /**
      * Helper method invoked by execute() for each WebLogic jar to be built.
      * Encapsulates the logic of constructing a java task for calling
@@ -537,7 +506,6 @@
      *      jarfile.
      */
     private void buildWeblogicJar(File sourceJar, File destJar, String publicId) {
-        Java javaTask = null;
 
         if (noEJBC) {
             try {
@@ -554,17 +522,11 @@
         String ejbcClassName = ejbcClass;
 
         try {
-            javaTask = new Java(getTask());
+            Java javaTask = new Java(getTask());
             javaTask.setTaskName("ejbc");
 
             javaTask.createJvmarg().setLine(additionalJvmArgs);
-            if (!(sysprops.isEmpty())) {
-                for (Enumeration en = sysprops.elements(); en.hasMoreElements();) {
-                    Environment.Variable entry
-                        = (Environment.Variable) en.nextElement();
-                    javaTask.addSysproperty(entry);
-                }
-            }
+            sysprops.forEach(javaTask::addSysproperty);
 
             if (getJvmDebugLevel() != null) {
                 javaTask.createJvmarg().setLine(" -Dweblogic.StdoutSeverityLevel=" + jvmDebugLevel);
@@ -594,20 +556,18 @@
                 String buildCompiler
                     = getTask().getProject().getProperty("build.compiler");
 
-                if (buildCompiler != null && buildCompiler.equals("jikes")) {
+                if ("jikes".equals(buildCompiler)) {
                     javaTask.createArg().setValue("-compiler");
                     javaTask.createArg().setValue("jikes");
                 }
-            } else {
-                if (!compiler.equals(DEFAULT_COMPILER)) {
-                    javaTask.createArg().setValue("-compiler");
-                    javaTask.createArg().setLine(compiler);
-                }
+            } else if (!DEFAULT_COMPILER.equals(compiler)) {
+                javaTask.createArg().setValue("-compiler");
+                javaTask.createArg().setLine(compiler);
             }
 
             Path combinedClasspath = getCombinedClasspath();
-            if (wlClasspath != null && combinedClasspath != null
-                 && combinedClasspath.toString().trim().length() > 0) {
+            if (!(wlClasspath == null || combinedClasspath == null
+                || combinedClasspath.toString().trim().isEmpty())) {
                 javaTask.createArg().setValue("-classpath");
                 javaTask.createArg().setPath(combinedClasspath);
             }
@@ -638,14 +598,11 @@
             }
         } catch (Exception e) {
             // Have to catch this because of the semantics of calling main()
-            String msg = "Exception while calling " + ejbcClassName
-                + ". Details: " + e.toString();
-
-            throw new BuildException(msg, e);
+            throw new BuildException("Exception while calling " + ejbcClassName
+                + ". Details: " + e.toString(), e);
         }
     }
 
-
     /**
      * Method used to encapsulate the writing of the JAR file. Iterates over
      * the filenames/java.io.Files in the Hashtable stored on the instance
@@ -656,7 +613,8 @@
      * @param publicId the id to use.
      * @throws BuildException if there is a problem.
      */
-    protected void writeJar(String baseName, File jarFile, Hashtable files,
+    @Override
+    protected void writeJar(String baseName, File jarFile, Hashtable<String, File> files,
                             String publicId) throws BuildException {
         // need to create a generic jar first.
         File genericJarFile = super.getVendorOutputJarFile(baseName);
@@ -673,16 +631,15 @@
         }
     }
 
-
     /**
      * Called to validate that the tool parameters have been configured.
      * @throws BuildException if there is an error.
      */
+    @Override
     public void validateConfigured() throws BuildException {
         super.validateConfigured();
     }
 
-
     /**
      * Helper method to check to see if a weblogic EBJ1.1 jar needs to be
      * rebuilt using ejbc. Called from writeJar it sees if the "Bean" classes
@@ -728,35 +685,33 @@
                 genericJar = new JarFile(genericJarFile);
                 wlJar = new JarFile(weblogicJarFile);
 
-                Hashtable genericEntries = new Hashtable();
-                Hashtable wlEntries = new Hashtable();
-                Hashtable replaceEntries = new Hashtable();
+                Hashtable<String, JarEntry> genericEntries = new Hashtable<>();
+                Hashtable<String, JarEntry> wlEntries = new Hashtable<>();
+                Hashtable<String, JarEntry> replaceEntries = new Hashtable<>();
 
                 //get the list of generic jar entries
-                for (Enumeration e = genericJar.entries(); e.hasMoreElements();) {
-                    JarEntry je = (JarEntry) e.nextElement();
-
+                for (Enumeration<JarEntry> e = genericJar.entries(); e.hasMoreElements();) {
+                    JarEntry je = e.nextElement();
                     genericEntries.put(je.getName().replace('\\', '/'), je);
                 }
                 //get the list of weblogic jar entries
-                for (Enumeration e = wlJar.entries(); e.hasMoreElements();) {
-                    JarEntry je = (JarEntry) e.nextElement();
-
+                for (Enumeration<JarEntry> e = wlJar.entries(); e.hasMoreElements();) {
+                    JarEntry je = e.nextElement();
                     wlEntries.put(je.getName(), je);
                 }
 
                 //Cycle Through generic and make sure its in weblogic
                 genericLoader = getClassLoaderFromJar(genericJarFile);
 
-                for (Enumeration e = genericEntries.keys(); e.hasMoreElements();) {
-                    String filepath = (String) e.nextElement();
+                for (Enumeration<String> e = genericEntries.keys(); e.hasMoreElements();) {
+                    String filepath = e.nextElement();
 
                     if (wlEntries.containsKey(filepath)) {
                         // File name/path match
 
                         // Check files see if same
-                        JarEntry genericEntry = (JarEntry) genericEntries.get(filepath);
-                        JarEntry wlEntry = (JarEntry) wlEntries.get(filepath);
+                        JarEntry genericEntry = genericEntries.get(filepath);
+                        JarEntry wlEntry = wlEntries.get(filepath);
 
                         if ((genericEntry.getCrc() != wlEntry.getCrc())
                             || (genericEntry.getSize() != wlEntry.getSize())) {
@@ -770,7 +725,7 @@
 
                                 classname = classname.substring(0, classname.lastIndexOf(".class"));
 
-                                Class genclass = genericLoader.loadClass(classname);
+                                Class<?> genclass = genericLoader.loadClass(classname);
 
                                 if (genclass.isInterface()) {
                                     //Interface changed   rebuild jar.
@@ -778,19 +733,17 @@
                                         + " has changed", Project.MSG_VERBOSE);
                                     rebuild = true;
                                     break;
-                                } else {
-                                    //Object class Changed   update it.
-                                    replaceEntries.put(filepath, genericEntry);
                                 }
-                            } else {
-                                // is it the manifest. If so ignore it
-                                if (!genericEntry.getName().equals("META-INF/MANIFEST.MF")) {
-                                    //File other then class changed   rebuild
-                                    log("Non class file " + genericEntry.getName()
-                                        + " has changed", Project.MSG_VERBOSE);
-                                    rebuild = true;
-                                    break;
-                                }
+                                //Object class Changed   update it.
+                                replaceEntries.put(filepath, genericEntry);
+                            } else if (!genericEntry.getName()
+                                .equals("META-INF/MANIFEST.MF")) {
+                                // it is the manifest, so ignore it
+                                //File other then class changed   rebuild
+                                log("Non class file " + genericEntry.getName()
+                                    + " has changed", Project.MSG_VERBOSE);
+                                rebuild = true;
+                                break;
                             }
                         }
                     } else {
@@ -810,15 +763,12 @@
                         newWLJarFile.delete();
                     }
 
-                    newJarStream = new JarOutputStream(new FileOutputStream(newWLJarFile));
+                    newJarStream = new JarOutputStream(Files.newOutputStream(newWLJarFile.toPath()));
                     newJarStream.setLevel(0);
 
                     //Copy files from old weblogic jar
-                    for (Enumeration e = wlEntries.elements(); e.hasMoreElements();) {
-                        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
-                        int bytesRead;
-                        InputStream is;
-                        JarEntry je = (JarEntry) e.nextElement();
+                    for (Enumeration<JarEntry> e = wlEntries.elements(); e.hasMoreElements();) {
+                        JarEntry je = e.nextElement();
 
                         if (je.getCompressedSize() == -1
                             || je.getCompressedSize() == je.getSize()) {
@@ -827,12 +777,13 @@
                             newJarStream.setLevel(JAR_COMPRESS_LEVEL);
                         }
 
+                        InputStream is;
                         // Update with changed Bean class
                         if (replaceEntries.containsKey(je.getName())) {
                             log("Updating Bean class from generic Jar "
                                 + je.getName(), Project.MSG_VERBOSE);
                             // Use the entry from the generic jar
-                            je = (JarEntry) replaceEntries.get(je.getName());
+                            je = replaceEntries.get(je.getName());
                             is = genericJar.getInputStream(je);
                         } else {
                             //use fle from original weblogic jar
@@ -841,6 +792,8 @@
                         }
                         newJarStream.putNextEntry(new JarEntry(je.getName()));
 
+                        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+                        int bytesRead;
                         while ((bytesRead = is.read(buffer)) != -1) {
                             newJarStream.write(buffer, 0, bytesRead);
                         }
@@ -866,24 +819,10 @@
 
             throw new BuildException(msg, ioe);
         } finally {
-            // need to close files and perhaps rename output
-            if (genericJar != null) {
-                try {
-                    genericJar.close();
-                } catch (IOException closeException) {
-                    // empty
-                }
-            }
-
-            if (wlJar != null) {
-                try {
-                    wlJar.close();
-                } catch (IOException closeException) {
-                    // empty
-                }
-            }
-
+            FileUtils.close(genericJar);
+            FileUtils.close(wlJar);
             FileUtils.close(newJarStream);
+
             if (newJarStream != null) {
                 try {
                     FILE_UTILS.rename(newWLJarFile, weblogicJarFile);
@@ -894,11 +833,11 @@
             }
             if (genericLoader != null
                 && genericLoader instanceof AntClassLoader) {
+                @SuppressWarnings("resource")
                 AntClassLoader loader = (AntClassLoader) genericLoader;
                 loader.cleanup();
             }
         }
-
         return rebuild;
     }
 
@@ -921,7 +860,6 @@
         if (classpath != null) {
             lookupPath.append(classpath);
         }
-
         return getTask().getProject().createClassLoader(lookupPath);
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicTOPLinkDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicTOPLinkDeploymentTool.java
index 0752bbe..15edf46 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicTOPLinkDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicTOPLinkDeploymentTool.java
@@ -62,14 +62,17 @@
      * @param srcDir the source file.
      * @return the descriptor handler.
      */
+    @Override
     protected DescriptorHandler getDescriptorHandler(File srcDir) {
         DescriptorHandler handler = super.getDescriptorHandler(srcDir);
         if (toplinkDTD != null) {
-            handler.registerDTD("-//The Object People, Inc.//"
-                + "DTD TOPLink for WebLogic CMP 2.5.1//EN", toplinkDTD);
+            handler.registerDTD(
+                "-//The Object People, Inc.//DTD TOPLink for WebLogic CMP 2.5.1//EN",
+                toplinkDTD);
         } else {
-            handler.registerDTD("-//The Object People, Inc.//"
-                + "DTD TOPLink for WebLogic CMP 2.5.1//EN", TL_DTD_LOC);
+            handler.registerDTD(
+                "-//The Object People, Inc.//DTD TOPLink for WebLogic CMP 2.5.1//EN",
+                TL_DTD_LOC);
         }
         return handler;
     }
@@ -80,21 +83,20 @@
      * @param ejbFiles the hashtable to add files to.
      * @param ddPrefix the prefix to use.
      */
-    protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+    @Override
+    protected void addVendorFiles(Hashtable<String, File> ejbFiles, String ddPrefix) {
         super.addVendorFiles(ejbFiles, ddPrefix);
         // Then the toplink deployment descriptor
 
         // Setup a naming standard here?.
 
-
         File toplinkDD = new File(getConfig().descriptorDir, ddPrefix + toplinkDescriptor);
 
         if (toplinkDD.exists()) {
             ejbFiles.put(META_DIR + toplinkDescriptor,
                          toplinkDD);
         } else {
-            log("Unable to locate toplink deployment descriptor. "
-                + "It was expected to be in "
+            log("Unable to locate toplink deployment descriptor. It was expected to be in "
                 + toplinkDD.getPath(), Project.MSG_WARN);
         }
     }
@@ -103,11 +105,12 @@
      * Called to validate that the tool parameters have been configured.
      * @throws BuildException if there is an error.
      */
+    @Override
     public void validateConfigured() throws BuildException {
         super.validateConfigured();
         if (toplinkDescriptor == null) {
-            throw new BuildException("The toplinkdescriptor attribute must "
-                + "be specified");
+            throw new BuildException(
+                "The toplinkdescriptor attribute must be specified");
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java
index 52668bd..2ea7279 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java
@@ -18,12 +18,11 @@
 package org.apache.tools.ant.taskdefs.optional.ejb;
 
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.jar.JarOutputStream;
@@ -32,6 +31,7 @@
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.taskdefs.optional.ejb.EjbJar.DTDLocation;
 import org.apache.tools.ant.types.Environment;
 import org.apache.tools.ant.types.Path;
 import org.apache.tools.ant.util.FileUtils;
@@ -148,7 +148,6 @@
         return wasClasspath.createPath();
     }
 
-
     /**
      * Set the websphere classpath.
      * @param wasClasspath the websphere classpath.
@@ -157,7 +156,6 @@
         this.wasClasspath = wasClasspath;
     }
 
-
     /** Sets the DB Vendor for the Entity Bean mapping; optional.
      * <p>
      * Valid options can be obtained by running the following command:
@@ -177,7 +175,6 @@
         this.dbVendor = dbvendor;
     }
 
-
     /**
      * Sets the name of the Database to create; optional.
      *
@@ -187,7 +184,6 @@
         this.dbName = dbName;
     }
 
-
     /**
      * Sets the name of the schema to create; optional.
      *
@@ -197,7 +193,6 @@
         this.dbSchema = dbSchema;
     }
 
-
     /**
      * Flag, default false, to only generate the deployment
      * code, do not run RMIC or Javac
@@ -208,7 +203,6 @@
         this.codegen = codegen;
     }
 
-
     /**
      * Flag, default true, to only output error messages.
      *
@@ -218,7 +212,6 @@
         this.quiet = quiet;
     }
 
-
     /**
      * Flag to disable the validation steps; optional, default false.
      *
@@ -228,7 +221,6 @@
         this.novalidate = novalidate;
     }
 
-
     /**
      * Flag to disable warning and informational messages; optional, default false.
      *
@@ -238,7 +230,6 @@
         this.nowarn = nowarn;
     }
 
-
     /**
      * Flag to disable informational messages; optional, default false.
      *
@@ -248,7 +239,6 @@
         this.noinform = noinform;
     }
 
-
     /**
      * Flag to enable internal tracing when set, optional, default false.
      *
@@ -276,7 +266,6 @@
         use35MappingRules = attr;
     }
 
-
     /**
      * Set the rebuild flag to false to only update changes in the jar rather
      * than rerunning ejbdeploy; optional, default true.
@@ -286,7 +275,6 @@
         this.alwaysRebuild = rebuild;
     }
 
-
     /**
      * String value appended to the basename of the deployment
      * descriptor to create the filename of the WebLogic EJB
@@ -297,7 +285,6 @@
         this.jarSuffix = inString;
     }
 
-
     /**
      * This controls whether the generic file used as input to
      * ejbdeploy is retained; optional, default false.
@@ -307,7 +294,6 @@
         this.keepGeneric = inValue;
     }
 
-
     /**
      * Decide, whether ejbdeploy should be called or not;
      * optional, default true.
@@ -318,7 +304,6 @@
         this.ejbdeploy = ejbdeploy;
     }
 
-
     /**
      * Setter used to store the location of the Sun's Generic EJB DTD. This
      * can be a file on the system or a resource on the classpath.
@@ -329,7 +314,6 @@
         this.ejb11DTD = inString;
     }
 
-
     /**
      * Set the value of the oldCMP scheme. This is an antonym for newCMP
      * @ant.attribute ignore="true"
@@ -339,7 +323,6 @@
         this.newCMP = !oldCMP;
     }
 
-
     /**
      * Set the value of the newCMP scheme. The old CMP scheme locates the
      * websphere CMP descriptor based on the naming convention where the
@@ -353,7 +336,6 @@
         this.newCMP = newCMP;
     }
 
-
     /**
      * The directory, where ejbdeploy will write temporary files;
      * optional, defaults to '_ejbdeploy_temp'.
@@ -363,24 +345,20 @@
         this.tempdir = tempdir;
     }
 
-
     /** {@inheritDoc}. */
+    @Override
     protected DescriptorHandler getDescriptorHandler(File srcDir) {
         DescriptorHandler handler = new DescriptorHandler(getTask(), srcDir);
         // register all the DTDs, both the ones that are known and
         // any supplied by the user
         handler.registerDTD(PUBLICID_EJB11, ejb11DTD);
 
-        for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
-            EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
-
+        for (DTDLocation dtdLocation : getConfig().dtdLocations) {
             handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
         }
-
         return handler;
     }
 
-
     /**
      * Get a description handler.
      * @param srcDir the source directory.
@@ -389,13 +367,12 @@
     protected DescriptorHandler getWebsphereDescriptorHandler(final File srcDir) {
         DescriptorHandler handler =
             new DescriptorHandler(getTask(), srcDir) {
+                @Override
                 protected void processElement() {
                 }
             };
 
-        for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
-            EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
-
+        for (DTDLocation dtdLocation : getConfig().dtdLocations) {
             handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
         }
         return handler;
@@ -407,9 +384,10 @@
      * @param ejbFiles a hashtable entryname -&gt; file.
      * @param baseName a prefix to use.
      */
-    protected void addVendorFiles(Hashtable ejbFiles, String baseName) {
+    @Override
+    protected void addVendorFiles(Hashtable<String, File> ejbFiles, String baseName) {
 
-        String ddPrefix = (usingBaseJarName() ? "" : baseName);
+        String ddPrefix = usingBaseJarName() ? "" : baseName;
         String dbPrefix = (dbVendor == null) ? "" : dbVendor + "-";
 
         // Get the Extensions document
@@ -419,8 +397,7 @@
             ejbFiles.put(META_DIR + WAS_EXT,
                 websphereEXT);
         } else {
-            log("Unable to locate websphere extensions. "
-                + "It was expected to be in "
+            log("Unable to locate websphere extensions. It was expected to be in "
                 + websphereEXT.getPath(), Project.MSG_VERBOSE);
         }
 
@@ -430,17 +407,15 @@
             ejbFiles.put(META_DIR + WAS_BND,
                 websphereBND);
         } else {
-            log("Unable to locate websphere bindings. "
-                + "It was expected to be in "
+            log("Unable to locate websphere bindings. It was expected to be in "
                 + websphereBND.getPath(), Project.MSG_VERBOSE);
         }
 
         if (!newCMP) {
             log("The old method for locating CMP files has been DEPRECATED.",
                 Project.MSG_VERBOSE);
-            log("Please adjust your websphere descriptor and set "
-                + "newCMP=\"true\" to use the new CMP descriptor "
-                + "inclusion mechanism. ", Project.MSG_VERBOSE);
+            log("Please adjust your websphere descriptor and set newCMP=\"true\" to use the new CMP descriptor inclusion mechanism. ",
+                Project.MSG_VERBOSE);
         } else {
             // We attempt to put in the MAP and Schema files of CMP beans
             try {
@@ -468,25 +443,24 @@
                 }
                 // There is nothing else to see here...keep moving sonny
             } catch (Exception e) {
-                String msg = "Exception while adding Vendor specific files: "
-                    + e.toString();
-
-                throw new BuildException(msg, e);
+                throw new BuildException(
+                    "Exception while adding Vendor specific files: "
+                        + e.toString(),
+                    e);
             }
         }
     }
 
-
     /**
      * Get the vendor specific name of the Jar that will be output. The
      * modification date of this jar will be checked against the dependent
      * bean classes.
      */
+    @Override
     File getVendorOutputJarFile(String baseName) {
         return new File(getDestDir(), baseName + jarSuffix);
     }
 
-
     /**
      * Gets the options for the EJB Deploy operation
      *
@@ -494,7 +468,7 @@
      */
     protected String getOptions() {
         // Set the options
-        StringBuffer options = new StringBuffer();
+        StringBuilder options = new StringBuilder();
 
         if (dbVendor != null) {
             options.append(" -dbvendor ").append(dbVendor);
@@ -542,7 +516,6 @@
         return options.toString();
     }
 
-
     /**
      * Helper method invoked by execute() for each websphere jar to be built.
      * Encapsulates the logic of constructing a java task for calling
@@ -603,15 +576,16 @@
             }
         } catch (Exception e) {
             // Have to catch this because of the semantics of calling main()
-            String msg = "Exception while calling ejbdeploy. Details: " + e.toString();
-
-            throw new BuildException(msg, e);
+            throw new BuildException(
+                "Exception while calling ejbdeploy. Details: " + e.toString(),
+                e);
         }
     }
 
     /** {@inheritDoc}. */
-    protected void writeJar(String baseName, File jarFile, Hashtable files, String publicId)
-         throws BuildException {
+    @Override
+    protected void writeJar(String baseName, File jarFile,
+        Hashtable<String, File> files, String publicId) throws BuildException {
         if (ejbdeploy) {
             // create the -generic.jar, if required
             File genericJarFile = super.getVendorOutputJarFile(baseName);
@@ -633,24 +607,23 @@
         }
     }
 
-
     /**
      * Called to validate that the tool parameters have been configured.
      * @throws BuildException if there is an error.
      */
+    @Override
     public void validateConfigured() throws BuildException {
         super.validateConfigured();
         if (ejbdeploy) {
             String home = getTask().getProject().getProperty("websphere.home");
             if (home == null) {
-                throw new BuildException("The 'websphere.home' property must "
-                    + "be set when 'ejbdeploy=true'");
+                throw new BuildException(
+                    "The 'websphere.home' property must be set when 'ejbdeploy=true'");
             }
             websphereHome = getTask().getProject().resolveFile(home);
         }
     }
 
-
     /**
      * Helper method to check to see if a websphere EBJ1.1 jar needs to be
      * rebuilt using ejbdeploy. Called from writeJar it sees if the "Bean"
@@ -696,34 +669,32 @@
                 genericJar = new JarFile(genericJarFile);
                 wasJar = new JarFile(websphereJarFile);
 
-                Hashtable genericEntries = new Hashtable();
-                Hashtable wasEntries = new Hashtable();
-                Hashtable replaceEntries = new Hashtable();
+                Hashtable<String, JarEntry> genericEntries = new Hashtable<>();
+                Hashtable<String, JarEntry> wasEntries = new Hashtable<>();
+                Hashtable<String, JarEntry> replaceEntries = new Hashtable<>();
 
                 //get the list of generic jar entries
-                for (Enumeration e = genericJar.entries(); e.hasMoreElements();) {
-                    JarEntry je = (JarEntry) e.nextElement();
-
+                for (Enumeration<JarEntry> e = genericJar.entries(); e.hasMoreElements();) {
+                    JarEntry je = e.nextElement();
                     genericEntries.put(je.getName().replace('\\', '/'), je);
                 }
                 //get the list of websphere jar entries
-                for (Enumeration e = wasJar.entries(); e.hasMoreElements();) {
-                    JarEntry je = (JarEntry) e.nextElement();
-
+                for (Enumeration<JarEntry> e = wasJar.entries(); e.hasMoreElements();) {
+                    JarEntry je = e.nextElement();
                     wasEntries.put(je.getName(), je);
                 }
 
                 //Cycle Through generic and make sure its in websphere
                 genericLoader = getClassLoaderFromJar(genericJarFile);
 
-                for (Enumeration e = genericEntries.keys(); e.hasMoreElements();) {
-                    String filepath = (String) e.nextElement();
+                for (Enumeration<String> e = genericEntries.keys(); e.hasMoreElements();) {
+                    String filepath = e.nextElement();
 
                     if (wasEntries.containsKey(filepath)) {
                         // File name/path match
                         // Check files see if same
-                        JarEntry genericEntry = (JarEntry) genericEntries.get(filepath);
-                        JarEntry wasEntry = (JarEntry) wasEntries.get(filepath);
+                        JarEntry genericEntry = genericEntries.get(filepath);
+                        JarEntry wasEntry = wasEntries.get(filepath);
 
                         if ((genericEntry.getCrc() != wasEntry.getCrc())
                             || (genericEntry.getSize() != wasEntry.getSize())) {
@@ -735,7 +706,7 @@
 
                                 classname = classname.substring(0, classname.lastIndexOf(".class"));
 
-                                Class genclass = genericLoader.loadClass(classname);
+                                Class<?> genclass = genericLoader.loadClass(classname);
 
                                 if (genclass.isInterface()) {
                                     //Interface changed   rebuild jar.
@@ -743,14 +714,13 @@
                                         + " has changed", Project.MSG_VERBOSE);
                                     rebuild = true;
                                     break;
-                                } else {
-                                    //Object class Changed   update it.
-                                    replaceEntries.put(filepath, genericEntry);
                                 }
+                                //Object class Changed   update it.
+                                replaceEntries.put(filepath, genericEntry);
                             } else {
                                 // is it the manifest. If so ignore it
                                 if (!genericEntry.getName().equals("META-INF/MANIFEST.MF")) {
-                                    //File other then class changed   rebuild
+                                    //File other then class changed  rebuild
                                     log("Non class file " + genericEntry.getName()
                                         + " has changed", Project.MSG_VERBOSE);
                                     rebuild = true;
@@ -775,15 +745,12 @@
                         newwasJarFile.delete();
                     }
 
-                    newJarStream = new JarOutputStream(new FileOutputStream(newwasJarFile));
+                    newJarStream = new JarOutputStream(Files.newOutputStream(newwasJarFile.toPath()));
                     newJarStream.setLevel(0);
 
                     //Copy files from old websphere jar
-                    for (Enumeration e = wasEntries.elements(); e.hasMoreElements();) {
-                        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
-                        int bytesRead;
-                        InputStream is;
-                        JarEntry je = (JarEntry) e.nextElement();
+                    for (Enumeration<JarEntry> e = wasEntries.elements(); e.hasMoreElements();) {
+                        JarEntry je = e.nextElement();
 
                         if (je.getCompressedSize() == -1
                             || je.getCompressedSize() == je.getSize()) {
@@ -792,12 +759,13 @@
                             newJarStream.setLevel(JAR_COMPRESS_LEVEL);
                         }
 
+                        InputStream is;
                         // Update with changed Bean class
                         if (replaceEntries.containsKey(je.getName())) {
                             log("Updating Bean class from generic Jar " + je.getName(),
                                 Project.MSG_VERBOSE);
                             // Use the entry from the generic jar
-                            je = (JarEntry) replaceEntries.get(je.getName());
+                            je = replaceEntries.get(je.getName());
                             is = genericJar.getInputStream(je);
                         } else {
                             //use fle from original websphere jar
@@ -806,6 +774,8 @@
                         }
                         newJarStream.putNextEntry(new JarEntry(je.getName()));
 
+                        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+                        int bytesRead;
                         while ((bytesRead = is.read(buffer)) != -1) {
                             newJarStream.write(buffer, 0, bytesRead);
                         }
@@ -819,36 +789,21 @@
                 rebuild = true;
             }
         } catch (ClassNotFoundException cnfe) {
-            String cnfmsg = "ClassNotFoundException while processing ejb-jar file"
-                 + ". Details: "
-                 + cnfe.getMessage();
-
-            throw new BuildException(cnfmsg, cnfe);
+            throw new BuildException(
+                "ClassNotFoundException while processing ejb-jar file. Details: "
+                    + cnfe.getMessage(),
+                cnfe);
         } catch (IOException ioe) {
-            String msg = "IOException while processing ejb-jar file "
-                 + ". Details: "
-                 + ioe.getMessage();
-
-            throw new BuildException(msg, ioe);
+            throw new BuildException(
+                "IOException while processing ejb-jar file . Details: "
+                    + ioe.getMessage(),
+                ioe);
         } finally {
             // need to close files and perhaps rename output
-            if (genericJar != null) {
-                try {
-                    genericJar.close();
-                } catch (IOException closeException) {
-                    // Ignore
-                }
-            }
-
-            if (wasJar != null) {
-                try {
-                    wasJar.close();
-                } catch (IOException closeException) {
-                    // Ignore
-                }
-            }
-
+            FileUtils.close(genericJar);
+            FileUtils.close(wasJar);
             FileUtils.close(newJarStream);
+
             if (newJarStream != null) {
                 try {
                     FILE_UTILS.rename(newwasJarFile, websphereJarFile);
@@ -859,15 +814,14 @@
             }
             if (genericLoader != null
                 && genericLoader instanceof AntClassLoader) {
+                @SuppressWarnings("resource")
                 AntClassLoader loader = (AntClassLoader) genericLoader;
                 loader.cleanup();
             }
         }
-
         return rebuild;
     }
 
-
     /**
      * Helper method invoked by isRebuildRequired to get a ClassLoader for a
      * Jar File passed to it.
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatability.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatability.java
index cbc7f37..262753c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatability.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatability.java
@@ -51,6 +51,7 @@
      *
      * @return the name of compatibility level
      */
+    @Override
     public String toString() {
         return name;
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatibility.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatibility.java
index cfe12a1..8e1ef16 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatibility.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatibility.java
@@ -51,6 +51,7 @@
      *
      * @return the name of compatibility level
      */
+    @Override
     public String toString() {
         return name;
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/Extension.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Extension.java
index d13d2f4..a0c7e9d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/Extension.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Extension.java
@@ -18,11 +18,12 @@
 package org.apache.tools.ant.taskdefs.optional.extension;
 
 import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
+import java.util.List;
+import java.util.Objects;
 import java.util.StringTokenizer;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.util.DeweyDecimal;
 import org.apache.tools.ant.util.StringUtils;
@@ -187,31 +188,13 @@
      */
     public static Extension[] getAvailable(final Manifest manifest) {
         if (null == manifest) {
-            return new Extension[ 0 ];
+            return new Extension[0];
         }
-
-        final ArrayList results = new ArrayList();
-
-        final Attributes mainAttributes = manifest.getMainAttributes();
-        if (null != mainAttributes) {
-            final Extension extension = getExtension("", mainAttributes);
-            if (null != extension) {
-                results.add(extension);
-            }
-        }
-
-        final Map entries = manifest.getEntries();
-        final Iterator keys = entries.keySet().iterator();
-        while (keys.hasNext()) {
-            final String key = (String) keys.next();
-            final Attributes attributes = (Attributes) entries.get(key);
-            final Extension extension = getExtension("", attributes);
-            if (null != extension) {
-                results.add(extension);
-            }
-        }
-
-        return (Extension[]) results.toArray(new Extension[results.size()]);
+        return Stream
+            .concat(Stream.of(manifest.getMainAttributes()),
+                manifest.getEntries().values().stream())
+            .map(attrs -> getExtension("", attrs)).filter(Objects::nonNull)
+            .toArray(Extension[]::new);
     }
 
     /**
@@ -491,10 +474,11 @@
      *
      * @return string representation of object.
      */
+    @Override
     public String toString() {
         final String brace = ": ";
 
-        final StringBuffer sb = new StringBuffer(EXTENSION_NAME.toString());
+        final StringBuilder sb = new StringBuilder(EXTENSION_NAME.toString());
         sb.append(brace);
         sb.append(extensionName);
         sb.append(StringUtils.LINE_SEP);
@@ -567,22 +551,17 @@
      */
     private static Extension[] getListed(final Manifest manifest,
                                           final Attributes.Name listKey) {
-        final ArrayList results = new ArrayList();
+        final List<Extension> results = new ArrayList<>();
         final Attributes mainAttributes = manifest.getMainAttributes();
 
         if (null != mainAttributes) {
             getExtension(mainAttributes, results, listKey);
         }
 
-        final Map entries = manifest.getEntries();
-        final Iterator keys = entries.keySet().iterator();
-        while (keys.hasNext()) {
-            final String key = (String) keys.next();
-            final Attributes attributes = (Attributes) entries.get(key);
-            getExtension(attributes, results, listKey);
-        }
+        manifest.getEntries().values()
+            .forEach(attributes -> getExtension(attributes, results, listKey));
 
-        return (Extension[]) results.toArray(new Extension[results.size()]);
+        return results.toArray(new Extension[results.size()]);
     }
 
     /**
@@ -595,18 +574,14 @@
      *    or OPTIONAL_EXTENSION_LIST
      */
     private static void getExtension(final Attributes attributes,
-                                     final ArrayList required,
+                                     final List<Extension> required,
                                      final Attributes.Name listKey) {
         final String names = attributes.getValue(listKey);
         if (null == names) {
             return;
         }
-
-        final String[] extensions = split(names, " ");
-        for (int i = 0; i < extensions.length; i++) {
-            final String prefix = extensions[ i ] + "-";
-            final Extension extension = getExtension(prefix, attributes);
-
+        for (final String prefix : split(names, " ")) {
+            final Extension extension = getExtension(prefix + "-", attributes);
             if (null != extension) {
                 required.add(extension);
             }
@@ -623,10 +598,10 @@
     private static String[] split(final String string,
                                         final String onToken) {
         final StringTokenizer tokenizer = new StringTokenizer(string, onToken);
-        final String[] result = new String[ tokenizer.countTokens() ];
+        final String[] result = new String[tokenizer.countTokens()];
 
         for (int i = 0; i < result.length; i++) {
-            result[ i ] = tokenizer.nextToken();
+            result[i] = tokenizer.nextToken();
         }
 
         return result;
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionAdapter.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionAdapter.java
index 4befa4f..0623add 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionAdapter.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionAdapter.java
@@ -150,6 +150,7 @@
      * @param reference the reference to which this instance is associated
      * @exception BuildException if this instance already has been configured.
      */
+    @Override
     public void setRefid(final Reference reference)
         throws BuildException {
         if (null != extensionName
@@ -183,8 +184,7 @@
         }
         dieOnCircularReference();
         if (null == extensionName) {
-            final String message = "Extension is missing name.";
-            throw new BuildException(message);
+            throw new BuildException("Extension is missing name.");
         }
 
         String specificationVersionString = null;
@@ -209,7 +209,8 @@
      * @return the extension in a string.
      * @see java.lang.Object#toString()
      */
+    @Override
     public String toString() {
-        return "{" + toExtension().toString() + "}";
+        return "{" + toExtension() + "}";
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionSet.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionSet.java
index 5aba37c..2868027 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionSet.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionSet.java
@@ -19,7 +19,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Iterator;
+import java.util.List;
 import java.util.Stack;
 
 import org.apache.tools.ant.BuildException;
@@ -39,12 +39,12 @@
     /**
      * ExtensionAdapter objects representing extensions.
      */
-    private final ArrayList extensions = new ArrayList();
+    private final List<ExtensionAdapter> extensions = new ArrayList<>();
 
     /**
      * Filesets specifying all the extensions wanted.
      */
-    private final ArrayList extensionsFilesets = new ArrayList();
+    private final List<FileSet> extensionsFilesets = new ArrayList<>();
 
     /**
      * Adds an extension that this library requires.
@@ -98,9 +98,9 @@
             return ((ExtensionSet) getCheckedRef()).toExtensions(proj);
         }
         dieOnCircularReference();
-        final ArrayList extensionsList = ExtensionUtil.toExtensions(extensions);
+        final List<Extension> extensionsList = ExtensionUtil.toExtensions(extensions);
         ExtensionUtil.extractExtensions(proj, extensionsList, extensionsFilesets);
-        return (Extension[]) extensionsList.toArray(new Extension[extensionsList.size()]);
+        return extensionsList.toArray(new Extension[extensionsList.size()]);
     }
 
     /**
@@ -123,7 +123,7 @@
     }
 
     @Override
-    protected synchronized void dieOnCircularReference(Stack stk, Project p)
+    protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
             return;
@@ -131,12 +131,11 @@
         if (isReference()) {
             super.dieOnCircularReference(stk, p);
         } else {
-            for (Iterator i = extensions.iterator(); i.hasNext();) {
-                pushAndInvokeCircularReferenceCheck((ExtensionAdapter) i.next(),
-                                                    stk, p);
+            for (ExtensionAdapter extensionAdapter : extensions) {
+                pushAndInvokeCircularReferenceCheck(extensionAdapter, stk, p);
             }
-            for (Iterator i = extensionsFilesets.iterator(); i.hasNext();) {
-                pushAndInvokeCircularReferenceCheck((FileSet) i.next(), stk, p);
+            for (FileSet fileSet : extensionsFilesets) {
+                pushAndInvokeCircularReferenceCheck(fileSet, stk, p);
             }
             setChecked(true);
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionUtil.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionUtil.java
index 8f65fd4..4be001c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionUtil.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionUtil.java
@@ -20,10 +20,10 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.jar.JarFile;
 import java.util.jar.Manifest;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.DirectoryScanner;
@@ -48,19 +48,10 @@
      * @param adapters the list of ExtensionAdapters to add to convert
      * @throws BuildException if an error occurs
      */
-    static ArrayList toExtensions(final List adapters)
+    static ArrayList<Extension> toExtensions(final List<? extends ExtensionAdapter> adapters)
         throws BuildException {
-        final ArrayList results = new ArrayList();
-
-        final int size = adapters.size();
-        for (int i = 0; i < size; i++) {
-            final ExtensionAdapter adapter =
-                (ExtensionAdapter) adapters.get(i);
-            final Extension extension = adapter.toExtension();
-            results.add(extension);
-        }
-
-        return results;
+        return adapters.stream().map(ExtensionAdapter::toExtension)
+            .collect(Collectors.toCollection(ArrayList::new));
     }
 
     /**
@@ -71,14 +62,12 @@
      * @throws BuildException if an error occurs
      */
     static void extractExtensions(final Project project,
-                                   final List libraries,
-                                   final List fileset)
+                                   final List<Extension> libraries,
+                                   final List<FileSet> fileset)
         throws BuildException {
         if (!fileset.isEmpty()) {
-            final Extension[] extensions = getExtensions(project,
-                                                          fileset);
-            for (int i = 0; i < extensions.length; i++) {
-                libraries.add(extensions[ i ]);
+            for (Extension extension : getExtensions(project, fileset)) {
+                libraries.add(extension);
             }
         }
     }
@@ -91,13 +80,11 @@
      * @throws BuildException if failing to scan libraries
      */
     private static Extension[] getExtensions(final Project project,
-                                              final List libraries)
+                                              final List<FileSet> libraries)
         throws BuildException {
-        final ArrayList extensions = new ArrayList();
-        final Iterator iterator = libraries.iterator();
-        while (iterator.hasNext()) {
-            final FileSet fileSet = (FileSet) iterator.next();
+        final List<Extension> extensions = new ArrayList<>();
 
+        for (FileSet fileSet : libraries) {
             boolean includeImpl = true;
             boolean includeURL = true;
 
@@ -115,7 +102,7 @@
                 loadExtensions(file, extensions, includeImpl, includeURL);
             }
         }
-        return (Extension[]) extensions.toArray(new Extension[extensions.size()]);
+        return extensions.toArray(new Extension[extensions.size()]);
     }
 
     /**
@@ -126,23 +113,17 @@
      * @throws BuildException if there is an error
      */
     private static void loadExtensions(final File file,
-                                        final List extensionList,
+                                        final List<Extension> extensionList,
                                         final boolean includeImpl,
                                         final boolean includeURL)
         throws BuildException {
-        JarFile jarFile = null;
-        try {
-            jarFile = new JarFile(file);
-            final Extension[] extensions =
-                Extension.getAvailable(jarFile.getManifest());
-            for (int i = 0; i < extensions.length; i++) {
-                final Extension extension = extensions[ i ];
+        try (JarFile jarFile = new JarFile(file)) {
+            for (Extension extension : Extension
+                .getAvailable(jarFile.getManifest())) {
                 addExtension(extensionList, extension, includeImpl, includeURL);
             }
         } catch (final Exception e) {
             throw new BuildException(e.getMessage(), e);
-        } finally {
-            close(jarFile);
         }
     }
 
@@ -157,7 +138,7 @@
      * @param includeImpl false to exclude implementation details
      * @param includeURL false to exclude implementation URL
      */
-    private static void addExtension(final List extensionList,
+    private static void addExtension(final List<Extension> extensionList,
                                       final Extension originalExtension,
                                       final boolean includeImpl,
                                       final boolean includeURL) {
@@ -204,28 +185,15 @@
      */
     static Manifest getManifest(final File file)
         throws BuildException {
-        JarFile jarFile = null;
-        try {
-            jarFile = new JarFile(file);
+        try (JarFile jarFile = new JarFile(file)) {
             Manifest m = jarFile.getManifest();
             if (m == null) {
-                throw new BuildException(file + " doesn't have a MANIFEST");
+                throw new BuildException("%s doesn't have a MANIFEST", file);
             }
             return m;
         } catch (final IOException ioe) {
             throw new BuildException(ioe.getMessage(), ioe);
-        } finally {
-            close(jarFile);
         }
     }
 
-    private static void close(JarFile device) {
-        if (null != device) {
-            try {
-                device.close();
-            } catch (IOException e) {
-                //ignore
-            }
-        }
-    }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtraAttribute.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtraAttribute.java
index d52bec4..21d1144 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtraAttribute.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtraAttribute.java
@@ -73,11 +73,11 @@
      */
     public void validate() throws BuildException {
         if (null == name) {
-            final String message = "Missing name from parameter.";
-            throw new BuildException(message);
-        } else if (null == value) {
-            final String message = "Missing value from parameter " + name + ".";
-            throw new BuildException(message);
+            throw new BuildException("Missing name from parameter.");
+        }
+        if (null == value) {
+            throw new BuildException(
+                "Missing value from parameter " + name + ".");
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibAvailableTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibAvailableTask.java
index 4cce0f5..cde8834 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibAvailableTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibAvailableTask.java
@@ -18,11 +18,12 @@
 package org.apache.tools.ant.taskdefs.optional.extension;
 
 import java.io.File;
-import java.util.Iterator;
+import java.util.List;
 import java.util.Vector;
-import java.util.jar.Manifest;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
 
 /**
@@ -40,7 +41,7 @@
      * Filesets specifying all the libraries
      * to display information about.
      */
-    private final Vector extensionFileSets = new Vector();
+    private final List<ExtensionSet> extensionFileSets = new Vector<>();
 
     /**
      * The name of the property to set if extension is available.
@@ -77,9 +78,8 @@
      */
     public void addConfiguredExtension(final ExtensionAdapter extension) {
         if (null != requiredExtension) {
-            final String message = "Can not specify extension to "
-                + "search for multiple times.";
-            throw new BuildException(message);
+            throw new BuildException(
+                "Can not specify extension to search for multiple times.");
         }
         requiredExtension = extension;
     }
@@ -90,7 +90,7 @@
      * @param extensionSet a set of extensions to search in.
      */
     public void addConfiguredExtensionSet(final ExtensionSet extensionSet) {
-        extensionFileSets.addElement(extensionSet);
+        extensionFileSets.add(extensionSet);
     }
 
     /**
@@ -98,35 +98,24 @@
      *
      * @throws BuildException if something goes wrong.
      */
+    @Override
     public void execute() throws BuildException {
         validate();
 
-        final Extension test = requiredExtension.toExtension();
+        final Project prj = getProject();
+        final Stream<Extension> extensions;
 
         // Check if list of files to check has been specified
         if (!extensionFileSets.isEmpty()) {
-            final Iterator iterator = extensionFileSets.iterator();
-            while (iterator.hasNext()) {
-                final ExtensionSet extensionSet
-                    = (ExtensionSet) iterator.next();
-                final Extension[] extensions =
-                    extensionSet.toExtensions(getProject());
-                for (int i = 0; i < extensions.length; i++) {
-                    final Extension extension = extensions[ i ];
-                    if (extension.isCompatibleWith(test)) {
-                        getProject().setNewProperty(propertyName, "true");
-                    }
-                }
-            }
+            extensions = extensionFileSets.stream()
+                .map(xset -> xset.toExtensions(prj)).flatMap(Stream::of);
         } else {
-            final Manifest manifest = ExtensionUtil.getManifest(libraryFile);
-            final Extension[] extensions = Extension.getAvailable(manifest);
-            for (int i = 0; i < extensions.length; i++) {
-                final Extension extension = extensions[ i ];
-                if (extension.isCompatibleWith(test)) {
-                    getProject().setNewProperty(propertyName, "true");
-                }
-            }
+            extensions = Stream.of(
+                Extension.getAvailable(ExtensionUtil.getManifest(libraryFile)));
+        }
+        final Extension test = requiredExtension.toExtension();
+        if (extensions.anyMatch(x -> x.isCompatibleWith(test))) {
+            prj.setNewProperty(propertyName, "true");
         }
     }
 
@@ -137,21 +126,16 @@
      */
     private void validate() throws BuildException {
         if (null == requiredExtension) {
-            final String message = "Extension element must be specified.";
-            throw new BuildException(message);
+            throw new BuildException("Extension element must be specified.");
         }
-
-        if (null == libraryFile && extensionFileSets.isEmpty()) {
-            final String message = "File attribute not specified.";
-            throw new BuildException(message);
-        }
-        if (null != libraryFile && !libraryFile.exists()) {
-            final String message = "File '" + libraryFile + "' does not exist.";
-            throw new BuildException(message);
-        }
-        if (null != libraryFile && !libraryFile.isFile()) {
-            final String message = "\'" + libraryFile + "\' is not a file.";
-            throw new BuildException(message);
+        if (null == libraryFile) {
+            if (extensionFileSets.isEmpty()) {
+                throw new BuildException("File attribute not specified.");
+            }
+        } else if (!libraryFile.exists()) {
+            throw new BuildException("File '%s' does not exist.", libraryFile);
+        } else if (!libraryFile.isFile()) {
+            throw new BuildException("'%s' is not a file.", libraryFile);
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibDisplayTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibDisplayTask.java
index d441b32..8282033 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibDisplayTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibDisplayTask.java
@@ -18,7 +18,7 @@
 package org.apache.tools.ant.taskdefs.optional.extension;
 
 import java.io.File;
-import java.util.Iterator;
+import java.util.List;
 import java.util.Vector;
 
 import org.apache.tools.ant.BuildException;
@@ -49,7 +49,7 @@
      * Filesets specifying all the libraries
      * to display information about.
      */
-    private final Vector libraryFileSets = new Vector();
+    private final List<FileSet> libraryFileSets = new Vector<>();
 
     /**
      * The JAR library to display information for.
@@ -66,7 +66,7 @@
      * @param fileSet a set of files about which library data will be displayed.
      */
     public void addFileset(final FileSet fileSet) {
-        libraryFileSets.addElement(fileSet);
+        libraryFileSets.add(fileSet);
     }
 
     /**
@@ -74,26 +74,23 @@
      *
      * @throws BuildException if the task fails.
      */
+    @Override
     public void execute() throws BuildException {
         validate();
 
         final LibraryDisplayer displayer = new LibraryDisplayer();
         // Check if list of files to check has been specified
-        if (!libraryFileSets.isEmpty()) {
-            final Iterator iterator = libraryFileSets.iterator();
-            while (iterator.hasNext()) {
-                final FileSet fileSet = (FileSet) iterator.next();
-                final DirectoryScanner scanner
-                    = fileSet.getDirectoryScanner(getProject());
+        if (libraryFileSets.isEmpty()) {
+            displayer.displayLibrary(libraryFile);
+        } else {
+            for (FileSet fileSet : libraryFileSets) {
+                final DirectoryScanner scanner =
+                    fileSet.getDirectoryScanner(getProject());
                 final File basedir = scanner.getBasedir();
-                final String[] files = scanner.getIncludedFiles();
-                for (int i = 0; i < files.length; i++) {
-                    final File file = new File(basedir, files[ i ]);
-                    displayer.displayLibrary(file);
+                for (String filename : scanner.getIncludedFiles()) {
+                    displayer.displayLibrary(new File(basedir, filename));
                 }
             }
-        } else {
-            displayer.displayLibrary(libraryFile);
         }
     }
 
@@ -103,17 +100,14 @@
      * @throws BuildException if invalid parameters found
      */
     private void validate() throws BuildException {
-        if (null == libraryFile && libraryFileSets.isEmpty()) {
-            final String message = "File attribute not specified.";
-            throw new BuildException(message);
-        }
-        if (null != libraryFile && !libraryFile.exists()) {
-            final String message = "File '" + libraryFile + "' does not exist.";
-            throw new BuildException(message);
-        }
-        if (null != libraryFile && !libraryFile.isFile()) {
-            final String message = "\'" + libraryFile + "\' is not a file.";
-            throw new BuildException(message);
+        if (null == libraryFile) {
+            if (libraryFileSets.isEmpty()) {
+                throw new BuildException("File attribute not specified.");
+            }
+        } else if (!libraryFile.exists()) {
+            throw new BuildException("File '%s' does not exist.", libraryFile);
+        } else if (!libraryFile.isFile()) {
+            throw new BuildException("'%s' is not a file.", libraryFile);
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibManifestTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibManifestTask.java
index 9941c86..7834309 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibManifestTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibManifestTask.java
@@ -18,18 +18,21 @@
 package org.apache.tools.ant.taskdefs.optional.extension;
 
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
 import java.util.ArrayList;
-import java.util.Iterator;
+import java.util.List;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.MagicNames;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
-import org.apache.tools.ant.util.FileUtils;
 
 /**
  * Generates a manifest that declares all the dependencies.
@@ -71,19 +74,19 @@
      * ExtensionAdapter objects representing
      * dependencies required by library.
      */
-    private final ArrayList dependencies = new ArrayList();
+    private final List<ExtensionSet> dependencies = new ArrayList<>();
 
     /**
      * ExtensionAdapter objects representing optional
      * dependencies required by library.
      */
-    private final ArrayList optionals = new ArrayList();
+    private final List<ExtensionSet> optionals = new ArrayList<>();
 
     /**
      * Extra attributes the user specifies for main section
      * in manifest.
      */
-    private final ArrayList extraAttributes = new ArrayList();
+    private final List<ExtraAttribute> extraAttributes = new ArrayList<>();
 
     /**
      * The location where generated manifest is placed.
@@ -105,7 +108,8 @@
     public void addConfiguredExtension(final ExtensionAdapter extensionAdapter)
             throws BuildException {
         if (null != extension) {
-            throw new BuildException("Can not have multiple extensions defined in one library.");
+            throw new BuildException(
+                "Can not have multiple extensions defined in one library.");
         }
         extension = extensionAdapter.toExtension();
     }
@@ -142,6 +146,7 @@
      *
      * @throws BuildException if the task fails.
      */
+    @Override
     public void execute() throws BuildException {
         validate();
 
@@ -159,13 +164,13 @@
         }
 
         //Add all the dependency data to manifest for dependencies
-        final ArrayList depends = toExtensions(dependencies);
+        final List<Extension> depends = toExtensions(dependencies);
         appendExtensionList(attributes, Extension.EXTENSION_LIST, "lib", depends.size());
         appendLibraryList(attributes, "lib", depends);
 
         // Add all the dependency data to manifest for "optional"
         //dependencies
-        final ArrayList option = toExtensions(optionals);
+        final List<Extension> option = toExtensions(optionals);
         appendExtensionList(attributes, Extension.OPTIONAL_EXTENSION_LIST, "opt", option.size());
         appendLibraryList(attributes, "opt", option);
 
@@ -187,7 +192,7 @@
             throw new BuildException("Destfile attribute not specified.");
         }
         if (destFile.exists() && !destFile.isFile()) {
-            throw new BuildException(destFile + " is not a file.");
+            throw new BuildException("%s is not a file.", destFile);
         }
     }
 
@@ -198,12 +203,8 @@
      *        attributes to
      */
     private void appendExtraAttributes(final Attributes attributes) {
-        final Iterator iterator = extraAttributes.iterator();
-        while (iterator.hasNext()) {
-            final ExtraAttribute attribute =
-                (ExtraAttribute) iterator.next();
-            attributes.putValue(attribute.getName(),
-                                 attribute.getValue());
+        for (ExtraAttribute attribute : extraAttributes) {
+            attributes.putValue(attribute.getName(), attribute.getValue());
         }
     }
 
@@ -214,13 +215,9 @@
      * @throws IOException if error writing file
      */
     private void writeManifest(final Manifest manifest) throws IOException {
-        FileOutputStream output = null;
-        try {
-            output = new FileOutputStream(destFile);
+        try (OutputStream output = Files.newOutputStream(destFile.toPath())) {
             manifest.write(output);
             output.flush();
-        } finally {
-            FileUtils.close(output);
         }
     }
 
@@ -236,12 +233,11 @@
      * @throws BuildException if an error occurs
      */
     private void appendLibraryList(final Attributes attributes, final String listPrefix,
-            final ArrayList extensions) throws BuildException {
+            final List<Extension> extensions) throws BuildException {
         final int size = extensions.size();
         for (int i = 0; i < size; i++) {
-            final Extension ext = (Extension) extensions.get(i);
-            final String prefix = listPrefix + i + "-";
-            Extension.addExtension(ext, prefix, attributes);
+            Extension.addExtension(extensions.get(i), listPrefix + i + "-",
+                attributes);
         }
     }
 
@@ -258,15 +254,10 @@
      */
     private void appendExtensionList(final Attributes attributes,
             final Attributes.Name extensionKey, final String listPrefix, final int size) {
-        final StringBuffer sb = new StringBuffer();
-        for (int i = 0; i < size; i++) {
-            sb.append(listPrefix);
-            sb.append(i);
-            sb.append(' ');
-        }
         //add in something like
         //"Extension-List: javahelp java3d"
-        attributes.put(extensionKey, sb.toString());
+        attributes.put(extensionKey, IntStream.range(0, size)
+            .mapToObj(i -> listPrefix + i).collect(Collectors.joining(" ")));
     }
 
     /**
@@ -275,17 +266,10 @@
      * @param extensionSets the list of ExtensionSets to add to list
      * @throws BuildException if an error occurs
      */
-    private ArrayList toExtensions(final ArrayList extensionSets) throws BuildException {
-        final ArrayList results = new ArrayList();
-
-        final int size = extensionSets.size();
-        for (int i = 0; i < size; i++) {
-            final ExtensionSet set = (ExtensionSet) extensionSets.get(i);
-            final Extension[] extensions = set.toExtensions(getProject());
-            for (int j = 0; j < extensions.length; j++) {
-                results.add(extensions[ j ]);
-            }
-        }
-        return results;
+    private List<Extension> toExtensions(final List<ExtensionSet> extensionSets)
+        throws BuildException {
+        final Project prj = getProject();
+        return extensionSets.stream().map(xset -> xset.toExtensions(prj))
+            .flatMap(Stream::of).collect(Collectors.toList());
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibResolveTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibResolveTask.java
index 9ebb4e3..e1be055 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibResolveTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibResolveTask.java
@@ -19,6 +19,7 @@
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.jar.Manifest;
 
 import org.apache.tools.ant.BuildException;
@@ -49,7 +50,7 @@
     /**
      * The set of resolvers to use to attempt to locate library.
      */
-    private final ArrayList resolvers = new ArrayList();
+    private final List<ExtensionResolver> resolvers = new ArrayList<>();
 
     /**
      * Flag to indicate that you should check that
@@ -132,9 +133,8 @@
      */
     public void addConfiguredExtension(final ExtensionAdapter extension) {
         if (null != requiredExtension) {
-            final String message = "Can not specify extension to "
-                + "resolve multiple times.";
-            throw new BuildException(message);
+            throw new BuildException(
+                "Can not specify extension to resolve multiple times.");
         }
         requiredExtension = extension.toExtension();
     }
@@ -144,6 +144,7 @@
      *
      * @throws BuildException if the task fails.
      */
+    @Override
     public void execute() throws BuildException {
         validate();
 
@@ -160,28 +161,26 @@
             return;
         }
 
-        final int size = resolvers.size();
-        for (int i = 0; i < size; i++) {
-            final ExtensionResolver resolver =
-                (ExtensionResolver) resolvers.get(i);
-
+        for (ExtensionResolver resolver : resolvers) {
             getProject().log("Searching for extension using Resolver:" + resolver,
                     Project.MSG_VERBOSE);
-
             try {
-                final File file = resolver.resolve(requiredExtension, getProject());
+                final File file =
+                    resolver.resolve(requiredExtension, getProject());
                 try {
                     checkExtension(file);
                     return;
                 } catch (final BuildException be) {
-                    final String message = "File " + file + " returned by "
-                            + "resolver failed to satisfy extension due to: " + be.getMessage();
-                    getProject().log(message, Project.MSG_WARN);
+                    getProject().log("File " + file + " returned by "
+                        + "resolver failed to satisfy extension due to: "
+                        + be.getMessage(), Project.MSG_WARN);
                 }
             } catch (final BuildException be) {
-                final String message = "Failed to resolve extension to file " + "using resolver "
-                        + resolver + " due to: " + be;
-                getProject().log(message, Project.MSG_WARN);
+                getProject()
+                    .log(
+                        "Failed to resolve extension to file "
+                            + "using resolver " + resolver + " due to: " + be,
+                        Project.MSG_WARN);
             }
         }
         missingExtension();
@@ -210,10 +209,10 @@
      */
     private void checkExtension(final File file) {
         if (!file.exists()) {
-            throw new BuildException("File " + file + " does not exist");
+            throw new BuildException("File %s does not exist", file);
         }
         if (!file.isFile()) {
-            throw new BuildException("File " + file + " is not a file");
+            throw new BuildException("File %s is not a file", file);
         }
         if (!checkExtension) {
             getProject().log("Setting property to " + file
@@ -223,9 +222,7 @@
             getProject().log("Checking file " + file + " to see if it satisfies extension",
                     Project.MSG_VERBOSE);
             final Manifest manifest = ExtensionUtil.getManifest(file);
-            final Extension[] extensions = Extension.getAvailable(manifest);
-            for (int i = 0; i < extensions.length; i++) {
-                final Extension extension = extensions[ i ];
+            for (final Extension extension : Extension.getAvailable(manifest)) {
                 if (extension.isCompatibleWith(requiredExtension)) {
                     setLibraryProperty(file);
                     return;
@@ -256,13 +253,10 @@
      */
     private void validate() throws BuildException {
         if (null == propertyName) {
-            final String message = "Property attribute must be specified.";
-            throw new BuildException(message);
+            throw new BuildException("Property attribute must be specified.");
         }
-
         if (null == requiredExtension) {
-            final String message = "Extension element must be specified.";
-            throw new BuildException(message);
+            throw new BuildException("Extension element must be specified.");
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibFileSet.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibFileSet.java
index 94dc879..3a877ac 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibFileSet.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibFileSet.java
@@ -25,8 +25,7 @@
  * how they are to be handled when building manifests.
  *
  */
-public class LibFileSet
-    extends FileSet {
+public class LibFileSet extends FileSet {
     /**
      * Flag indicating whether should include the
      * "Implementation-URL" attribute in manifest.
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibraryDisplayer.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibraryDisplayer.java
index 80627f4..0d2af0d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibraryDisplayer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibraryDisplayer.java
@@ -20,6 +20,8 @@
 import java.io.File;
 import java.text.ParseException;
 import java.util.jar.Manifest;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 
@@ -72,32 +74,28 @@
         if (0 != available.length) {
             System.out.println("Extensions Supported By Library:");
             for (int i = 0; i < available.length; i++) {
-                final Extension extension = available[ i ];
-                System.out.println(extension.toString());
+                System.out.println(available[i]);
             }
         }
 
         if (0 != required.length) {
             System.out.println("Extensions Required By Library:");
             for (int i = 0; i < required.length; i++) {
-                final Extension extension = required[ i ];
-                System.out.println(extension.toString());
+                System.out.println(required[i]);
             }
         }
 
         if (0 != options.length) {
             System.out.println("Extensions that will be used by Library if present:");
             for (int i = 0; i < options.length; i++) {
-                final Extension extension = options[ i ];
-                System.out.println(extension.toString());
+                System.out.println(options[i]);
             }
         }
 
         if (0 != specifications.length) {
             System.out.println("Specifications Supported By Library:");
             for (int i = 0; i < specifications.length; i++) {
-                final Specification specification = specifications[ i ];
-                displaySpecification(specification);
+                displaySpecification(specifications[i]);
             }
         }
     }
@@ -138,12 +136,9 @@
     private void displaySpecification(final Specification specification) {
         final String[] sections = specification.getSections();
         if (null != sections) {
-            final StringBuffer sb = new StringBuffer("Sections: ");
-            for (int i = 0; i < sections.length; i++) {
-                sb.append(" ");
-                sb.append(sections[ i ]);
-            }
-            System.out.println(sb);
+            System.out.print("Sections:  ");
+            System.out
+                .println(Stream.of(sections).collect(Collectors.joining(" ")));
         }
         System.out.println(specification.toString());
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java
index 8b09b98..f1d33e2 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java
@@ -19,11 +19,14 @@
 
 import java.text.ParseException;
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.util.DeweyDecimal;
 import org.apache.tools.ant.util.StringUtils;
@@ -167,25 +170,17 @@
     public static Specification[] getSpecifications(final Manifest manifest)
         throws ParseException {
         if (null == manifest) {
-            return new Specification[ 0 ];
+            return new Specification[0];
         }
+        final List<Specification> results = new ArrayList<>();
 
-        final ArrayList results = new ArrayList();
-
-        final Map entries = manifest.getEntries();
-        final Iterator keys = entries.keySet().iterator();
-        while (keys.hasNext()) {
-            final String key = (String) keys.next();
-            final Attributes attributes = (Attributes) entries.get(key);
-            final Specification specification
-                = getSpecification(key, attributes);
-            if (null != specification) {
-                results.add(specification);
-            }
+        for (Map.Entry<String, Attributes> e : manifest.getEntries()
+            .entrySet()) {
+            Optional.ofNullable(getSpecification(e.getKey(), e.getValue()))
+                .ifPresent(results::add);
         }
-
-        final ArrayList trimmedResults = removeDuplicates(results);
-        return (Specification[]) trimmedResults.toArray(new Specification[trimmedResults.size()]);
+        return removeDuplicates(results)
+            .toArray(new Specification[removeDuplicates(results).size()]);
     }
 
     /**
@@ -239,10 +234,10 @@
                 this.specificationVersion
                     = new DeweyDecimal(specificationVersion);
             } catch (final NumberFormatException nfe) {
-                final String error = "Bad specification version format '"
-                    + specificationVersion + "' in '" + specificationTitle
-                    + "'. (Reason: " + nfe + ")";
-                throw new IllegalArgumentException(error);
+                throw new IllegalArgumentException(
+                    "Bad specification version format '" + specificationVersion
+                        + "' in '" + specificationTitle + "'. (Reason: " + nfe
+                        + ")");
             }
         }
 
@@ -253,13 +248,7 @@
         if (null == this.specificationTitle) {
             throw new NullPointerException("specificationTitle");
         }
-
-        String[] copy = null;
-        if (null != sections) {
-            copy = new String[ sections.length ];
-            System.arraycopy(sections, 0, copy, 0, sections.length);
-        }
-        this.sections = copy;
+        this.sections = sections == null ? null : sections.clone();
     }
 
     /**
@@ -324,12 +313,7 @@
      *         or null if relevant to no sections.
      */
     public String[] getSections() {
-        if (null == sections) {
-            return null;
-        }
-        final String[] newSections = new String[ sections.length ];
-        System.arraycopy(sections, 0, newSections, 0, sections.length);
-        return newSections;
+        return sections == null ? null : sections.clone();
     }
 
     /**
@@ -390,7 +374,7 @@
      * @return true if the specification is compatible with this specification
      */
     public boolean isCompatibleWith(final Specification other) {
-        return (COMPATIBLE == getCompatibilityWith(other));
+        return COMPATIBLE == getCompatibilityWith(other);
     }
 
     /**
@@ -398,11 +382,12 @@
      *
      * @return string representation of object.
      */
+    @Override
     public String toString() {
         final String brace = ": ";
 
-        final StringBuffer sb
-            = new StringBuffer(SPECIFICATION_TITLE.toString());
+        final StringBuilder sb
+            = new StringBuilder(SPECIFICATION_TITLE.toString());
         sb.append(brace);
         sb.append(specificationTitle);
         sb.append(StringUtils.LINE_SEP);
@@ -441,7 +426,6 @@
             sb.append(implementationVendor);
             sb.append(StringUtils.LINE_SEP);
         }
-
         return sb.toString();
     }
 
@@ -467,30 +451,24 @@
      * @param list the array of results to trim
      * @return an array list with all duplicates removed
      */
-    private static ArrayList removeDuplicates(final ArrayList list) {
-        final ArrayList results = new ArrayList();
-        final ArrayList sections = new ArrayList();
-        while (list.size() > 0) {
-            final Specification specification = (Specification) list.remove(0);
-            final Iterator iterator = list.iterator();
-            while (iterator.hasNext()) {
-                final Specification other = (Specification) iterator.next();
+    private static List<Specification> removeDuplicates(final List<Specification> list) {
+        final List<Specification> results = new ArrayList<>();
+        final List<String> sections = new ArrayList<>();
+        while (!list.isEmpty()) {
+            final Specification specification = list.remove(0);
+            for (final Iterator<Specification> iterator =
+                list.iterator(); iterator.hasNext();) {
+                final Specification other = iterator.next();
                 if (isEqual(specification, other)) {
-                    final String[] otherSections = other.getSections();
-                    if (null != otherSections) {
-                        sections.addAll(Arrays.asList(otherSections));
-                    }
+                    Optional.ofNullable(other.getSections())
+                        .ifPresent(s -> Collections.addAll(sections, s));
                     iterator.remove();
                 }
             }
-
-            final Specification merged =
-                mergeInSections(specification, sections);
-            results.add(merged);
+            results.add(mergeInSections(specification, sections));
             //Reset list of sections
             sections.clear();
         }
-
         return results;
     }
 
@@ -522,22 +500,23 @@
      * @return the merged specification
      */
     private static Specification mergeInSections(final Specification specification,
-                                              final ArrayList sectionsToAdd) {
-        if (0 == sectionsToAdd.size()) {
+                                              final List<String> sectionsToAdd) {
+        if (sectionsToAdd.isEmpty()) {
             return specification;
         }
-        sectionsToAdd.addAll(Arrays.asList(specification.getSections()));
-
-        final String[] sections =
-            (String[]) sectionsToAdd.toArray(new String[sectionsToAdd.size()]);
+        Stream<String> sections =
+            Stream
+                .concat(
+                    Optional.ofNullable(specification.getSections())
+                        .map(Stream::of).orElse(Stream.empty()),
+                    sectionsToAdd.stream());
 
         return new Specification(specification.getSpecificationTitle(),
                 specification.getSpecificationVersion().toString(),
                 specification.getSpecificationVendor(),
                 specification.getImplementationTitle(),
                 specification.getImplementationVersion(),
-                specification.getImplementationVendor(),
-                sections);
+                specification.getImplementationVendor(), sections.toArray(String[]::new));
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/AntResolver.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/AntResolver.java
index 6284679..b174455 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/AntResolver.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/AntResolver.java
@@ -66,6 +66,7 @@
      * @return the file resolved
      * @throws BuildException if the file cannot be resolved
      */
+    @Override
     public File resolve(final Extension extension,
                          final Project project) throws BuildException {
         validate();
@@ -111,6 +112,7 @@
      * Returns a string representation
      * @return the string representation
      */
+    @Override
     public String toString() {
         return "Ant[" + antfile + "==>" + destfile + "]";
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/LocationResolver.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/LocationResolver.java
index e2fec02..8d3e9bc 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/LocationResolver.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/LocationResolver.java
@@ -46,19 +46,19 @@
      * @return the file resolved
      * @throws BuildException if no location is set
      */
+    @Override
     public File resolve(final Extension extension,
                         final Project project) throws BuildException {
         if (null == location) {
-            final String message = "No location specified for resolver";
-            throw new BuildException(message);
+            throw new BuildException("No location specified for resolver");
         }
-
         return project.resolveFile(location);
     }
     /**
      * Returns a string representation of the Location
      * @return the string representation
      */
+    @Override
     public String toString() {
         return "Location[" + location + "]";
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/URLResolver.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/URLResolver.java
index d693b89..7e3dca5 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/URLResolver.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/URLResolver.java
@@ -66,6 +66,7 @@
      * @return file the file resolved
      * @throws BuildException if the URL is invalid
      */
+    @Override
     public File resolve(final Extension extension,
                          final Project project) throws BuildException {
         validate();
@@ -110,16 +111,15 @@
      */
     private void validate() {
         if (null == url) {
-            final String message = "Must specify URL";
-            throw new BuildException(message);
+            throw new BuildException("Must specify URL");
         }
-
         if (null == destdir && null == destfile) {
-            final String message = "Must specify destination file or directory";
-            throw new BuildException(message);
-        } else if (null != destdir && null != destfile) {
-            final String message = "Must not specify both destination file or directory";
-            throw new BuildException(message);
+            throw new BuildException(
+                "Must specify destination file or directory");
+        }
+        if (null != destdir && null != destfile) {
+            throw new BuildException(
+                "Must not specify both destination file or directory");
         }
     }
 
@@ -127,6 +127,7 @@
      * Returns a string representation of the URL
      * @return the string representation
      */
+    @Override
     public String toString() {
         return "URL[" + url + "]";
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/i18n/Translate.java b/src/main/org/apache/tools/ant/taskdefs/optional/i18n/Translate.java
index 26c5996..edcced8 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/i18n/Translate.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/i18n/Translate.java
@@ -20,13 +20,15 @@
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
+import java.nio.file.Files;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Vector;
 
 import org.apache.tools.ant.BuildException;
@@ -137,12 +139,12 @@
     /**
      * Vector to hold source file sets.
      */
-    private Vector filesets = new Vector();
+    private List<FileSet> filesets = new Vector<>();
 
     /**
      * Holds key value pairs loaded from resource bundle file
      */
-    private Hashtable resourceMap = new Hashtable();
+    private Map<String, String> resourceMap = new Hashtable<>();
     /**
 
      * Used to resolve file names.
@@ -268,7 +270,7 @@
      * @param set the fileset to be added
      */
     public void addFileset(FileSet set) {
-        filesets.addElement(set);
+        filesets.add(set);
     }
 
     /**
@@ -280,6 +282,7 @@
      *       <li>endtoken</li>
      *            </ul>
      */
+    @Override
     public void execute() throws BuildException {
         if (bundle == null) {
             throw new BuildException("The bundle attribute must be set.",
@@ -318,7 +321,7 @@
         if (!toDir.exists()) {
             toDir.mkdirs();
         } else if (toDir.isFile()) {
-            throw new BuildException(toDir + " is not a directory");
+            throw new BuildException("%s is not a directory", toDir);
         }
 
         if (srcEncoding == null) {
@@ -361,23 +364,18 @@
         Locale locale = new Locale(bundleLanguage,
                                    bundleCountry,
                                    bundleVariant);
+
         String language = locale.getLanguage().length() > 0
             ? "_" + locale.getLanguage() : "";
         String country = locale.getCountry().length() > 0
             ? "_" + locale.getCountry() : "";
         String variant = locale.getVariant().length() > 0
             ? "_" + locale.getVariant() : "";
-        String bundleFile = bundle + language + country + variant;
-        processBundle(bundleFile, BUNDLE_SPECIFIED_LANGUAGE_COUNTRY_VARIANT, false);
 
-        bundleFile = bundle + language + country;
-        processBundle(bundleFile, BUNDLE_SPECIFIED_LANGUAGE_COUNTRY, false);
-
-        bundleFile = bundle + language;
-        processBundle(bundleFile, BUNDLE_SPECIFIED_LANGUAGE, false);
-
-        bundleFile = bundle;
-        processBundle(bundleFile, BUNDLE_NOMATCH, false);
+        processBundle(bundle + language + country + variant, BUNDLE_SPECIFIED_LANGUAGE_COUNTRY_VARIANT, false);
+        processBundle(bundle + language + country, BUNDLE_SPECIFIED_LANGUAGE_COUNTRY, false);
+        processBundle(bundle + language, BUNDLE_SPECIFIED_LANGUAGE, false);
+        processBundle(bundle, BUNDLE_NOMATCH, false);
 
         //Load default locale bundle files
         //using default file encoding scheme.
@@ -391,14 +389,9 @@
             ? "_" + locale.getVariant() : "";
         bundleEncoding = System.getProperty("file.encoding");
 
-        bundleFile = bundle + language + country + variant;
-        processBundle(bundleFile, BUNDLE_DEFAULT_LANGUAGE_COUNTRY_VARIANT, false);
-
-        bundleFile = bundle + language + country;
-        processBundle(bundleFile, BUNDLE_DEFAULT_LANGUAGE_COUNTRY, false);
-
-        bundleFile = bundle + language;
-        processBundle(bundleFile, BUNDLE_DEFAULT_LANGUAGE, true);
+        processBundle(bundle + language + country + variant, BUNDLE_DEFAULT_LANGUAGE_COUNTRY_VARIANT, false);
+        processBundle(bundle + language + country, BUNDLE_DEFAULT_LANGUAGE_COUNTRY, false);
+        processBundle(bundle + language, BUNDLE_DEFAULT_LANGUAGE, true);
     }
 
     /**
@@ -407,9 +400,9 @@
     private void processBundle(final String bundleFile, final int i,
                                final boolean checkLoaded) throws BuildException {
         final File propsFile = getProject().resolveFile(bundleFile + ".properties");
-        FileInputStream ins = null;
+        InputStream ins = null;
         try {
-            ins = new FileInputStream(propsFile);
+            ins = Files.newInputStream(propsFile.toPath());
             loaded = true;
             bundleLastModified[i] = propsFile.lastModified();
             log("Using " + propsFile, Project.MSG_DEBUG);
@@ -429,12 +422,10 @@
      * Load resourceMap with key value pairs.  Values of existing keys
      * are not overwritten.  Bundle's encoding scheme is used.
      */
-    private void loadResourceMap(FileInputStream ins) throws BuildException {
-        try {
-            BufferedReader in = null;
-            InputStreamReader isr = new InputStreamReader(ins, bundleEncoding);
-            in = new BufferedReader(isr);
-            String line = null;
+    private void loadResourceMap(InputStream ins) throws BuildException {
+        try (BufferedReader in =
+            new BufferedReader(new InputStreamReader(ins, bundleEncoding))) {
+            String line;
             while ((line = in.readLine()) != null) {
                 //So long as the line isn't empty and isn't a comment...
                 if (line.trim().length() > 1 && '#' != line.charAt(0) && '!' != line.charAt(0)) {
@@ -474,9 +465,6 @@
                     }
                 }
             }
-            if (in != null) {
-                in.close();
-            }
         } catch (IOException ioe) {
             throw new BuildException(ioe.getMessage(), getLocation());
         }
@@ -496,9 +484,7 @@
      */
     private void translate() throws BuildException {
         int filesProcessed = 0;
-        final int size = filesets.size();
-        for (int i = 0; i < size; i++) {
-            FileSet fs = (FileSet) filesets.elementAt(i);
+        for (FileSet fs : filesets) {
             DirectoryScanner ds = fs.getDirectoryScanner(getProject());
             String[] srcFiles = ds.getIncludedFiles();
             for (int j = 0; j < srcFiles.length; j++) {
@@ -548,18 +534,14 @@
     }
 
     private void translateOneFile(File src, File dest) throws IOException {
-        BufferedWriter out = null;
-        BufferedReader in = null;
-        try {
-            FileOutputStream fos = new FileOutputStream(dest);
-            out = new BufferedWriter(new OutputStreamWriter(fos, destEncoding));
-            FileInputStream fis = new FileInputStream(src);
-            in = new BufferedReader(new InputStreamReader(fis, srcEncoding));
-            String line;
+        try (BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
+            Files.newOutputStream(dest.toPath()), destEncoding));
+                BufferedReader in = new BufferedReader(new InputStreamReader(
+                    Files.newInputStream(src.toPath()), srcEncoding))) {
             LineTokenizer lineTokenizer = new LineTokenizer();
             lineTokenizer.setIncludeDelims(true);
-            line = lineTokenizer.getToken(in);
-            while ((line) != null) {
+            String line = lineTokenizer.getToken(in);
+            while (line != null) {
                 // 2003-02-21 new replace algorithm by tbee (tbee@tbee.org)
                 // because it wasn't able to replace something like "@aaa;@bbb;"
 
@@ -601,7 +583,7 @@
                         } else {
                             // find the replace string
                             if (resourceMap.containsKey(token)) {
-                                replace = (String) resourceMap.get(token);
+                                replace = resourceMap.get(token);
                             } else {
                                 log("Replacement string missing for: " + token,
                                     Project.MSG_VERBOSE);
@@ -624,9 +606,6 @@
                 out.write(line);
                 line = lineTokenizer.getToken(in);
             }
-        } finally {
-            FileUtils.close(in);
-            FileUtils.close(out);
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/image/Image.java b/src/main/org/apache/tools/ant/taskdefs/optional/image/Image.java
index 108d2e2..6ab58c0 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/image/Image.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/image/Image.java
@@ -18,8 +18,9 @@
 package org.apache.tools.ant.taskdefs.optional.image;
 
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
 import java.util.Locale;
 import java.util.Vector;
 
@@ -27,7 +28,6 @@
 import javax.media.jai.PlanarImage;
 
 import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.DirectoryScanner;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.taskdefs.MatchingTask;
 import org.apache.tools.ant.types.FileSet;
@@ -38,7 +38,6 @@
 import org.apache.tools.ant.types.optional.image.Scale;
 import org.apache.tools.ant.types.optional.image.TransformOperation;
 import org.apache.tools.ant.util.FileNameMapper;
-import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.IdentityMapper;
 import org.apache.tools.ant.util.StringUtils;
 
@@ -54,14 +53,17 @@
  * href="http://java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/">
  * JAI Programming Guide</a>.
  *
+ * @deprecated JAI is not developed any more. Internal APIs that JAI depends on were
+ * scheduled for removal in Java 7 and finally removed in Java 9.
  * @see org.apache.tools.ant.types.optional.image.ImageOperation
  * @see org.apache.tools.ant.types.DataType
  */
+@Deprecated
 public class Image extends MatchingTask {
     // CheckStyle:VisibilityModifier OFF - bc
-    protected Vector instructions = new Vector();
+    protected Vector<ImageOperation> instructions = new Vector<>();
     protected boolean overwrite = false;
-    protected Vector filesets = new Vector();
+    protected Vector<FileSet> filesets = new Vector<>();
     protected File srcDir = null;
     protected File destDir = null;
 
@@ -84,7 +86,7 @@
      * @param set the FileSet to add.
      */
     public void addFileset(FileSet set) {
-        filesets.addElement(set);
+        filesets.add(set);
     }
 
     /**
@@ -234,9 +236,7 @@
                 continue;
             }
 
-            for (int j = 0; j < dstNames.length; ++j){
-
-                final String dstName = dstNames[j];
+            for (String dstName : dstNames) {
                 final File dstFile = new File(dstDir, dstName).getAbsoluteFile();
 
                 if (dstFile.exists()) {
@@ -275,6 +275,7 @@
      * @param file The file to be processed.
      * @deprecated this method isn't used anymore
      */
+    @Deprecated
     public void processFile(File file) {
         processFile(file, new File(destDir == null
                                    ? srcDir : destDir, file.getName()));
@@ -291,14 +292,10 @@
         try {
             log("Processing File: " + file.getAbsolutePath());
 
-            FileSeekableStream input = null;
             PlanarImage image = null;
-            try {
-                input = new FileSeekableStream(file);
+            try (FileSeekableStream input = new FileSeekableStream(file)) {
                 image = JAI.create("stream", input);
-                final int size = instructions.size();
-                for (int i = 0; i < size; i++) {
-                    Object instr = instructions.elementAt(i);
+                for (ImageOperation instr : instructions) {
                     if (instr instanceof TransformOperation) {
                         image = ((TransformOperation) instr)
                             .executeTransformOperation(image);
@@ -306,33 +303,25 @@
                         log("Not a TransformOperation: " + instr);
                     }
                 }
-            } finally {
-                FileUtils.close(input);
             }
 
             File dstParent = newFile.getParentFile();
             if (!dstParent.isDirectory()
                 && !(dstParent.mkdirs() || dstParent.isDirectory())) {
-                throw new BuildException("Failed to create parent directory "
-                                         + dstParent);
+                throw new BuildException("Failed to create parent directory %s",
+                    dstParent);
             }
 
             if (overwrite && newFile.exists() && !newFile.equals(file)) {
                 newFile.delete();
             }
 
-            FileOutputStream stream = null;
-            try {
-                stream = new FileOutputStream(newFile);
-
+            try (OutputStream stream = Files.newOutputStream(newFile.toPath())) {
                 JAI.create("encode", image, stream,
-                           str_encoding.toUpperCase(Locale.ENGLISH),
-                           null);
+                    str_encoding.toUpperCase(Locale.ENGLISH), null);
                 stream.flush();
-            } finally {
-                FileUtils.close(stream);
             }
-        } catch (IOException err) {
+        } catch (IOException | RuntimeException err) {
             if (!file.equals(newFile)) {
                 newFile.delete();
             }
@@ -341,15 +330,6 @@
             } else {
                 throw new BuildException(err);
             }
-        } catch (java.lang.RuntimeException rerr) {
-            if (!file.equals(newFile)){
-                newFile.delete();
-            }
-            if (!failonerror) {
-                log("Error processing file:  " + rerr);
-            } else {
-                throw new BuildException(rerr);
-            }
         }
     }
 
@@ -357,6 +337,7 @@
      * Executes the Task.
      * @throws BuildException on error.
      */
+    @Override
     public void execute() throws BuildException {
 
         validateAttributes();
@@ -367,29 +348,20 @@
             int writeCount = 0;
 
             // build mapper
-            final FileNameMapper mapper;
-            if (mapperElement==null){
-                mapper = new IdentityMapper();
-            } else {
-                mapper = mapperElement.getImplementation();
-            }
+            final FileNameMapper mapper = mapperElement == null
+                ? new IdentityMapper() : mapperElement.getImplementation();
 
             // deal with specified srcDir
             if (srcDir != null) {
-                final DirectoryScanner ds = super.getDirectoryScanner(srcDir);
-
-                final String[] files = ds.getIncludedFiles();
-                writeCount += processDir(srcDir, files, dest, mapper);
+                writeCount += processDir(srcDir,
+                    super.getDirectoryScanner(srcDir).getIncludedFiles(), dest,
+                    mapper);
             }
             // deal with the filesets
-            final int size = filesets.size();
-            for (int i = 0; i < size; i++) {
-                final FileSet fs = (FileSet) filesets.elementAt(i);
-                final DirectoryScanner ds =
-                    fs.getDirectoryScanner(getProject());
-                final String[] files = ds.getIncludedFiles();
-                final File fromDir = fs.getDir(getProject());
-                writeCount += processDir(fromDir, files, dest, mapper);
+            for (FileSet fs : filesets) {
+                writeCount += processDir(fs.getDir(getProject()),
+                    fs.getDirectoryScanner(getProject()).getIncludedFiles(),
+                    dest, mapper);
             }
 
             if (writeCount > 0) {
@@ -409,16 +381,16 @@
      * @throws BuildException on error.
      */
     protected void validateAttributes() throws BuildException {
-        if (srcDir == null && filesets.size() == 0) {
-            throw new BuildException("Specify at least one source"
-                                     + "--a srcDir or a fileset.");
+        if (srcDir == null && filesets.isEmpty()) {
+            throw new BuildException(
+                "Specify at least one source--a srcDir or a fileset.");
         }
         if (srcDir == null && destDir == null) {
             throw new BuildException("Specify the destDir, or the srcDir.");
         }
-        if (str_encoding.equalsIgnoreCase("jpg")) {
+        if ("jpg".equalsIgnoreCase(str_encoding)) {
             str_encoding = "JPEG";
-        } else if (str_encoding.equalsIgnoreCase("tif")) {
+        } else if ("tif".equalsIgnoreCase(str_encoding)) {
             str_encoding = "TIFF";
         }
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/AbstractHotDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/AbstractHotDeploymentTool.java
index 11447e0..b5296bd 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/AbstractHotDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/AbstractHotDeploymentTool.java
@@ -87,13 +87,14 @@
      *  base class.  Subclasses should check attributes accordingly.
      *  @exception org.apache.tools.ant.BuildException if the attributes are invalid or incomplete.
      */
+    @Override
     public void validateAttributes() throws BuildException {
         if (task.getAction() == null) {
             throw new BuildException("The \"action\" attribute must be set");
         }
 
         if (!isActionValid()) {
-            throw new BuildException("Invalid action \"" + task.getAction() + "\" passed");
+            throw new BuildException("Invalid action \"%s\" passed", task.getAction());
         }
 
         if (classpath == null) {
@@ -102,17 +103,11 @@
     }
 
     /**
-     *  Perform the actual deployment.
-     *  It's up to the subclasses to implement the actual behavior.
-     *  @exception org.apache.tools.ant.BuildException if the attributes are invalid or incomplete.
-     */
-    public abstract void deploy() throws BuildException;
-
-    /**
      *  Sets the parent task.
      *  @param task a ServerDeploy object representing the parent task.
      *  @ant.attribute ignore="true"
      */
+    @Override
     public void setTask(ServerDeploy task) {
         this.task = task;
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/GenericHotDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/GenericHotDeploymentTool.java
index 5a5abba..1cb0a7e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/GenericHotDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/GenericHotDeploymentTool.java
@@ -70,8 +70,9 @@
      *  For this generic implementation, the only valid action is "deploy"
      *  @return true if the "action" attribute is valid, false if not.
      */
+    @Override
     protected boolean isActionValid() {
-        return (getTask().getAction().equals(VALID_ACTIONS[0]));
+        return getTask().getAction().equals(VALID_ACTIONS[0]);
     }
 
     /**
@@ -79,6 +80,7 @@
      *  @param task An ServerDeploy object representing the parent task.
      *  @ant.attribute ignored="true"
      */
+    @Override
     public void setTask(ServerDeploy task) {
         super.setTask(task);
         java = new Java(task);
@@ -90,6 +92,7 @@
      *  supplied classpath, classname, JVM args, and command line arguments.
      *  @exception org.apache.tools.ant.BuildException if the attributes are invalid or incomplete.
      */
+    @Override
     public void deploy() throws BuildException {
         java.setClassname(className);
         java.setClasspath(getClasspath());
@@ -103,6 +106,7 @@
      *  Ensures the className and arguments attribute have been set.
      *  @exception org.apache.tools.ant.BuildException if the attributes are invalid or incomplete.
      */
+    @Override
     public void validateAttributes() throws BuildException {
         super.validateAttributes();
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/JonasHotDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/JonasHotDeploymentTool.java
index 4c7866c..1d580fa 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/JonasHotDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/JonasHotDeploymentTool.java
@@ -76,7 +76,6 @@
      */
     private int davidPort;
 
-
     /**
      *  Set the host for the David ORB; required if
      *  ORB==david.
@@ -87,7 +86,6 @@
         davidHost = inValue;
     }
 
-
     /**
      *  Set the port for the David ORB; required if
      *  ORB==david.
@@ -98,7 +96,6 @@
         davidPort = inValue;
     }
 
-
     /**
      *  set the jonas root directory (-Dinstall.root=). This
      *  element is required.
@@ -109,7 +106,6 @@
         jonasroot = inValue;
     }
 
-
     /**
      *
      * Choose your ORB : RMI, JEREMIE, DAVID, ...; optional.
@@ -124,14 +120,13 @@
         orb = inValue;
     }
 
-
     /**
      *  gets the classpath field.
      *
      *@return    A Path representing the "classpath" attribute.
      */
+    @Override
     public Path getClasspath() {
-
         Path aClassPath = super.getClasspath();
 
         if (aClassPath == null) {
@@ -147,7 +142,6 @@
         return aClassPath;
     }
 
-
     /**
      * Validates the passed in attributes.
      *
@@ -161,6 +155,7 @@
      *
      * @exception BuildException if something goes wrong
      */
+    @Override
     public void validateAttributes() throws BuildException {
         // super.validateAttributes(); // don't want to call this method
 
@@ -172,7 +167,7 @@
         }
 
         if (!isActionValid()) {
-            throw new BuildException("Invalid action \"" + action + "\" passed");
+            throw new BuildException("Invalid action \"%s\" passed", action);
         }
 
         if (getClassName() == null) {
@@ -213,9 +208,9 @@
             java.createArg().setLine("-n " + getServer());
         }
 
-        if (action.equals(ACTION_DEPLOY)
-            || action.equals(ACTION_UPDATE)
-            || action.equals("redeploy")) {
+        if (ACTION_DEPLOY.equals(action)
+            || ACTION_UPDATE.equals(action)
+            || "redeploy".equals(action)) {
             java.createArg().setLine("-a " + getTask().getSource());
         } else if (action.equals(ACTION_DELETE) || action.equals(ACTION_UNDEPLOY)) {
             java.createArg().setLine("-r " + getTask().getSource());
@@ -224,7 +219,6 @@
         }
     }
 
-
     /**
      *  Determines if the action supplied is valid. <p>
      *
@@ -234,19 +228,17 @@
      *@return    true if the action attribute is valid, false if
      *      not.
      */
+    @Override
     protected boolean isActionValid() {
-        boolean valid = false;
-
         String action = getTask().getAction();
 
-        for (int i = 0; i < VALID_ACTIONS.length; i++) {
-            if (action.equals(VALID_ACTIONS[i])) {
-                valid = true;
-                break;
+        for (String validAction : VALID_ACTIONS) {
+            if (action.equals(validAction)) {
+                return true;
             }
         }
-
-        return valid;
+        // TODO what about redeploy, mentioned in #validateAttribute
+        return false;
     }
 }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/ServerDeploy.java b/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/ServerDeploy.java
index 8965b8e..7947a7b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/ServerDeploy.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/ServerDeploy.java
@@ -19,7 +19,7 @@
 package org.apache.tools.ant.taskdefs.optional.j2ee;
 
 import java.io.File;
-import java.util.Enumeration;
+import java.util.List;
 import java.util.Vector;
 
 import org.apache.tools.ant.BuildException;
@@ -44,7 +44,7 @@
     private File source;
 
     /** The vendor specific tool for deploying the component **/
-    private Vector vendorTools = new Vector();
+    private List<AbstractHotDeploymentTool> vendorTools = new Vector<>();
 
     ///////////////////////////////////////////////////////////////////////////
     //
@@ -60,7 +60,7 @@
      */
     public void addGeneric(GenericHotDeploymentTool tool) {
         tool.setTask(this);
-        vendorTools.addElement(tool);
+        vendorTools.add(tool);
     }
 
     /**
@@ -71,7 +71,7 @@
      */
     public void addWeblogic(WebLogicHotDeploymentTool tool) {
         tool.setTask(this);
-        vendorTools.addElement(tool);
+        vendorTools.add(tool);
     }
 
     /**
@@ -82,7 +82,7 @@
      */
     public void addJonas(JonasHotDeploymentTool tool) {
         tool.setTask(this);
-        vendorTools.addElement(tool);
+        vendorTools.add(tool);
     }
 
 
@@ -100,10 +100,9 @@
      *  @exception org.apache.tools.ant.BuildException if the attributes
      *  are invalid or incomplete, or a failure occurs in the deployment process.
      */
+    @Override
     public void execute() throws BuildException {
-        for (Enumeration e = vendorTools.elements();
-             e.hasMoreElements();) {
-            HotDeploymentTool tool = (HotDeploymentTool) e.nextElement();
+        for (HotDeploymentTool tool : vendorTools) {
             tool.validateAttributes();
             tool.deploy();
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/WebLogicHotDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/WebLogicHotDeploymentTool.java
index d0dc91b..2838c2d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/WebLogicHotDeploymentTool.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/WebLogicHotDeploymentTool.java
@@ -59,6 +59,7 @@
      *  tools is executed.
      *  @exception BuildException if the attributes are invalid or incomplete.
      */
+    @Override
     public void deploy() {
         Java java = new Java(getTask());
         java.setFork(true);
@@ -80,6 +81,7 @@
      *
      *  @exception BuildException if the attributes are invalid or incomplete
      */
+    @Override
     public void validateAttributes() throws BuildException {
         super.validateAttributes();
 
@@ -93,22 +95,22 @@
         // check for missing application on deploy & update
         if ((action.equals(ACTION_DEPLOY) || action.equals(ACTION_UPDATE))
             && application == null) {
-            throw new BuildException("The application attribute must be set "
-                + "if action = " + action);
+            throw new BuildException(
+                "The application attribute must be set if action = %s", action);
         }
 
         // check for missing source on deploy & update
         if ((action.equals(ACTION_DEPLOY) || action.equals(ACTION_UPDATE))
             && getTask().getSource() == null) {
-            throw new BuildException("The source attribute must be set if "
-                + "action = " + action);
+            throw new BuildException(
+                "The source attribute must be set if action = %s", action);
         }
 
         // check for missing application on delete & undeploy
         if ((action.equals(ACTION_DELETE) || action.equals(ACTION_UNDEPLOY))
             && application == null) {
-            throw new BuildException("The application attribute must be set if "
-                + "action = " + action);
+            throw new BuildException(
+                "The application attribute must be set if action = %s", action);
         }
     }
 
@@ -120,17 +122,17 @@
      */
     public String getArguments() throws BuildException {
         String action = getTask().getAction();
-        String args = null;
 
         if (action.equals(ACTION_DEPLOY) || action.equals(ACTION_UPDATE)) {
-            args = buildDeployArgs();
-        } else if (action.equals(ACTION_DELETE) || action.equals(ACTION_UNDEPLOY)) {
-            args = buildUndeployArgs();
-        } else if (action.equals(ACTION_LIST)) {
-            args = buildListArgs();
+            return buildDeployArgs();
         }
-
-        return args;
+        if (action.equals(ACTION_DELETE) || action.equals(ACTION_UNDEPLOY)) {
+            return buildUndeployArgs();
+        }
+        if (action.equals(ACTION_LIST)) {
+            return buildListArgs();
+        }
+        return null;
     }
 
     /**
@@ -138,19 +140,16 @@
      * <p>Valid actions are contained in the static array VALID_ACTIONS</p>
      * @return true if the action attribute is valid, false if not.
      */
+    @Override
     protected boolean isActionValid() {
-        boolean valid = false;
-
         String action = getTask().getAction();
 
-        for (int i = 0; i < VALID_ACTIONS.length; i++) {
-            if (action.equals(VALID_ACTIONS[i])) {
-                valid = true;
-                break;
+        for (String validAction : VALID_ACTIONS) {
+            if (action.equals(validAction)) {
+                return true;
             }
         }
-
-        return valid;
+        return false;
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJDoc.java b/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJDoc.java
index a4dc0f4..d3aff08 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJDoc.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJDoc.java
@@ -20,8 +20,8 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.Map;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -44,7 +44,7 @@
     private static final String TEXT              = "TEXT";
     private static final String ONE_TABLE         = "ONE_TABLE";
 
-    private final Hashtable optionalAttrs = new Hashtable();
+    private final Map<String, Object> optionalAttrs = new Hashtable<>();
 
     private String outputFile = null;
     private boolean plainText = false;
@@ -65,7 +65,7 @@
      * @param plainText a <code>boolean</code> value.
      */
     public void setText(boolean plainText) {
-        optionalAttrs.put(TEXT, plainText ? Boolean.TRUE : Boolean.FALSE);
+        optionalAttrs.put(TEXT, Boolean.valueOf(plainText));
         this.plainText = plainText;
     }
 
@@ -74,7 +74,7 @@
      * @param oneTable a <code>boolean</code> value.
      */
     public void setOnetable(boolean oneTable) {
-        optionalAttrs.put(ONE_TABLE, oneTable ? Boolean.TRUE : Boolean.FALSE);
+        optionalAttrs.put(ONE_TABLE, Boolean.valueOf(oneTable));
     }
 
     /**
@@ -124,19 +124,15 @@
      * Do the task.
      * @throws BuildException if there is an error.
      */
+    @Override
     public void execute() throws BuildException {
 
         // load command line with optional attributes
-        Enumeration iter = optionalAttrs.keys();
-        while (iter.hasMoreElements()) {
-            String name  = (String) iter.nextElement();
-            Object value = optionalAttrs.get(name);
-            cmdl.createArgument()
-                .setValue("-" + name + ":" + value.toString());
-        }
+        optionalAttrs.forEach((name, value) -> cmdl.createArgument()
+            .setValue("-" + name + ":" + value.toString()));
 
         if (targetFile == null || !targetFile.isFile()) {
-            throw new BuildException("Invalid target: " + targetFile);
+            throw new BuildException("Invalid target: %s", targetFile);
         }
 
         if (outputFile != null) {
@@ -195,8 +191,8 @@
             suffix = DEFAULT_SUFFIX_TEXT;
         }
 
-        if ((optionalOutputFile == null) || optionalOutputFile.equals("")) {
-            int filePos = javaccFile.lastIndexOf("/");
+        if ((optionalOutputFile == null) || optionalOutputFile.isEmpty()) {
+            int filePos = javaccFile.lastIndexOf('/');
 
             if (filePos >= 0) {
                 javaccFile = javaccFile.substring(filePos + 1);
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJTree.java b/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJTree.java
index 3d51afb..433ce22 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJTree.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJTree.java
@@ -20,8 +20,8 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.Map;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -54,7 +54,7 @@
     private static final String VISITOR_EXCEPTION = "VISITOR_EXCEPTION";
     private static final String NODE_PREFIX       = "NODE_PREFIX";
 
-    private final Hashtable optionalAttrs = new Hashtable();
+    private final Map<String, Object> optionalAttrs = new Hashtable<>();
 
     private String outputFile = null;
 
@@ -74,7 +74,7 @@
      * @param buildNodeFiles a <code>boolean</code> value.
      */
     public void setBuildnodefiles(boolean buildNodeFiles) {
-        optionalAttrs.put(BUILD_NODE_FILES, buildNodeFiles ? Boolean.TRUE : Boolean.FALSE);
+        optionalAttrs.put(BUILD_NODE_FILES, Boolean.valueOf(buildNodeFiles));
     }
 
     /**
@@ -82,7 +82,7 @@
      * @param multi a <code>boolean</code> value.
      */
     public void setMulti(boolean multi) {
-        optionalAttrs.put(MULTI, multi ? Boolean.TRUE : Boolean.FALSE);
+        optionalAttrs.put(MULTI, Boolean.valueOf(multi));
     }
 
     /**
@@ -90,7 +90,7 @@
      * @param nodeDefaultVoid a <code>boolean</code> value.
      */
     public void setNodedefaultvoid(boolean nodeDefaultVoid) {
-        optionalAttrs.put(NODE_DEFAULT_VOID, nodeDefaultVoid ? Boolean.TRUE : Boolean.FALSE);
+        optionalAttrs.put(NODE_DEFAULT_VOID, Boolean.valueOf(nodeDefaultVoid));
     }
 
     /**
@@ -98,7 +98,7 @@
      * @param nodeFactory a <code>boolean</code> value.
      */
     public void setNodefactory(boolean nodeFactory) {
-        optionalAttrs.put(NODE_FACTORY, nodeFactory ? Boolean.TRUE : Boolean.FALSE);
+        optionalAttrs.put(NODE_FACTORY, Boolean.valueOf(nodeFactory));
     }
 
     /**
@@ -106,7 +106,7 @@
      * @param nodeScopeHook a <code>boolean</code> value.
      */
     public void setNodescopehook(boolean nodeScopeHook) {
-        optionalAttrs.put(NODE_SCOPE_HOOK, nodeScopeHook ? Boolean.TRUE : Boolean.FALSE);
+        optionalAttrs.put(NODE_SCOPE_HOOK, Boolean.valueOf(nodeScopeHook));
     }
 
     /**
@@ -114,7 +114,7 @@
      * @param nodeUsesParser a <code>boolean</code> value.
      */
     public void setNodeusesparser(boolean nodeUsesParser) {
-        optionalAttrs.put(NODE_USES_PARSER, nodeUsesParser ? Boolean.TRUE : Boolean.FALSE);
+        optionalAttrs.put(NODE_USES_PARSER, Boolean.valueOf(nodeUsesParser));
     }
 
     /**
@@ -122,7 +122,7 @@
      * @param staticParser a <code>boolean</code> value.
      */
     public void setStatic(boolean staticParser) {
-        optionalAttrs.put(STATIC, staticParser ? Boolean.TRUE : Boolean.FALSE);
+        optionalAttrs.put(STATIC, Boolean.valueOf(staticParser));
     }
 
     /**
@@ -130,7 +130,7 @@
      * @param visitor a <code>boolean</code> value.
      */
     public void setVisitor(boolean visitor) {
-        optionalAttrs.put(VISITOR, visitor ? Boolean.TRUE : Boolean.FALSE);
+        optionalAttrs.put(VISITOR, Boolean.valueOf(visitor));
     }
 
     /**
@@ -214,21 +214,18 @@
      * Run the task.
      * @throws BuildException on error.
      */
+    @Override
     public void execute() throws BuildException {
 
         // load command line with optional attributes
-        Enumeration iter = optionalAttrs.keys();
-        while (iter.hasMoreElements()) {
-            String name  = (String) iter.nextElement();
-            Object value = optionalAttrs.get(name);
-            cmdl.createArgument().setValue("-" + name + ":" + value.toString());
-        }
+        optionalAttrs.forEach((name, value) -> cmdl.createArgument()
+            .setValue("-" + name + ":" + value.toString()));
 
         if (targetFile == null || !targetFile.isFile()) {
-            throw new BuildException("Invalid target: " + targetFile);
+            throw new BuildException("Invalid target: %s", targetFile);
         }
 
-        File javaFile = null;
+        File javaFile;
 
         // use the directory containing the target as the output directory
         if (outputDirectory == null) {
@@ -305,8 +302,8 @@
                                                 outputDir);
         String jjtreeFile = destFile.getAbsolutePath().replace('\\', '/');
 
-        if ((optionalOutputFile == null) || optionalOutputFile.equals("")) {
-            int filePos = jjtreeFile.lastIndexOf("/");
+        if ((optionalOutputFile == null) || optionalOutputFile.isEmpty()) {
+            int filePos = jjtreeFile.lastIndexOf('/');
 
             if (filePos >= 0) {
                 jjtreeFile = jjtreeFile.substring(filePos + 1);
@@ -328,7 +325,7 @@
             }
         }
 
-        if ((outputDir == null) || outputDir.equals("")) {
+        if ((outputDir == null) || outputDir.isEmpty()) {
             outputDir = getDefaultOutputDirectory();
         }
 
@@ -363,17 +360,17 @@
 
         String root = getRoot(new File(destFile)).getAbsolutePath();
 
-        if ((root.length() > 1)
+        if (root.length() > 1
             && destFile.startsWith(root.substring(0, root.length() - 1))) {
-            throw new BuildException("Drive letter in 'outputfile' not "
-                                     + "supported: " + destFile);
+            throw new BuildException(
+                "Drive letter in 'outputfile' not supported: %s", destFile);
         }
 
         return destFile;
     }
 
     private String makeOutputFileRelative(String destFile) {
-        StringBuffer relativePath = new StringBuffer();
+        StringBuilder relativePath = new StringBuilder();
         String defaultOutputDirectory = getDefaultOutputDirectory();
         int nextPos = defaultOutputDirectory.indexOf('/');
         int startPos = nextPos + 1;
@@ -388,10 +385,7 @@
                 startPos = nextPos + 1;
             }
         }
-
-        relativePath.append(destFile);
-
-        return relativePath.toString();
+        return relativePath.append(destFile).toString();
     }
 
     private String getDefaultOutputDirectory() {
@@ -410,7 +404,6 @@
         while (root.getParent() != null) {
             root = root.getParentFile();
         }
-
         return root;
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JavaCC.java b/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JavaCC.java
index c8ce319..79a24b8 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JavaCC.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JavaCC.java
@@ -20,8 +20,8 @@
 
 import java.io.File;
 import java.io.InputStream;
-import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.Map;
 
 import org.apache.tools.ant.AntClassLoader;
 import org.apache.tools.ant.BuildException;
@@ -64,7 +64,7 @@
     private static final String KEEP_LINE_COLUMN       = "KEEP_LINE_COLUMN";
     private static final String JDK_VERSION            = "JDK_VERSION";
 
-    private final Hashtable optionalAttrs = new Hashtable();
+    private final Map<String, Object> optionalAttrs = new Hashtable<>();
 
     // required attributes
     private File outputDirectory = null;
@@ -79,19 +79,19 @@
 
     protected static final String[] ARCHIVE_LOCATIONS = //NOSONAR
         new String[] {
-        "JavaCC.zip",
-        "bin/lib/JavaCC.zip",
-        "bin/lib/javacc.jar",
-        "javacc.jar", // used by jpackage for JavaCC 3.x
-    };
+            "JavaCC.zip",
+            "bin/lib/JavaCC.zip",
+            "bin/lib/javacc.jar",
+            "javacc.jar", // used by jpackage for JavaCC 3.x
+        };
 
     protected static final int[] ARCHIVE_LOCATIONS_VS_MAJOR_VERSION = //NOSONAR
         new int[] {
-        1,
-        2,
-        3,
-        3,
-    };
+            1,
+            2,
+            3,
+            3,
+        };
 
     protected static final String COM_PACKAGE = "COM.sun.labs.";
     protected static final String COM_JAVACC_CLASS = "javacc.Main";
@@ -331,19 +331,16 @@
      * Run the task.
      * @throws BuildException on error.
      */
+    @Override
     public void execute() throws BuildException {
 
         // load command line with optional attributes
-        Enumeration iter = optionalAttrs.keys();
-        while (iter.hasMoreElements()) {
-            String name  = (String) iter.nextElement();
-            Object value = optionalAttrs.get(name);
-            cmdl.createArgument().setValue("-" + name + ":" + value.toString());
-        }
+        optionalAttrs.forEach((name, value) -> cmdl.createArgument()
+            .setValue("-" + name + ":" + value));
 
         // check the target is a file
         if (targetFile == null || !targetFile.isFile()) {
-            throw new BuildException("Invalid target: " + targetFile);
+            throw new BuildException("Invalid target: %s", targetFile);
         }
 
         // use the directory containing the target as the output directory
@@ -425,12 +422,11 @@
         String packagePrefix = null;
         String mainClass = null;
 
-        AntClassLoader l = null;
-        try {
-            l = AntClassLoader.newAntClassLoader(null, null,
-                                                 path
-                                                 .concatSystemClasspath("ignore"),
-                                                 true);
+        try (AntClassLoader l =
+             AntClassLoader.newAntClassLoader(null, null,
+                                              path
+                                              .concatSystemClasspath("ignore"),
+                                              true)) {
             String javaccClass = COM_PACKAGE + COM_JAVACC_CLASS;
             InputStream is = l.getResourceAsStream(javaccClass.replace('.', '/')
                                                    + ".class");
@@ -498,10 +494,6 @@
                 throw new BuildException("unknown task type " + type);
             }
             return packagePrefix + mainClass;
-        } finally {
-            if (l != null) {
-                l.cleanup();
-            }
         }
     }
 
@@ -528,8 +520,9 @@
             }
         }
 
-        throw new BuildException("Could not find a path to JavaCC.zip "
-                                 + "or javacc.jar from '" + home + "'.");
+        throw new BuildException(
+            "Could not find a path to JavaCC.zip or javacc.jar from '%s'.",
+            home);
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/javah/ForkingJavah.java b/src/main/org/apache/tools/ant/taskdefs/optional/javah/ForkingJavah.java
index c12f594..a537669 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/javah/ForkingJavah.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/javah/ForkingJavah.java
@@ -45,6 +45,7 @@
      * @return true if the compilation was successful.
      * @throws BuildException if there is an error.
      */
+    @Override
     public boolean compile(Javah javah) throws BuildException {
         Commandline cmd = SunJavah.setupJavahCommand(javah);
         Project project = javah.getProject();
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java b/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java
index d40e595..931131b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java
@@ -42,12 +42,11 @@
     public static String getDefault() {
         if (JavaEnvUtils.isKaffe()) {
             return Kaffeh.IMPLEMENTATION_NAME;
-        } else if (JavaEnvUtils.isGij()) {
-            return Gcjh.IMPLEMENTATION_NAME;
-        } else if (JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_9)) {
-            return ForkingJavah.IMPLEMENTATION_NAME;
         }
-        return SunJavah.IMPLEMENTATION_NAME;
+        if (JavaEnvUtils.isGij()) {
+            return Gcjh.IMPLEMENTATION_NAME;
+        }
+        return ForkingJavah.IMPLEMENTATION_NAME;
     }
 
     /**
@@ -86,29 +85,29 @@
         if ((JavaEnvUtils.isKaffe() && choice == null)
             || Kaffeh.IMPLEMENTATION_NAME.equals(choice)) {
             return new Kaffeh();
-        } else if ((JavaEnvUtils.isGij() && choice == null)
+        }
+        if ((JavaEnvUtils.isGij() && choice == null)
             || Gcjh.IMPLEMENTATION_NAME.equals(choice)) {
             return new Gcjh();
-        } else if (JavaEnvUtils.isAtLeastJavaVersion("10") &&
-                   (choice == null || ForkingJavah.IMPLEMENTATION_NAME.equals(choice))) {
+        }
+        if (JavaEnvUtils.isAtLeastJavaVersion("10") &&
+            (choice == null || ForkingJavah.IMPLEMENTATION_NAME.equals(choice))) {
             throw new BuildException("javah does not exist under Java 10 and higher,"
                 + " use the javac task with nativeHeaderDir instead");
-        } else if ((JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_9)
-                    && choice == null)
-                   || ForkingJavah.IMPLEMENTATION_NAME.equals(choice)) {
+        }
+        if (ForkingJavah.IMPLEMENTATION_NAME.equals(choice)) {
             return new ForkingJavah();
-        } else if (SunJavah.IMPLEMENTATION_NAME.equals(choice)) {
+        }
+        if (SunJavah.IMPLEMENTATION_NAME.equals(choice)) {
             return new SunJavah();
-        } else if (choice != null) {
+        }
+        if (choice != null) {
             return resolveClassName(choice,
                                     // Memory leak in line below
                                     log.getProject()
                                     .createClassLoader(classpath));
         }
-
-        // This default has been good enough until Ant 1.6.3, so stick
-        // with it
-        return new SunJavah();
+        return new ForkingJavah();
     }
 
     /**
@@ -123,7 +122,7 @@
     private static JavahAdapter resolveClassName(String className,
                                                  ClassLoader loader)
             throws BuildException {
-        return (JavahAdapter) ClasspathUtils.newInstance(className,
+        return ClasspathUtils.newInstance(className,
                 loader != null ? loader :
                 JavahAdapterFactory.class.getClassLoader(), JavahAdapter.class);
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java b/src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java
index 7911b17..dbfd05c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java
@@ -44,10 +44,11 @@
      * @throws BuildException if there is an error.
      * @since Ant 1.6.3
      */
+    @Override
     public boolean compile(Javah javah) throws BuildException {
         Commandline cmd = setupJavahCommand(javah);
         ExecuteJava ej = new ExecuteJava();
-        Class c = null;
+        Class<?> c;
         try {
             try {
                 // first search for the "old" javah class in 1.4.2 tools.jar
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java
index acccf9f..1aa9228 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java
@@ -24,8 +24,12 @@
 import java.io.PrintWriter;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
-import java.util.Vector;
+import java.util.Optional;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -42,6 +46,8 @@
 import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.LoaderUtils;
 
+import jdepend.textui.JDepend;
+
 /**
  * Runs JDepend tests.
  *
@@ -53,7 +59,6 @@
  *
  */
 public class JDependTask extends Task {
-    //private CommandlineJava commandline = new CommandlineJava();
 
     // required attributes
     private Path sourcesPath; // Deprecated!
@@ -71,7 +76,7 @@
     private String format = "text";
     private PatternSet defaultPatterns = new PatternSet();
 
-    private static Constructor packageFilterC;
+    private static Constructor<?> packageFilterC;
     private static Method setFilter;
 
     private boolean includeRuntime = false;
@@ -79,13 +84,12 @@
 
     static {
         try {
-            Class packageFilter =
+            Class<?> packageFilter =
                 Class.forName("jdepend.framework.PackageFilter");
             packageFilterC =
-                packageFilter.getConstructor(new Class[] {java.util.Collection.class});
+                packageFilter.getConstructor(Collection.class);
             setFilter =
-                jdepend.textui.JDepend.class.getDeclaredMethod("setFilter",
-                                                               new Class[] {packageFilter});
+                JDepend.class.getDeclaredMethod("setFilter", packageFilter);
         } catch (Throwable t) {
             if (setFilter == null) {
                 packageFilterC = null;
@@ -189,6 +193,7 @@
      * @return a source path
      * @deprecated since 1.6.x.
      */
+    @Deprecated
     public Path createSourcespath() {
         if (sourcesPath == null) {
             sourcesPath = new Path(getProject());
@@ -201,6 +206,7 @@
      * @return the sources path
      * @deprecated since 1.6.x.
      */
+    @Deprecated
     public Path getSourcespath() {
         return sourcesPath;
     }
@@ -325,6 +331,7 @@
         /**
          * @return the enumerated values
          */
+        @Override
         public String[] getValues() {
             return formats;
         }
@@ -368,11 +375,11 @@
 
         File f = LoaderUtils.getResourceSource(getClass().getClassLoader(),
                                                resource);
-        if (f != null) {
+        if (f == null) {
+            log("Couldn\'t find " + resource, Project.MSG_DEBUG);
+        } else {
             log("Found " + f.getAbsolutePath(), Project.MSG_DEBUG);
             runtimeClasses.createPath().setLocation(f);
-        } else {
-            log("Couldn\'t find " + resource, Project.MSG_DEBUG);
         }
     }
 
@@ -381,31 +388,29 @@
      *
      * @exception BuildException if an error occurs
      */
+    @Override
     public void execute() throws BuildException {
 
         CommandlineJava commandline = new CommandlineJava();
 
         if ("text".equals(format)) {
             commandline.setClassname("jdepend.textui.JDepend");
-        } else
-            if ("xml".equals(format)) {
-                commandline.setClassname("jdepend.xmlui.JDepend");
-            }
+        } else if ("xml".equals(format)) {
+            commandline.setClassname("jdepend.xmlui.JDepend");
+        }
 
         if (jvm != null) {
             commandline.setVm(jvm);
         }
         if (getSourcespath() == null && getClassespath() == null) {
             throw new BuildException("Missing classespath required argument");
-        } else if (getClassespath() == null) {
-            String msg =
-                "sourcespath is deprecated in JDepend >= 2.5 "
-                + "- please convert to classespath";
-            log(msg);
+        }
+        if (getClassespath() == null) {
+            log("sourcespath is deprecated in JDepend >= 2.5 - please convert to classespath");
         }
 
         // execute the test and get the return code
-        int exitValue = JDependTask.ERRORS;
+        int exitValue;
         boolean wasKilled = false;
         if (!getFork()) {
             exitValue = executeInVM(commandline);
@@ -426,11 +431,10 @@
             String errorMessage = "JDepend FAILED"
                 + (wasKilled ? " - Timed out" : "");
 
-            if  (getHaltonerror()) {
+            if (getHaltonerror()) {
                 throw new BuildException(errorMessage, getLocation());
-            } else {
-                log(errorMessage, Project.MSG_ERR);
             }
+            log(errorMessage, Project.MSG_ERR);
         }
     }
 
@@ -471,15 +475,10 @@
             log("Output to be stored in " + getOutputFile().getPath());
         }
 
-
         try {
-            if (getClassespath() != null) {
-                // This is the new, better way - use classespath instead
-                // of sourcespath.  The code is currently the same - you
-                // need class files in a directory to use this or jar files.
-                String[] cP = getClassespath().list();
-                for (int i = 0; i < cP.length; i++) {
-                    File f = new File(cP[i]);
+            getWorkingPath().ifPresent(path -> {
+                for (String filepath : path.list()) {
+                    File f = new File(filepath);
                     // not necessary as JDepend would fail, but why loose
                     // some time?
                     if (!f.exists()) {
@@ -500,48 +499,17 @@
                         throw new BuildException(msg);
                     }
                 }
-
-            } else if (getSourcespath() != null) {
-
-                // This is the old way and is deprecated - classespath is
-                // the right way to do this and is above
-                String[] sP = getSourcespath().list();
-                for (int i = 0; i < sP.length; i++) {
-                    File f = new File(sP[i]);
-
-                    // not necessary as JDepend would fail, but why loose
-                    // some time?
-                    if (!f.exists() || !f.isDirectory()) {
-                        String msg = "\""
-                            + f.getPath()
-                            + "\" does not represent a valid"
-                            + " directory. JDepend would fail.";
-                        log(msg);
-                        throw new BuildException(msg);
-                    }
-                    try {
-                        jdepend.addDirectory(f.getPath());
-                    } catch (IOException e) {
-                        String msg =
-                            "JDepend Failed when adding a source directory: "
-                            + e.getMessage();
-                        log(msg);
-                        throw new BuildException(msg);
-                    }
-                }
-            }
+            });
 
             // This bit turns <exclude> child tags into patters to ignore
             String[] patterns = defaultPatterns.getExcludePatterns(getProject());
             if (patterns != null && patterns.length > 0) {
                 if (setFilter != null) {
-                    Vector v = new Vector();
-                    for (int i = 0; i < patterns.length; i++) {
-                        v.addElement(patterns[i]);
-                    }
+                    List<String> v = new ArrayList<>();
+                    Collections.addAll(v, patterns);
                     try {
-                        Object o = packageFilterC.newInstance(new Object[] {v});
-                        setFilter.invoke(jdepend, new Object[] {o});
+                        Object o = packageFilterC.newInstance(v);
+                        setFilter.invoke(jdepend, o);
                     } catch (Throwable e) {
                         log("excludes will be ignored as JDepend doesn't like me: "
                             + e.getMessage(), Project.MSG_WARN);
@@ -554,8 +522,8 @@
 
             jdepend.analyze();
             if (pw != null && pw.checkError()) {
-                throw new IOException("Encountered an error writing JDepend"
-                                      + " output");
+                throw new IOException(
+                    "Encountered an error writing JDepend output");
             }
         } catch (IOException ex) {
             throw new BuildException(ex);
@@ -566,7 +534,6 @@
         return SUCCESS;
     }
 
-
     /**
      * Execute the task by forking a new JVM. The command will block until
      * it finishes. To know if the process was destroyed or not, use the
@@ -594,8 +561,8 @@
         }
 
         if (includeRuntime) {
-            Map/*<String, String>*/ env = Execute.getEnvironmentVariables();
-            String cp = (String) env.get("CLASSPATH");
+            Map<String, String> env = Execute.getEnvironmentVariables();
+            String cp = env.get("CLASSPATH");
             if (cp != null) {
                 commandline.createClasspath(getProject()).createPath()
                     .append(new Path(getProject(), cp));
@@ -615,42 +582,20 @@
             // we have to find a cleaner way to put this output
         }
 
-        if (getSourcespath() != null) {
-            // This is deprecated - use classespath in the future
-            String[] sP = getSourcespath().list();
-            for (int i = 0; i < sP.length; i++) {
-                File f = new File(sP[i]);
+        getWorkingPath().ifPresent(path -> {
+            for (String filepath : path.list()) {
+                File f = new File(filepath);
 
                 // not necessary as JDepend would fail, but why loose
                 // some time?
                 if (!f.exists() || !f.isDirectory()) {
-                    throw new BuildException("\"" + f.getPath()
-                                             + "\" does not represent a valid"
-                                             + " directory. JDepend would"
-                                             + " fail.");
+                    throw new BuildException(
+                        "\"%s\" does not represent a valid directory. JDepend would fail.",
+                        f.getPath());
                 }
                 commandline.createArgument().setValue(f.getPath());
             }
-        }
-
-        if (getClassespath() != null) {
-            // This is the new way - use classespath - code is the
-            // same for now
-            String[] cP = getClassespath().list();
-            for (int i = 0; i < cP.length; i++) {
-                File f = new File(cP[i]);
-                // not necessary as JDepend would fail, but why loose
-                // some time?
-                if (!f.exists()) {
-                    throw new BuildException("\"" + f.getPath()
-                                             + "\" does not represent a valid"
-                                             + " file or directory. JDepend would"
-                                             + " fail.");
-                }
-                commandline.createArgument().setValue(f.getPath());
-            }
-        }
-
+        });
         Execute execute = new Execute(new LogStreamHandler(this,
             Project.MSG_INFO, Project.MSG_WARN), watchdog);
         execute.setCommandline(commandline.getCommandline());
@@ -681,4 +626,15 @@
         }
         return new ExecuteWatchdog(getTimeout().longValue());
     }
+
+    private Optional<Path> getWorkingPath() {
+        Optional<Path> result = Optional.ofNullable(getClassespath());
+        if (result.isPresent()) {
+            return result;
+        }
+        result = Optional.ofNullable(getSourcespath());
+        result.ifPresent(resources -> log("nested sourcespath is deprecated; please use classespath"));
+        return result;
+    }
+
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java b/src/main/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java
index 20e9fc5..7609c2f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java
@@ -49,8 +49,8 @@
         super();
 
         int count = data.readUnsignedShort();
-        types = new byte [ count ];
-        values = new Object [ count ];
+        types = new byte[count];
+        values = new Object[count];
         // read in all constant pool entries.
         for (int i = 1; i < count; i++) {
             byte type = data.readByte();
@@ -64,33 +64,33 @@
                 break;
 
             case INTEGER :
-                values[i] = new Integer(data.readInt());
+                values[i] = Integer.valueOf(data.readInt());
                 break;
 
             case FLOAT :
-                values[i] = new Float(data.readFloat());
+                values[i] = Float.valueOf(data.readFloat());
                 break;
 
             case LONG :
-                values[i] = new Long(data.readLong());
+                values[i] = Long.valueOf(data.readLong());
                 ++i;
                 break;
 
             case DOUBLE :
-                values[i] = new Double(data.readDouble());
+                values[i] = Double.valueOf(data.readDouble());
                 ++i;
                 break;
 
             case CLASS :
             case STRING :
-                values[i] = new Integer(data.readUnsignedShort());
+                values[i] = Integer.valueOf(data.readUnsignedShort());
                 break;
 
             case FIELDREF :
             case METHODREF :
             case INTERFACEMETHODREF :
             case NAMEANDTYPE :
-                values[i] = new Integer(data.readInt());
+                values[i] = Integer.valueOf(data.readInt());
                 break;
             default:
                 // Do nothing
@@ -133,7 +133,6 @@
         return className;
     }
 
-
 }
 
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java
index 5a2cba6..db8b3a3 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java
@@ -52,11 +52,19 @@
  */
 public class JlinkTask extends MatchingTask {
 
+    private File outfile = null;
+
+    private Path mergefiles = null;
+
+    private Path addfiles = null;
+
+    private boolean compress = false;
+
     /**
      * The output file for this run of jlink. Usually a jar or zip file.
      * @param outfile the output file
      */
-    public  void setOutfile(File outfile) {
+    public void setOutfile(File outfile) {
         this.outfile = outfile;
     }
 
@@ -65,7 +73,7 @@
      * be merged into the output.
      * @return a path to be configured
      */
-    public  Path createMergefiles() {
+    public Path createMergefiles() {
         if (this.mergefiles == null) {
             this.mergefiles = new Path(getProject());
         }
@@ -76,7 +84,7 @@
      * Sets the files to be merged into the output.
      * @param mergefiles a path
      */
-    public  void setMergefiles(Path mergefiles) {
+    public void setMergefiles(Path mergefiles) {
         if (this.mergefiles == null) {
             this.mergefiles = mergefiles;
         } else {
@@ -89,7 +97,7 @@
      * be added to the output.
      * @return a path to be configured
      */
-    public  Path createAddfiles() {
+    public Path createAddfiles() {
         if (this.addfiles == null) {
             this.addfiles = new Path(getProject());
         }
@@ -100,7 +108,7 @@
      * Sets the files to be added into the output.
      * @param addfiles a path
      */
-    public  void setAddfiles(Path addfiles) {
+    public void setAddfiles(Path addfiles) {
         if (this.addfiles == null) {
             this.addfiles = addfiles;
         } else {
@@ -112,7 +120,7 @@
      * Defines whether or not the output should be compacted.
      * @param compress a <code>boolean</code> value
      */
-    public  void setCompress(boolean compress) {
+    public void setCompress(boolean compress) {
         this.compress = compress;
     }
 
@@ -120,15 +128,16 @@
      * Does the adding and merging.
      * @throws BuildException on error
      */
-    public  void execute() throws BuildException {
+    @Override
+    public void execute() throws BuildException {
         //Be sure everything has been set.
         if (outfile == null) {
-            throw new BuildException("outfile attribute is required! "
-                + "Please set.");
+            throw new BuildException(
+                "outfile attribute is required! Please set.");
         }
         if (!haveAddFiles() && !haveMergeFiles()) {
-            throw new BuildException("addfiles or mergefiles required! "
-                + "Please set.");
+            throw new BuildException(
+                "addfiles or mergefiles required! Please set.");
         }
         log("linking:     " + outfile.getPath());
         log("compression: " + compress, Project.MSG_VERBOSE);
@@ -159,23 +168,6 @@
     }
 
     private boolean haveEntries(Path p) {
-        if (p == null) {
-            return false;
-        }
-        if (p.size() > 0) {
-            return true;
-        }
-        return false;
+        return !(p == null || p.isEmpty());
     }
-
-    private  File outfile = null;
-
-    private  Path mergefiles = null;
-
-    private  Path addfiles = null;
-
-    private  boolean compress = false;
-
 }
-
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java b/src/main/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java
index 0c143cf..0d4895c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java
@@ -24,11 +24,12 @@
 
 import java.io.BufferedInputStream;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.Enumeration;
+import java.util.List;
 import java.util.Vector;
 import java.util.zip.CRC32;
 import java.util.zip.Deflater;
@@ -37,8 +38,6 @@
 import java.util.zip.ZipFile;
 import java.util.zip.ZipOutputStream;
 
-import org.apache.tools.ant.util.FileUtils;
-
 // CheckStyle:TypeNameCheck OFF - bc
 /**
  * jlink links together multiple .jar files.
@@ -49,9 +48,9 @@
 
     private String outfile = null;
 
-    private Vector mergefiles = new Vector(VECTOR_INIT_SIZE);
+    private List<String> mergefiles = new Vector<>(VECTOR_INIT_SIZE);
 
-    private Vector addfiles = new Vector(VECTOR_INIT_SIZE);
+    private List<String> addfiles = new Vector<>(VECTOR_INIT_SIZE);
 
     private boolean compression = false;
 
@@ -71,7 +70,6 @@
         this.outfile = outfile;
     }
 
-
     /**
      * Adds a file to be merged into the output.
      * @param fileToMerge the file to merge into the output.
@@ -80,10 +78,9 @@
         if (fileToMerge == null) {
             return;
         }
-        mergefiles.addElement(fileToMerge);
+        mergefiles.add(fileToMerge);
     }
 
-
     /** Adds a file to be added into the output.
      * @param fileToAdd the file to add to the output.
      */
@@ -91,38 +88,35 @@
         if (fileToAdd == null) {
             return;
         }
-        addfiles.addElement(fileToAdd);
+        addfiles.add(fileToAdd);
     }
 
-
     /**
      * Adds several files to be merged into the output.
      * @param filesToMerge an array of files to merge into the output.
      */
-    public void addMergeFiles(String[] filesToMerge) {
+    public void addMergeFiles(String... filesToMerge) {
         if (filesToMerge == null) {
             return;
         }
-        for (int i = 0; i < filesToMerge.length; i++) {
-            addMergeFile(filesToMerge[i]);
+        for (String element : filesToMerge) {
+            addMergeFile(element);
         }
     }
 
-
     /**
-     * Adds several file to be added into the output.
+     * Adds several files to be added into the output.
      * @param filesToAdd an array of files to add to the output.
      */
-    public void addAddFiles(String[] filesToAdd) {
+    public void addAddFiles(String... filesToAdd) {
         if (filesToAdd == null) {
             return;
         }
-        for (int i = 0; i < filesToAdd.length; i++) {
-            addAddFile(filesToAdd[i]);
+        for (String element : filesToAdd) {
+            addAddFile(element);
         }
     }
 
-
     /**
      * Determines whether output will be compressed.
      * @param compress if true use compression.
@@ -131,7 +125,6 @@
         this.compression = compress;
     }
 
-
     /**
      * Performs the linking of files. Addfiles are added to the output as-is.
      * For example, a jar file is added to the output as a jar file. However,
@@ -145,48 +138,40 @@
      * @throws Exception on error.
      */
     public void link() throws Exception { //NOSONAR
-        ZipOutputStream output = new ZipOutputStream(new FileOutputStream(outfile));
+        try (ZipOutputStream output =
+            new ZipOutputStream(Files.newOutputStream(Paths.get(outfile)))) {
 
-        if (compression) {
-            output.setMethod(ZipOutputStream.DEFLATED);
-            output.setLevel(Deflater.DEFAULT_COMPRESSION);
-        } else {
-            output.setMethod(ZipOutputStream.STORED);
-        }
-
-        Enumeration merges = mergefiles.elements();
-
-        while (merges.hasMoreElements()) {
-            String path = (String) merges.nextElement();
-            File f = new File(path);
-
-            if (f.getName().endsWith(".jar") || f.getName().endsWith(".zip")) {
-                //Do the merge
-                mergeZipJarContents(output, f);
+            if (compression) {
+                output.setMethod(ZipOutputStream.DEFLATED);
+                output.setLevel(Deflater.DEFAULT_COMPRESSION);
             } else {
-                //Add this file to the addfiles Vector and add it
-                //later at the top level of the output file.
-                addAddFile(path);
+                output.setMethod(ZipOutputStream.STORED);
+            }
+            for (String path : mergefiles) {
+                File f = new File(path);
+
+                if (f.getName().endsWith(".jar")
+                    || f.getName().endsWith(".zip")) {
+                    //Do the merge
+                    mergeZipJarContents(output, f);
+                } else {
+                    //Add this file to the addfiles Vector and add it
+                    //later at the top level of the output file.
+                    addAddFile(path);
+                }
+            }
+            for (String name : addfiles) {
+                File f = new File(name);
+
+                if (f.isDirectory()) {
+                    addDirContents(output, f, f.getName() + '/', compression);
+                } else {
+                    addFile(output, f, "", compression);
+                }
             }
         }
-
-        Enumeration adds = addfiles.elements();
-
-        while (adds.hasMoreElements()) {
-            String name = (String) adds.nextElement();
-            File f = new File(name);
-
-            if (f.isDirectory()) {
-                //System.out.println("in jlink: adding directory contents of " + f.getPath());
-                addDirContents(output, f, f.getName() + '/', compression);
-            } else {
-                addFile(output, f, "", compression);
-            }
-        }
-        FileUtils.close(output);
     }
 
-
     /**
      * The command line entry point for jlink.
      * @param args an array of arguments
@@ -212,7 +197,6 @@
         }
     }
 
-
     /*
      * Actually performs the merging of f into the output.
      * f should be a zip or jar file.
@@ -222,12 +206,11 @@
         if (!f.exists()) {
             return;
         }
-        ZipFile zipf = new ZipFile(f);
-        try {
-            Enumeration entries = zipf.entries();
+        try (ZipFile zipf = new ZipFile(f)) {
+            Enumeration<? extends ZipEntry> entries = zipf.entries();
 
             while (entries.hasMoreElements()) {
-                ZipEntry inputEntry = (ZipEntry) entries.nextElement();
+                ZipEntry inputEntry = entries.nextElement();
                 //Ignore manifest entries.  They're bound to cause conflicts between
                 //files that are being merged.  User should supply their own
                 //manifest file when doing the merge.
@@ -245,35 +228,29 @@
                         //entry from another mergefile was called "com".
                         //In that case, just ignore the error and go on to the
                         //next entry.
-                        String mess = ex.getMessage();
-
-                        if (mess.indexOf("duplicate") >= 0) {
+                        if (ex.getMessage().indexOf("duplicate") >= 0) {
                             //It was the duplicate entry.
                             continue;
-                        } else {
-                            // I hate to admit it, but we don't know what happened
-                            // here.  Throw the Exception.
-                            throw ex;
                         }
+                        // I hate to admit it, but we don't know what happened
+                        // here.  Throw the Exception.
+                        throw ex;
                     }
 
-                    InputStream in = zipf.getInputStream(inputEntry);
-                    int len = buffer.length;
-                    int count = -1;
+                    try (InputStream in = zipf.getInputStream(inputEntry)) {
+                        int len = buffer.length;
+                        int count = -1;
 
-                    while ((count = in.read(buffer, 0, len)) > 0) {
-                        output.write(buffer, 0, count);
+                        while ((count = in.read(buffer, 0, len)) > 0) {
+                            output.write(buffer, 0, count);
+                        }
+                        output.closeEntry();
                     }
-                    in.close();
-                    output.closeEntry();
                 }
             }
-        } finally {
-            zipf.close();
         }
     }
 
-
     /*
      * Adds contents of a directory to the output.
      */
@@ -293,7 +270,6 @@
         }
     }
 
-
     /*
      * Gets the name of an entry in the file.  This is the real name
      * which for a class is the name of the package with the class
@@ -304,9 +280,7 @@
 
         if (!name.endsWith(".class")) {
             // see if the file is in fact a .class file, and determine its actual name.
-            InputStream input = null;
-            try {
-                input = new FileInputStream(file);
+            try (InputStream input = Files.newInputStream(file.toPath())) {
                 String className = ClassNameReader.getClassName(input);
 
                 if (className != null) {
@@ -314,13 +288,12 @@
                 }
             } catch (IOException ioe) {
                 //do nothing
-            } finally {
-                FileUtils.close(input);
             }
         }
-        System.out.println("From " + file.getPath() + " and prefix " + prefix
-                           + ", creating entry " + prefix + name);
-        return (prefix + name);
+        System.out.printf(
+            "From %1$s and prefix %2$s, creating entry %2$s%3$s%n",
+            file.getPath(), prefix, name);
+        return prefix + name;
     }
 
 
@@ -340,12 +313,9 @@
         if (!compress) {
             entry.setCrc(calcChecksum(file));
         }
-        FileInputStream input = new FileInputStream(file);
-
-        addToOutputStream(output, input, entry);
+        addToOutputStream(output, Files.newInputStream(file.toPath()), entry);
     }
 
-
     /*
      * A convenience method that several other methods might call.
      */
@@ -359,7 +329,7 @@
             return;
         }
 
-        int numBytes = -1;
+        int numBytes;
 
         while ((numBytes = input.read(buffer)) > 0) {
             output.write(buffer, 0, numBytes);
@@ -368,7 +338,6 @@
         input.close();
     }
 
-
     /*
      * A method that does the work on a given entry in a mergefile.
      * The big deal is to set the right parameters in the ZipEntry
@@ -390,11 +359,9 @@
         String name = inputEntry.getName();
 
         if (!(inputEntry.isDirectory() || name.endsWith(".class"))) {
-            try {
-                InputStream input = zip.getInputStream(zip.getEntry(name));
+            try (InputStream input = zip.getInputStream(zip.getEntry(name))) {
                 String className = ClassNameReader.getClassName(input);
 
-                input.close();
                 if (className != null) {
                     name = className.replace('.', '/') + ".class";
                 }
@@ -419,18 +386,15 @@
         return outputEntry;
     }
 
-
     /*
      * Necessary in the case where you add a entry that
      * is not compressed.
      */
     private long calcChecksum(File f) throws IOException {
-        BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
-
-        return calcChecksum(in);
+        return calcChecksum(
+            new BufferedInputStream(Files.newInputStream(f.toPath())));
     }
 
-
     /*
      * Necessary in the case where you add a entry that
      * is not compressed.
@@ -438,18 +402,15 @@
     private long calcChecksum(InputStream in) throws IOException {
         CRC32 crc = new CRC32();
         int len = buffer.length;
-        int count = -1;
-        int haveRead = 0;
+        int count;
 
         while ((count = in.read(buffer, 0, len)) > 0) {
-            haveRead += count;
             crc.update(buffer, 0, count);
         }
         in.close();
         return crc.getValue();
     }
 
-
 }
 
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/Jasper41Mangler.java b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/Jasper41Mangler.java
index 609938c..d863715 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/Jasper41Mangler.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/Jasper41Mangler.java
@@ -27,19 +27,18 @@
  */
 public class Jasper41Mangler implements JspMangler {
 
-
     /**
      * map from a jsp file to a java filename; does not do packages
      *
      * @param jspFile file
      * @return java filename
      */
+    @Override
     public String mapJspToJavaName(File jspFile) {
         String jspUri = jspFile.getAbsolutePath();
         int start = jspUri.lastIndexOf(File.separatorChar) + 1;
         int end = jspUri.length();
-        StringBuffer modifiedClassName;
-        modifiedClassName = new StringBuffer(jspUri.length() - start);
+        StringBuilder modifiedClassName = new StringBuilder(jspUri.length() - start);
         if (!Character.isJavaIdentifierStart(jspUri.charAt(start))
             || jspUri.charAt(start) == '_') {
             // If the first char is not a start of Java identifier or is _
@@ -78,7 +77,6 @@
         // CheckStyle:MagicNumber ON
     }
 
-
     /**
      * taking in the substring representing the path relative to the source dir
      * return a new string representing the destination path
@@ -86,6 +84,7 @@
      * @return null as this is not implemented.
      * @todo
      */
+    @Override
     public String mapPath(String path) {
         return null;
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java
index 4cadace..ca353b2 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java
@@ -19,8 +19,7 @@
 package org.apache.tools.ant.taskdefs.optional.jsp;
 
 import java.io.File;
-import java.util.Date;
-import java.util.Enumeration;
+import java.time.Instant;
 import java.util.Vector;
 
 import org.apache.tools.ant.AntClassLoader;
@@ -80,8 +79,8 @@
     private boolean mapped;
     private int verbose = 0;
     // CheckStyle:VisibilityModifier OFF - bc
-    protected Vector compileList = new Vector();
-    Vector javaFiles = new Vector();
+    protected Vector<String> compileList = new Vector<>();
+    Vector<File> javaFiles = new Vector<>();
 
     /**
      *  flag to control action on execution trouble
@@ -209,6 +208,7 @@
     public String getIeplugin() {
         return iepluginid;
     }
+
     /**
      * Java Plugin CLASSID for Internet Explorer
      * @param iepluginid the id to use.
@@ -272,7 +272,6 @@
         return uriroot;
     }
 
-
     /**
      * Set the classpath to be used for this compilation.
      * @param cp the path to be used.
@@ -413,7 +412,7 @@
      * get the list of files to compile
      * @return the list of files.
      */
-    public Vector getCompileList() {
+    public Vector<String> getCompileList() {
         return compileList;
     }
 
@@ -422,6 +421,7 @@
      * have changed and hand them off to a jsp compiler
      * @throws BuildException on error.
      */
+    @Override
     public void execute()
         throws BuildException {
 
@@ -439,13 +439,10 @@
 
         File dest = getActualDestDir();
 
-        AntClassLoader al = null;
-        try {
+        try (AntClassLoader al = getProject().createClassLoader(compilerClasspath)) {
             //bind to a compiler
             JspCompilerAdapter compiler =
-                JspCompilerAdapterFactory
-                .getCompiler(compilerName, this,
-                             al = getProject().createClassLoader(compilerClasspath));
+                JspCompilerAdapterFactory.getCompiler(compilerName, this, al);
 
             //if we are a webapp, hand off to the compiler, which had
             //better handle it
@@ -499,7 +496,7 @@
             log("compiling " + compileList.size() + " files",
                 Project.MSG_VERBOSE);
 
-            if (compileList.size() > 0) {
+            if (!compileList.isEmpty()) {
 
                 log("Compiling " + compileList.size() + " source file"
                     + (compileList.size() == 1 ? "" : "s")
@@ -507,16 +504,10 @@
                     + dest);
                 doCompilation(compiler);
 
+            } else if (filecount == 0) {
+                log("there were no files to compile", Project.MSG_INFO);
             } else {
-                if (filecount == 0) {
-                    log("there were no files to compile", Project.MSG_INFO);
-                } else {
-                    log("all files are up to date", Project.MSG_VERBOSE);
-                }
-            }
-        } finally {
-            if (al != null) {
-                al.cleanup();
+                log("all files are up to date", Project.MSG_VERBOSE);
             }
         }
     }
@@ -526,15 +517,11 @@
      * this is destDir or it id destDir + the package name
      */
     private File getActualDestDir() {
-        File dest = null;
         if (packageName == null) {
-            dest = destDir;
-        } else {
-            String path = destDir.getPath() + File.separatorChar
-                + packageName.replace('.', File.separatorChar);
-            dest = new File(path);
+            return destDir;
         }
-        return dest;
+        return new File(destDir.getPath() + File.separatorChar
+            + packageName.replace('.', File.separatorChar));
     }
 
     /**
@@ -549,9 +536,8 @@
         if (!compiler.execute()) {
             if (failOnError) {
                 throw new BuildException(FAIL_MSG, getLocation());
-            } else {
-                log(FAIL_MSG, Project.MSG_ERR);
             }
+            log(FAIL_MSG, Project.MSG_ERR);
         }
     }
 
@@ -573,23 +559,19 @@
     protected void scanDir(File srcDir, File dest, JspMangler mangler,
                            String[] files) {
 
-        long now = (new Date()).getTime();
+        long now = Instant.now().toEpochMilli();
 
-        for (int i = 0; i < files.length; i++) {
-            String filename = files[i];
+        for (String filename : files) {
             File srcFile = new File(srcDir, filename);
             File javaFile = mapToJavaFile(mangler, srcFile, srcDir, dest);
             if (javaFile == null) {
                 continue;
             }
-
             if (srcFile.lastModified() > now) {
                 log("Warning: file modified in the future: " + filename,
                     Project.MSG_WARN);
             }
-            boolean shouldCompile = false;
-            shouldCompile = isCompileNeeded(srcFile, javaFile);
-            if (shouldCompile) {
+            if (isCompileNeeded(srcFile, javaFile)) {
                 compileList.addElement(srcFile.getAbsolutePath());
                 javaFiles.addElement(javaFile);
             }
@@ -619,26 +601,21 @@
             log("Compiling " + srcFile.getPath()
                 + " because java file " + javaFile.getPath()
                 + " does not exist", Project.MSG_VERBOSE);
-        } else {
-            if (srcFile.lastModified() > javaFile.lastModified()) {
-                shouldCompile = true;
-                log("Compiling " + srcFile.getPath()
-                    + " because it is out of date with respect to "
-                    + javaFile.getPath(),
-                    Project.MSG_VERBOSE);
-            } else {
-                if (javaFile.length() == 0) {
-                    shouldCompile = true;
-                    log("Compiling " + srcFile.getPath()
-                        + " because java file " + javaFile.getPath()
-                        + " is empty", Project.MSG_VERBOSE);
-                }
-            }
+        } else if (srcFile.lastModified() > javaFile.lastModified()) {
+            shouldCompile = true;
+            log("Compiling " + srcFile.getPath()
+                + " because it is out of date with respect to "
+                + javaFile.getPath(),
+                Project.MSG_VERBOSE);
+        } else if (javaFile.length() == 0) {
+            shouldCompile = true;
+            log("Compiling " + srcFile.getPath()
+                + " because java file " + javaFile.getPath()
+                + " is empty", Project.MSG_VERBOSE);
         }
         return shouldCompile;
     }
 
-
     /**
      * get a filename from our jsp file.
      * @param mangler the jsp filename manager.
@@ -654,7 +631,6 @@
             return null;
         }
         String javaFileName = mangler.mapJspToJavaName(srcFile);
-        //        String srcFileDir=srcFile.getParent();
         return new File(dest, javaFileName);
     }
 
@@ -665,9 +641,7 @@
      */
     public void deleteEmptyJavaFiles() {
         if (javaFiles != null) {
-            Enumeration e = javaFiles.elements();
-            while (e.hasMoreElements()) {
-                File file = (File) e.nextElement();
+            for (File file : javaFiles) {
                 if (file.exists() && file.length() == 0) {
                     log("deleting empty output file " + file);
                     file.delete();
@@ -701,9 +675,6 @@
         public void setBaseDir(File directory) {
             this.directory = directory;
         }
-        //end inner class
     }
 
-
-    //end class
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspNameMangler.java b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspNameMangler.java
index 965f413..8fe43ab 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspNameMangler.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspNameMangler.java
@@ -58,6 +58,7 @@
      * @param jspFile file
      * @return java filename
      */
+    @Override
     public String mapJspToJavaName(File jspFile) {
         return mapJspToBaseName(jspFile) + ".java";
     }
@@ -70,20 +71,19 @@
      * @return extensionless potentially remapped name
      */
     private String mapJspToBaseName(File jspFile) {
-        String className;
-        className = stripExtension(jspFile);
+        String className = stripExtension(jspFile);
 
         // since we don't mangle extensions like the servlet does,
         // we need to check for keywords as class names
-        for (int i = 0; i < keywords.length; ++i) {
-            if (className.equals(keywords[i])) {
+        for (String keyword : keywords) {
+            if (className.equals(keyword)) {
                 className += "%";
                 break;
             }
         }
 
         // Fix for invalid characters. If you think of more add to the list.
-        StringBuffer modifiedClassName = new StringBuffer(className.length());
+        StringBuilder modifiedClassName = new StringBuilder(className.length());
         // first char is more restrictive than the rest
         char firstChar = className.charAt(0);
         if (Character.isJavaIdentifierStart(firstChar)) {
@@ -148,6 +148,7 @@
      * @param path not used
      * @return null always.
      */
+    @Override
     public String mapPath(String path) {
         return null;
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/WLJspc.java b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/WLJspc.java
index 2680847..5539749 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/WLJspc.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/WLJspc.java
@@ -19,7 +19,8 @@
 
 //apache/ant imports
 import java.io.File;
-import java.util.Date;
+import java.time.Instant;
+import java.util.List;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
@@ -98,21 +99,22 @@
     //private String compilerPath; //fully qualified name for the compiler executable
 
     private String pathToPackage = "";
-    private Vector filesToDo = new Vector();
+    private List<String> filesToDo = new Vector<>();
 
     /**
      * Run the task.
      * @throws BuildException if there is an error.
      */
+    @Override
     public void execute() throws BuildException {
         if (!destinationDirectory.isDirectory()) {
-            throw new BuildException("destination directory "
-                + destinationDirectory.getPath() + " is not valid");
+            throw new BuildException("destination directory %s is not valid",
+                destinationDirectory.getPath());
         }
 
         if (!sourceDirectory.isDirectory()) {
-            throw new BuildException("src directory "
-                + sourceDirectory.getPath() + " is not valid");
+            throw new BuildException("src directory %s is not valid",
+                sourceDirectory.getPath());
         }
 
         if (destinationPackage == null) {
@@ -120,7 +122,6 @@
                                      getLocation());
         }
 
-
         pathToPackage
             = this.destinationPackage.replace('.', File.separatorChar);
         // get all the files in the sourceDirectory
@@ -146,8 +147,6 @@
         String[] args = new String[12];
         // CheckStyle:MagicNumber ON
 
-        File jspFile = null;
-        String parents = "";
         int j = 0;
         //TODO  this array stuff is a remnant of prev trials.. gotta remove.
         args[j++] = "-d";
@@ -168,24 +167,21 @@
         this.scanDir(files);
         log("Compiling " + filesToDo.size() + " JSP files");
 
-        final int size = filesToDo.size();
-        for (int i = 0; i < size; i++) {
+        for (String filename : filesToDo) {
             //TODO
             // All this to get package according to weblogic standards
             // Can be written better... this is too hacky!
-            // Careful.. similar code in scanDir , but slightly different!!
-            String filename = (String) filesToDo.elementAt(i);
-            jspFile = new File(filename);
+            // Careful.. similar code in scanDir, but slightly different!!
+            File jspFile = new File(filename);
             args[j] = "-package";
-            parents = jspFile.getParent();
-            if ((parents != null)  && (!("").equals(parents))) {
-                parents =  this.replaceString(parents, File.separator, "_.");
-                args[j + 1] = destinationPackage + "." + "_" + parents;
-            } else {
+            String parents = jspFile.getParent();
+            if (parents == null || "".equals(parents)) {
                 args[j + 1] = destinationPackage;
+            } else {
+                parents = this.replaceString(parents, File.separator, "_.");
+                args[j + 1] = destinationPackage + "." + "_" + parents;
             }
 
-
             args[j + 2] =  sourceDirectory + File.separator + filename;
             helperTask.clearArgs();
 
@@ -202,8 +198,6 @@
         }
     }
 
-
-
     /**
      * Set the classpath to be used for this compilation.
      * @param classpath the classpath to use.
@@ -234,7 +228,6 @@
      * @param dirName the directory containing the source jsp's
      */
     public void setSrc(File dirName) {
-
         sourceDirectory = dirName;
     }
 
@@ -245,7 +238,6 @@
      * @param dirName the directory containing the source jsp's
      */
     public void setDest(File dirName) {
-
         destinationDirectory = dirName;
     }
 
@@ -255,7 +247,6 @@
      * @param packageName the package name for the classes
      */
     public void setPackage(String packageName) {
-
         destinationPackage = packageName;
     }
 
@@ -265,52 +256,48 @@
      * @param files the files to scan.
      */
     protected void scanDir(String[] files) {
-
-        long now = (new Date()).getTime();
-        File jspFile = null;
-        String parents = null;
-        String pack = "";
-        for (int i = 0; i < files.length; i++) {
-            File srcFile = new File(this.sourceDirectory, files[i]);
+        long now = Instant.now().toEpochMilli();
+        for (String file : files) {
+            File srcFile = new File(this.sourceDirectory, file);
             //TODO
             // All this to convert source to destination directory according
             // to weblogic standards Can be written better... this is too hacky!
-            jspFile = new File(files[i]);
-            parents = jspFile.getParent();
+            File jspFile = new File(file);
+            String parents = jspFile.getParent();
 
-            if ((parents != null)  && (!("").equals(parents))) {
+            String pack;
+            if (parents == null || "".equals(parents)) {
+                pack = pathToPackage;
+            } else {
                 parents =  this.replaceString(parents, File.separator, "_/");
                 pack = pathToPackage + File.separator + "_" + parents;
-            } else {
-                pack = pathToPackage;
             }
 
             String filePath = pack + File.separator + "_";
-            int startingIndex = files[i].lastIndexOf(File.separator) != -1
-                    ? files[i].lastIndexOf(File.separator) + 1 : 0;
-            int endingIndex = files[i].indexOf(".jsp");
+            int startingIndex = file.lastIndexOf(File.separator) != -1
+                    ? file.lastIndexOf(File.separator) + 1 : 0;
+            int endingIndex = file.indexOf(".jsp");
             if (endingIndex == -1) {
-                log("Skipping " + files[i] + ". Not a JSP",
+                log("Skipping " + file + ". Not a JSP",
                     Project.MSG_VERBOSE);
                 continue;
             }
 
-            filePath += files[i].substring(startingIndex, endingIndex);
+            filePath += file.substring(startingIndex, endingIndex);
             filePath += ".class";
             File classFile = new File(this.destinationDirectory, filePath);
 
             if (srcFile.lastModified() > now) {
                 log("Warning: file modified in the future: "
-                    + files[i], Project.MSG_WARN);
+                    + file, Project.MSG_WARN);
             }
             if (srcFile.lastModified() > classFile.lastModified()) {
-                filesToDo.addElement(files[i]);
-                log("Recompiling File " + files[i], Project.MSG_VERBOSE);
+                filesToDo.add(file);
+                log("Recompiling File " + file, Project.MSG_VERBOSE);
             }
         }
     }
 
-
     /**
      * Replace occurrences of a string with a replacement string.
      * @param inpString the string to convert.
@@ -321,9 +308,8 @@
     protected String replaceString(String inpString, String escapeChars,
                                    String replaceChars) {
         String localString = "";
-        int numTokens = 0;
         StringTokenizer st = new StringTokenizer(inpString, escapeChars, true);
-        numTokens = st.countTokens();
+        int numTokens = st.countTokens();
         for (int i = 0; i < numTokens; i++) {
             String test = st.nextToken();
             test = (test.equals(escapeChars) ? replaceChars : test);
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/DefaultJspCompilerAdapter.java b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/DefaultJspCompilerAdapter.java
index 59a9b2c..5814597 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/DefaultJspCompilerAdapter.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/DefaultJspCompilerAdapter.java
@@ -19,8 +19,8 @@
 package org.apache.tools.ant.taskdefs.optional.jsp.compilers;
 
 import java.io.File;
-import java.util.Enumeration;
 import java.util.Vector;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.taskdefs.optional.jsp.JspC;
@@ -35,7 +35,7 @@
 public abstract class DefaultJspCompilerAdapter
     implements JspCompilerAdapter {
 
-    private static String lSep = System.getProperty("line.separator");
+    private static String lSep = System.lineSeparator();
 
     /**
      * Logs the compilation parameters, adds the files to compile and logs the
@@ -45,27 +45,18 @@
      * @param cmd the command line used
      */
     protected void logAndAddFilesToCompile(JspC jspc,
-                                           Vector compileList,
+                                           Vector<String> compileList,
                                            CommandlineJava cmd) {
         jspc.log("Compilation " + cmd.describeJavaCommand(),
                  Project.MSG_VERBOSE);
 
-        StringBuffer niceSourceList = new StringBuffer("File");
-        if (compileList.size() != 1) {
-            niceSourceList.append("s");
-        }
-        niceSourceList.append(" to be compiled:");
-
-        niceSourceList.append(lSep);
-
-        Enumeration e = compileList.elements();
-        while (e.hasMoreElements()) {
-            String arg = (String) e.nextElement();
-            cmd.createArgument().setValue(arg);
-            niceSourceList.append("    ");
-            niceSourceList.append(arg);
-            niceSourceList.append(lSep);
-        }
+        StringBuilder niceSourceList =
+            new StringBuilder(compileList.size() == 1 ? "File" : "Files")
+                .append(" to be compiled:").append(lSep)
+                .append(compileList.stream()
+                    .peek(arg -> cmd.createArgument().setValue(arg))
+                    .map(arg -> "    " + arg)
+                    .collect(Collectors.joining(lSep)));
 
         jspc.log(niceSourceList.toString(), Project.MSG_VERBOSE);
     }
@@ -83,6 +74,7 @@
      * set the owner
      * @param owner the owner JspC compiler
      */
+    @Override
     public void setJspc(JspC owner) {
         this.owner = owner;
     }
@@ -94,7 +86,6 @@
         return owner;
     }
 
-
     /**
      * add a single argument to the argument list, if the value aint null
      * @param cmd the command line
@@ -138,6 +129,7 @@
      * @return true if the compiler wants to do its own
      * depends
      */
+    @Override
     public boolean implementsOwnDependencyChecking() {
         return false;
     }
@@ -150,4 +142,3 @@
         return getJspc().getProject();
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JasperC.java b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JasperC.java
index f0becac..46644dd 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JasperC.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JasperC.java
@@ -59,6 +59,7 @@
      * @return true if successful
      * @throws BuildException on error
      */
+    @Override
     public boolean execute()
         throws BuildException {
         getJspc().log("Using jasper compiler", Project.MSG_VERBOSE);
@@ -80,9 +81,8 @@
             java.setDir(getProject().getBaseDir());
             java.setClassname("org.apache.jasper.JspC");
             //this is really irritating; we need a way to set stuff
-            String []args = cmd.getJavaCommand().getArguments();
-            for (int i = 0; i < args.length; i++) {
-                java.createArg().setValue(args[i]);
+            for (String arg : cmd.getJavaCommand().getArguments()) {
+                java.createArg().setValue(arg);
             }
             java.setFailonerror(getJspc().getFailonerror());
             //we are forking here to be sure that if JspC calls
@@ -94,17 +94,14 @@
         } catch (Exception ex) {
             if (ex instanceof BuildException) {
                 throw (BuildException) ex;
-            } else {
-                throw new BuildException("Error running jsp compiler: ",
-                                         ex, getJspc().getLocation());
             }
+            throw new BuildException("Error running jsp compiler: ",
+                                         ex, getJspc().getLocation());
         } finally {
             getJspc().deleteEmptyJavaFiles();
         }
     }
 
-
-
     /**
      * build up a command line
      * @return a command line for jasper
@@ -144,7 +141,7 @@
     /**
      * @return an instance of the mangler this compiler uses
      */
-
+    @Override
     public JspMangler createMangler() {
         return mangler;
     }
@@ -157,26 +154,19 @@
         if (p == null) {
             p = new Path(getProject());
             return p.concatSystemClasspath("only");
-        } else {
-            return p.concatSystemClasspath("ignore");
         }
+        return p.concatSystemClasspath("ignore");
     }
 
     /**
      * @since Ant 1.6.2
      */
     private boolean isTomcat5x() {
-        AntClassLoader l = null;
-        try {
-            l = getProject().createClassLoader(getClasspath());
+        try (AntClassLoader l = getProject().createClassLoader(getClasspath())) {
             l.loadClass("org.apache.jasper.tagplugins.jstl.If");
             return true;
         } catch (ClassNotFoundException e) {
             return false;
-        } finally {
-            if (l != null) {
-                l.cleanup();
-            }
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapterFactory.java b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapterFactory.java
index 2876ba0..a172340 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapterFactory.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapterFactory.java
@@ -80,11 +80,11 @@
                                                  AntClassLoader loader)
         throws BuildException {
 
-        if (compilerType.equalsIgnoreCase("jasper")) {
+        if ("jasper".equalsIgnoreCase(compilerType)) {
             //tomcat4.0 gets the old mangler
             return new JasperC(new JspNameMangler());
         }
-        if (compilerType.equalsIgnoreCase("jasper41")) {
+        if ("jasper41".equalsIgnoreCase(compilerType)) {
             //tomcat4.1 gets the new one
             return new JasperC(new Jasper41Mangler());
         }
@@ -104,9 +104,8 @@
                                                        AntClassLoader classloader)
         throws BuildException {
         try {
-            Class c = classloader.findClass(className);
-            Object o = c.newInstance();
-            return (JspCompilerAdapter) o;
+            Class<? extends JspCompilerAdapter> c = classloader.findClass(className).asSubclass(JspCompilerAdapter.class);
+            return c.newInstance();
         } catch (ClassNotFoundException cnfe) {
             throw new BuildException(className + " can\'t be found.", cnfe);
         } catch (ClassCastException cce) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/AggregateTransformer.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/AggregateTransformer.java
index 2c1b13d..84afe3c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/AggregateTransformer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/AggregateTransformer.java
@@ -18,15 +18,11 @@
 package org.apache.tools.ant.taskdefs.optional.junit;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Vector;
-
+import java.nio.file.Files;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.transform.TransformerFactory;
@@ -75,12 +71,27 @@
          * list authorized values.
          * @return authorized values.
          */
+        @Override
         public String[] getValues() {
             return new String[]{FRAMES, NOFRAMES};
         }
     }
 
+    private static final String JDK_INTERNAL_FACTORY =
+            "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl";
+
     // CheckStyle:VisibilityModifier OFF - bc
+    /** XML Parser factory */
+    private static DocumentBuilderFactory privateDBFactory;
+
+    /** XML Parser factory accessible to subclasses */
+    protected static DocumentBuilderFactory dbfactory;
+
+    static {
+       privateDBFactory = DocumentBuilderFactory.newInstance();
+       dbfactory = privateDBFactory;
+    }
+
     /** Task */
     protected Task task;
 
@@ -120,16 +131,6 @@
     /** the format to use for the report. Must be <tt>FRAMES</tt> or <tt>NOFRAMES</tt> */
     protected String format = FRAMES;
 
-    /** XML Parser factory */
-    private static DocumentBuilderFactory privateDBFactory;
-
-    /** XML Parser factory accessible to subclasses */
-    protected static DocumentBuilderFactory dbfactory;
-
-    static {
-       privateDBFactory = DocumentBuilderFactory.newInstance();
-       dbfactory = privateDBFactory;
-    }
     // CheckStyle:VisibilityModifier ON
 
     /**
@@ -176,12 +177,9 @@
     protected void setXmlfile(File xmlfile) throws BuildException {
         try {
             DocumentBuilder builder = privateDBFactory.newDocumentBuilder();
-            InputStream in = new FileInputStream(xmlfile);
-            try {
+            try (InputStream in = Files.newInputStream(xmlfile.toPath())) {
                 Document doc = builder.parse(in);
                 setXmlDocument(doc);
-            } finally {
-                in.close();
             }
         } catch (Exception e) {
             throw new BuildException("Error while parsing document: " + xmlfile, e);
@@ -260,8 +258,8 @@
 
         // acrobatic cast.
         xsltTask.setIn(((XMLResultAggregator) task).getDestinationFile());
-        File outputFile = null;
-        if (format.equals(FRAMES)) {
+        File outputFile;
+        if (FRAMES.equals(format)) {
             String tempFileProperty = getClass().getName() + String.valueOf(counter++); //NOSONAR
             File tmp = FILE_UTILS.resolveFile(project.getBaseDir(), project
                     .getProperty("java.io.tmpdir"));
@@ -355,8 +353,6 @@
         return JAXPUtils.getSystemId(file);
     }
 
-    private static final String JDK_INTERNAL_FACTORY = "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl";
-
     /**
      * If we end up using the JDK's own TraX factory on Java 9+, then
      * set the features and attributes necessary to allow redirect
@@ -375,8 +371,9 @@
         }
         if (JDK_INTERNAL_FACTORY.equals(factoryName)
             && JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_9)) {
-            factory.addFeature(new XSLTProcess.Factory.Feature("http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions",
-                                                               true));
+            factory.addFeature(new XSLTProcess.Factory.Feature(
+                "http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions",
+                true));
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/BaseTest.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/BaseTest.java
index 24e6c07..6e120c4 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/BaseTest.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/BaseTest.java
@@ -33,7 +33,7 @@
     protected boolean fork = false;
     protected String ifProperty = null;
     protected String unlessProperty = null;
-    protected Vector formatters = new Vector();
+    protected Vector<FormatterElement> formatters = new Vector<>();
     /** destination directory */
     protected File destDir = null;
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/BatchTest.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/BatchTest.java
index 0807024..11271bf 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/BatchTest.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/BatchTest.java
@@ -22,6 +22,7 @@
 import java.io.File;
 import java.util.Enumeration;
 import java.util.Vector;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.types.FileSet;
@@ -79,7 +80,6 @@
         }
     }
 
-
     /**
      * Add a new ResourceCollection instance to this
      * batchtest. Whatever the collection is, only names that are
@@ -98,7 +98,7 @@
      * @return  an enumeration of all elements of this batchtest that are
      * a <tt>JUnitTest</tt> instance.
      */
-    public Enumeration elements() {
+    public Enumeration<JUnitTest> elements() {
         JUnitTest[] tests = createAllJUnitTest();
         return Enumerations.fromArray(tests);
     }
@@ -109,7 +109,7 @@
      * @param v the vector to which should be added all individual tests of this
      * batch test.
      */
-    void addTestsTo(Vector v) {
+    void addTestsTo(Vector<? super JUnitTest> v) {
         JUnitTest[] tests = createAllJUnitTest();
         v.ensureCapacity(v.size() + tests.length);
         for (int i = 0; i < tests.length; i++) {
@@ -123,13 +123,8 @@
      * @return the array of all <tt>JUnitTest</tt>s that belongs to this batch.
      */
     private JUnitTest[] createAllJUnitTest() {
-        String[] filenames = getFilenames();
-        JUnitTest[] tests = new JUnitTest[filenames.length];
-        for (int i = 0; i < tests.length; i++) {
-            String classname = javaToClass(filenames[i]);
-            tests[i] = createJUnitTest(classname);
-        }
-        return tests;
+        return Stream.of(getFilenames()).map(BatchTest::javaToClass)
+            .map(this::createJUnitTest).toArray(JUnitTest[]::new);
     }
 
     /**
@@ -143,21 +138,11 @@
      * For the class <tt>org/apache/Whatever.class</tt> it will return <tt>org/apache/Whatever</tt>.
      */
     private String[] getFilenames() {
-        Vector v = new Vector();
-        for (Resource r : resources) {
-            if (r.isExists()) {
-                String pathname = r.getName();
-                if (pathname.endsWith(".java")) {
-                    v.addElement(pathname.substring(0, pathname.length() - ".java".length()));
-                } else if (pathname.endsWith(".class")) {
-                    v.addElement(pathname.substring(0, pathname.length() - ".class".length()));
-                }
-            }
-        }
-
-        String[] files = new String[v.size()];
-        v.copyInto(files);
-        return files;
+        return resources.stream().filter(Resource::isExists)
+            .map(Resource::getName)
+            .filter(name -> name.endsWith(".java") || name.endsWith(".class"))
+            .map(name -> name.substring(0, name.lastIndexOf('.')))
+            .toArray(String[]::new);
     }
 
     /**
@@ -192,10 +177,7 @@
         test.setFailureProperty(failureProperty);
         test.setErrorProperty(errorProperty);
         test.setSkipNonTests(isSkipNonTests());
-        Enumeration list = this.formatters.elements();
-        while (list.hasMoreElements()) {
-            test.addFormatter((FormatterElement) list.nextElement());
-        }
+        this.formatters.forEach(test::addFormatter);
         return test;
     }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java
index 8d106b2..4f00180 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java
@@ -89,6 +89,7 @@
      * Sets the stream the formatter is supposed to write its results to.
      * @param out the output stream to write to
      */
+    @Override
     public void setOutput(OutputStream out) {
         this.out = out;
         output = new BufferedWriter(new java.io.OutputStreamWriter(out));
@@ -98,6 +99,7 @@
      * @see JUnitResultFormatter#setSystemOutput(String)
      * {@inheritDoc}.
      */
+    @Override
     public void setSystemOutput(String out) {
         systemOutput = out;
     }
@@ -106,6 +108,7 @@
      * @see JUnitResultFormatter#setSystemError(String)
      * {@inheritDoc}.
      */
+    @Override
     public void setSystemError(String err) {
         systemError = err;
     }
@@ -115,15 +118,15 @@
      * The whole testsuite started.
      * @param suite the test suite
      */
+    @Override
     public void startTestSuite(JUnitTest suite) {
         if (output == null) {
             return; // Quick return - no output do nothing.
         }
-        StringBuffer sb = new StringBuffer("Testsuite: ");
-        sb.append(suite.getName());
-        sb.append(StringUtils.LINE_SEP);
         try {
-            output.write(sb.toString());
+            output
+                .write(new StringBuilder("Testsuite: ").append(suite.getName())
+                    .append(StringUtils.LINE_SEP).toString());
             output.flush();
         } catch (IOException ex) {
             throw new BuildException(ex);
@@ -134,8 +137,9 @@
      * The whole testsuite ended.
      * @param suite the test suite
      */
+    @Override
     public void endTestSuite(JUnitTest suite) {
-        StringBuffer sb = new StringBuffer("Tests run: ");
+        StringBuilder sb = new StringBuilder("Tests run: ");
         sb.append(suite.runCount());
         sb.append(", Failures: ");
         sb.append(suite.failureCount());
@@ -190,6 +194,7 @@
      * A test started.
      * @param test a test
      */
+    @Override
     public void startTest(Test test) {
     }
 
@@ -197,6 +202,7 @@
      * A test ended.
      * @param test a test
      */
+    @Override
     public void endTest(Test test) {
     }
 
@@ -218,6 +224,7 @@
      * @param test a test
      * @param t    the assertion failed by the test
      */
+    @Override
     public void addFailure(Test test, AssertionFailedError t) {
         addFailure(test, (Throwable) t);
     }
@@ -227,6 +234,7 @@
      * @param test  a test
      * @param error the error thrown by the test
      */
+    @Override
     public void addError(Test test, Throwable error) {
         formatError("\tCaused an ERROR", test, error);
     }
@@ -239,9 +247,8 @@
     protected String formatTest(Test test) {
         if (test == null) {
             return "Null Test: ";
-        } else {
-            return "Testcase: " + test.toString() + ":";
         }
+        return "Testcase: " + test.toString() + ":";
     }
 
     /**
@@ -271,6 +278,7 @@
     }
 
 
+    @Override
     public void testIgnored(Test test) {
         formatSkip(test, JUnitVersionHelper.getIgnoreMessage(test));
     }
@@ -294,6 +302,7 @@
 
     }
 
+    @Override
     public void testAssumptionFailure(Test test, Throwable cause) {
         formatSkip(test, cause.getMessage());
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java
index 8ad40dd..5b04c37 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java
@@ -34,7 +34,7 @@
  *
  */
 public class CustomJUnit4TestAdapterCache extends JUnit4TestAdapterCache {
-
+    private static final long serialVersionUID = 1L;
     private static final CustomJUnit4TestAdapterCache INSTANCE = new CustomJUnit4TestAdapterCache();
 
     public static CustomJUnit4TestAdapterCache getInstance() {
@@ -45,6 +45,7 @@
         super();
     }
 
+    @Override
     public RunNotifier getNotifier(final TestResult result, final JUnit4TestAdapter adapter) {
         return getNotifier(result);
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/DOMUtil.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/DOMUtil.java
index cb1939e..cb9ab81 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/DOMUtil.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/DOMUtil.java
@@ -86,13 +86,14 @@
     }
 
     /** custom implementation of a nodelist */
-    public static class NodeListImpl extends Vector implements NodeList {
+    public static class NodeListImpl extends Vector<Node> implements NodeList {
         private static final long serialVersionUID = 3175749150080946423L;
 
         /**
          * Get the number of nodes in the list.
          * @return the length of the list.
          */
+        @Override
         public int getLength() {
             return size();
         }
@@ -101,9 +102,10 @@
          * @param i the index of the node to get.
          * @return the node if the index is in bounds, null otherwise.
          */
+        @Override
         public Node item(int i) {
             try {
-                return (Node) elementAt(i);
+                return elementAt(i);
             } catch (ArrayIndexOutOfBoundsException e) {
                 return null; // conforming to NodeList interface
             }
@@ -164,9 +166,9 @@
      * @return  the cloned node that is appended to <tt>parent</tt>
      */
     public static Node importNode(Node parent, Node child) {
-        Node copy = null;
         final Document doc = parent.getOwnerDocument();
 
+        Node copy;
         switch (child.getNodeType()) {
         case Node.CDATA_SECTION_NODE:
             copy = doc.createCDATASection(((CDATASection) child).getData());
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/Enumerations.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/Enumerations.java
index 327547e..d965e4c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/Enumerations.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/Enumerations.java
@@ -17,6 +17,8 @@
  */
 package org.apache.tools.ant.taskdefs.optional.junit;
 
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.NoSuchElementException;
 
@@ -28,78 +30,35 @@
  */
 public final class Enumerations {
 
-        private Enumerations() {
-        }
+    private Enumerations() {
+    }
 
-        /**
-         * creates an enumeration from an array of objects.
-         * @param       array   the array of object to enumerate.
-         * @return the enumeration over the array of objects.
-         */
-        public static Enumeration fromArray(Object[] array) {
-                return new ArrayEnumeration(array);
-        }
+    /**
+     * creates an enumeration from an array of objects.
+     * @param <T> object type
+     * @param array the array of object to enumerate.
+     * @return the enumeration over the array of objects.
+     */
+    @SafeVarargs
+    public static <T> Enumeration<T> fromArray(T... array) {
+        return Collections.enumeration(Arrays.asList(array));
+    }
 
-        /**
-        * creates an enumeration from an array of enumeration. The created enumeration
-        * will sequentially enumerate over all elements of each enumeration and skip
-        * <tt>null</tt> enumeration elements in the array.
-        * @param        enums   the array of enumerations.
-        * @return the enumeration over the array of enumerations.
-         */
-        public static Enumeration fromCompound(Enumeration[] enums) {
-                return new CompoundEnumeration(enums);
-        }
+    /**
+     * creates an enumeration from an array of enumeration. The created enumeration
+     * will sequentially enumerate over all elements of each enumeration and skip
+     * <tt>null</tt> enumeration elements in the array.
+     * @param <T> object type
+     * @param enums the array of enumerations.
+     * @return the enumeration over the array of enumerations.
+     */
+    @SafeVarargs
+    public static <T> Enumeration<T> fromCompound(Enumeration<? extends T>... enums) {
+        return new CompoundEnumeration<>(enums);
+    }
 
 }
 
-
-/**
- * Convenient enumeration over an array of objects.
- */
-class ArrayEnumeration implements Enumeration {
-
-        /** object array */
-        private Object[] array;
-
-        /** current index */
-        private int pos;
-
-        /**
-         * Initialize a new enumeration that wraps an array.
-         * @param       array   the array of object to enumerate.
-         */
-        public ArrayEnumeration(Object[] array) {
-                this.array = array;
-                this.pos = 0;
-        }
-        /**
-         * Tests if this enumeration contains more elements.
-         *
-         * @return  <code>true</code> if and only if this enumeration object
-         *           contains at least one more element to provide;
-         *          <code>false</code> otherwise.
-         */
-        public boolean hasMoreElements() {
-                return (pos < array.length);
-        }
-
-        /**
-         * Returns the next element of this enumeration if this enumeration
-         * object has at least one more element to provide.
-         *
-         * @return     the next element of this enumeration.
-         * @throws  NoSuchElementException  if no more elements exist.
-         */
-        public Object nextElement() throws NoSuchElementException {
-                if (hasMoreElements()) {
-                        Object o = array[pos];
-                        pos++;
-                        return o;
-                }
-                throw new NoSuchElementException();
-        }
-}
 /**
  * Convenient enumeration over an array of enumeration. For example:
  * <pre>
@@ -130,48 +89,49 @@
  * }
  * </pre>
  */
- class CompoundEnumeration implements Enumeration {
+ class CompoundEnumeration<T> implements Enumeration<T> {
 
-        /** enumeration array */
-        private Enumeration[] enumArray;
+    /** enumeration array */
+    private Enumeration<? extends T>[] enumArray;
 
-        /** index in the enums array */
-        private int index = 0;
+    /** index in the enums array */
+    private int index = 0;
 
-    public CompoundEnumeration(Enumeration[] enumarray) {
-                this.enumArray = enumarray;
+    @SafeVarargs
+    public CompoundEnumeration(Enumeration<? extends T>... enumarray) {
+        this.enumArray = enumarray;
     }
 
-        /**
-         * Tests if this enumeration contains more elements.
-         *
-         * @return  <code>true</code> if and only if this enumeration object
-         *           contains at least one more element to provide;
-         *          <code>false</code> otherwise.
-         */
+    /**
+     * Tests if this enumeration contains more elements.
+     *
+     * @return  <code>true</code> if and only if this enumeration object
+     *           contains at least one more element to provide;
+     *          <code>false</code> otherwise.
+     */
+    @Override
     public boolean hasMoreElements() {
-                while (index < enumArray.length) {
-                        if (enumArray[index] != null && enumArray[index].hasMoreElements()) {
-                                return true;
-                        }
-                        index++;
-                }
-                return false;
+        while (index < enumArray.length) {
+            if (enumArray[index] != null && enumArray[index].hasMoreElements()) {
+                    return true;
+            }
+            index++;
+        }
+        return false;
     }
 
-        /**
-         * Returns the next element of this enumeration if this enumeration
-         * object has at least one more element to provide.
-         *
-         * @return     the next element of this enumeration.
-         * @throws  NoSuchElementException  if no more elements exist.
-         */
-    public Object nextElement() throws NoSuchElementException {
-                if (hasMoreElements()) {
-                        return enumArray[index].nextElement();
-                }
-                throw new NoSuchElementException();
+    /**
+     * Returns the next element of this enumeration if this enumeration
+     * object has at least one more element to provide.
+     *
+     * @return     the next element of this enumeration.
+     * @throws  NoSuchElementException  if no more elements exist.
+     */
+    @Override
+    public T nextElement() throws NoSuchElementException {
+        if (hasMoreElements()) {
+            return enumArray[index].nextElement();
+        }
+        throw new NoSuchElementException();
     }
 }
-
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
index e7ffa67..254dda5 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
@@ -23,12 +23,11 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.text.SimpleDateFormat;
+import java.util.Comparator;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.SortedSet;
 import java.util.TreeSet;
-import java.util.Vector;
-
 import junit.framework.AssertionFailedError;
 import junit.framework.Test;
 
@@ -89,7 +88,7 @@
     private static final String LOG_PREFIX = "    [junit]";
 
     /** Class names of failed tests without duplicates. */
-    private static SortedSet/*<TestInfos>*/ failedTests = new TreeSet();
+    private static SortedSet<TestInfos> failedTests = new TreeSet<>();
 
     /** A writer for writing the generated source to. */
     private BufferedWriter writer;
@@ -146,20 +145,13 @@
      * @param project
      *            project reference
      */
+    @Override
     public void setProject(Project project) {
         // store project reference for logging
         super.setProject(project);
         // check if already registered
-        boolean alreadyRegistered = false;
-        Vector allListeners = project.getBuildListeners();
-        final int size = allListeners.size();
-        for (int i = 0; i < size; i++) {
-            Object listener = allListeners.get(i);
-            if (listener instanceof FailureRecorder) {
-                alreadyRegistered = true;
-                break;
-            }
-        }
+        boolean alreadyRegistered = project.getBuildListeners().stream()
+            .anyMatch(FailureRecorder.class::isInstance);
         // register if needed
         if (!alreadyRegistered) {
             verbose("Register FailureRecorder (@" + this.hashCode() + ") as BuildListener");
@@ -173,6 +165,7 @@
      * Not used
      * {@inheritDoc}
      */
+    @Override
     public void endTestSuite(JUnitTest suite) throws BuildException {
     }
 
@@ -182,6 +175,7 @@
      * @param throwable the reason it erred.
      * @see junit.framework.TestListener#addError(junit.framework.Test, java.lang.Throwable)
      */
+    @Override
     public void addError(Test test, Throwable throwable) {
         failedTests.add(new TestInfos(test));
     }
@@ -194,6 +188,7 @@
      * @see junit.framework.TestListener#addFailure(junit.framework.Test, junit.framework.AssertionFailedError)
      */
     // CheckStyle:LineLengthCheck ON
+    @Override
     public void addFailure(Test test, AssertionFailedError error) {
         failedTests.add(new TestInfos(test));
     }
@@ -202,6 +197,7 @@
      * Not used
      * {@inheritDoc}
      */
+    @Override
     public void setOutput(OutputStream out) {
         // unused, close output file so it can be deleted before the VM exits
         if (out != System.out) {
@@ -213,6 +209,7 @@
      * Not used
      * {@inheritDoc}
      */
+    @Override
     public void setSystemError(String err) {
     }
 
@@ -220,6 +217,7 @@
      * Not used
      * {@inheritDoc}
      */
+    @Override
     public void setSystemOutput(String out) {
     }
 
@@ -227,6 +225,7 @@
      * Not used
      * {@inheritDoc}
      */
+    @Override
     public void startTestSuite(JUnitTest suite) throws BuildException {
     }
 
@@ -234,6 +233,7 @@
      * Not used
      * {@inheritDoc}
      */
+    @Override
     public void endTest(Test test) {
     }
 
@@ -241,6 +241,7 @@
      * Not used
      * {@inheritDoc}
      */
+    @Override
     public void startTest(Test test) {
     }
 
@@ -248,7 +249,7 @@
 
     private void writeJavaClass() {
         try {
-            File sourceFile = new File((getLocationName() + ".java"));
+            File sourceFile = new File(getLocationName() + ".java");
             verbose("Write collector class to '" + sourceFile.getAbsolutePath() + "'");
 
             if (sourceFile.exists() && !sourceFile.delete()) {
@@ -299,8 +300,8 @@
         writer.newLine();
         writer.write("        TestSuite suite = new TestSuite();");
         writer.newLine();
-        for (Iterator iter = failedTests.iterator(); iter.hasNext();) {
-            TestInfos testInfos = (TestInfos) iter.next();
+        for (Iterator<TestInfos> iter = failedTests.iterator(); iter.hasNext();) {
+            TestInfos testInfos = iter.next();
             writer.write("        suite.addTest(");
             writer.write(String.valueOf(testInfos));
             writer.write(");");
@@ -323,6 +324,7 @@
      * Logging facade in INFO-mode.
      * @param message Log-message
      */
+    @Override
     public void log(String message) {
         getProject().log(LOG_PREFIX + " " + message, Project.MSG_INFO);
     }
@@ -338,7 +340,7 @@
     /**
      * TestInfos holds information about a given test for later use.
      */
-    public static class TestInfos implements Comparable {
+    public static class TestInfos implements Comparable<TestInfos> {
 
         /** The class name of the test. */
         private final String className;
@@ -363,6 +365,7 @@
          * @see java.lang.Object#toString()
          * @see FailureRecorder#createSuiteMethod()
          */
+        @Override
         public String toString() {
             return "new " + className + "(\"" + methodName + "\")";
         }
@@ -374,17 +377,18 @@
          * @see java.lang.Comparable#compareTo
          * @see SortedSet#comparator()
          */
-        public int compareTo(Object other) {
-            if (other instanceof TestInfos) {
-                TestInfos otherInfos = (TestInfos) other;
-                return toString().compareTo(otherInfos.toString());
-            } else {
-                return -1;
-            }
+        @Override
+        public int compareTo(TestInfos other) {
+            return Comparator.comparing(Object::toString).compare(this, other);
         }
+
+        @Override
         public boolean equals(Object obj) {
-            return obj instanceof TestInfos && toString().equals(obj.toString());
+            return obj == this || obj instanceof TestInfos
+                && toString().equals(obj.toString());
         }
+
+        @Override
         public int hashCode() {
             return toString().hashCode();
         }
@@ -396,6 +400,7 @@
      * Not used
      * {@inheritDoc}
      */
+    @Override
     public void buildFinished(BuildEvent event) {
     }
 
@@ -403,6 +408,7 @@
      * Not used
      * {@inheritDoc}
      */
+    @Override
     public void buildStarted(BuildEvent event) {
     }
 
@@ -410,6 +416,7 @@
      * Not used
      * {@inheritDoc}
      */
+    @Override
     public void messageLogged(BuildEvent event) {
     }
 
@@ -417,6 +424,7 @@
      * Not used
      * {@inheritDoc}
      */
+    @Override
     public void targetFinished(BuildEvent event) {
     }
 
@@ -424,6 +432,7 @@
      * Not used
      * {@inheritDoc}
      */
+    @Override
     public void targetStarted(BuildEvent event) {
     }
 
@@ -433,6 +442,7 @@
      * @param event  not used
      * @see org.apache.tools.ant.BuildListener#taskFinished(org.apache.tools.ant.BuildEvent)
      */
+    @Override
     public void taskFinished(BuildEvent event) {
         if (!failedTests.isEmpty()) {
             writeJavaClass();
@@ -443,6 +453,7 @@
      * Not used
      * {@inheritDoc}
      */
+    @Override
     public void taskStarted(BuildEvent event) {
     }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
index 5b31e7f..226304c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
@@ -20,17 +20,18 @@
 
 import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.nio.file.Files;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.PropertyHelper;
 import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.optional.junit.JUnitTaskMirror.JUnitResultFormatterMirror;
 import org.apache.tools.ant.types.EnumeratedAttribute;
 import org.apache.tools.ant.util.KeepAliveOutputStream;
 
@@ -59,6 +60,18 @@
  * @see JUnitResultFormatter
  */
 public class FormatterElement {
+    /** xml formatter class */
+    public static final String XML_FORMATTER_CLASS_NAME =
+        "org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter";
+    /** brief formatter class */
+    public static final String BRIEF_FORMATTER_CLASS_NAME =
+        "org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter";
+    /** plain formatter class */
+    public static final String PLAIN_FORMATTER_CLASS_NAME =
+        "org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter";
+    /** failure recorder class */
+    public static final String FAILURE_RECORDER_CLASS_NAME =
+        "org.apache.tools.ant.taskdefs.optional.junit.FailureRecorder";
 
     private String classname;
     private String extension;
@@ -74,19 +87,6 @@
      */
     private Project project;
 
-    /** xml formatter class */
-    public static final String XML_FORMATTER_CLASS_NAME =
-        "org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter";
-    /** brief formatter class */
-    public static final String BRIEF_FORMATTER_CLASS_NAME =
-        "org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter";
-    /** plain formatter class */
-    public static final String PLAIN_FORMATTER_CLASS_NAME =
-        "org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter";
-    /** failure recorder class */
-    public static final String FAILURE_RECORDER_CLASS_NAME =
-        "org.apache.tools.ant.taskdefs.optional.junit.FailureRecorder";
-
     /**
      * <p>Quick way to use a standard formatter.</p>
      *
@@ -104,18 +104,19 @@
      * @param type the enumerated value to use.
      */
     public void setType(TypeAttribute type) {
-        if ("xml".equals(type.getValue())) {
+        switch (type.getValue()) {
+        case "xml":
             setClassname(XML_FORMATTER_CLASS_NAME);
-        } else {
-            if ("brief".equals(type.getValue())) {
-                setClassname(BRIEF_FORMATTER_CLASS_NAME);
-            } else {
-                if ("failure".equals(type.getValue())) {
-                    setClassname(FAILURE_RECORDER_CLASS_NAME);
-                } else { // must be plain, ensured by TypeAttribute
-                    setClassname(PLAIN_FORMATTER_CLASS_NAME);
-                }
-            }
+            break;
+        case "brief":
+            setClassname(BRIEF_FORMATTER_CLASS_NAME);
+            break;
+        case "failure":
+            setClassname(FAILURE_RECORDER_CLASS_NAME);
+            break;
+        default:
+            setClassname(PLAIN_FORMATTER_CLASS_NAME);
+            break;
         }
     }
 
@@ -127,12 +128,18 @@
      */
     public void setClassname(String classname) {
         this.classname = classname;
-        if (XML_FORMATTER_CLASS_NAME.equals(classname)) {
-           setExtension(".xml");
-        } else if (PLAIN_FORMATTER_CLASS_NAME.equals(classname)) {
-           setExtension(".txt");
-        } else if (BRIEF_FORMATTER_CLASS_NAME.equals(classname)) {
-           setExtension(".txt");
+        if (classname != null) {
+            switch (classname) {
+            case XML_FORMATTER_CLASS_NAME:
+                setExtension(".xml");
+                break;
+            case PLAIN_FORMATTER_CLASS_NAME:
+                setExtension(".txt");
+                break;
+            case BRIEF_FORMATTER_CLASS_NAME:
+                setExtension(".txt");
+                break;
+            }
         }
     }
 
@@ -268,7 +275,6 @@
         this.project = project;
     }
 
-
     /**
      * @since Ant 1.6
      */
@@ -281,7 +287,7 @@
         //although this code appears to duplicate that of ClasspathUtils.newInstance,
         //we cannot use that because this formatter may run in a forked process,
         //without that class.
-        Class f = null;
+        Class<?> f;
         try {
             if (loader == null) {
                 f = Class.forName(classname);
@@ -298,26 +304,21 @@
                 + ": " + e, e);
         }
 
-        Object o = null;
+        JUnitResultFormatterMirror r;
         try {
-            o = f.newInstance();
-        } catch (InstantiationException e) {
-            throw new BuildException(e);
-        } catch (IllegalAccessException e) {
+            r = f.asSubclass(JUnitResultFormatterMirror.class).newInstance();
+        } catch (ClassCastException e) {
+            throw new BuildException("%s is not a JUnitResultFormatter",
+                classname);
+        } catch (InstantiationException | IllegalAccessException e) {
             throw new BuildException(e);
         }
 
-        if (!(o instanceof JUnitTaskMirror.JUnitResultFormatterMirror)) {
-            throw new BuildException(classname + " is not a JUnitResultFormatter");
-        }
-        JUnitTaskMirror.JUnitResultFormatterMirror r =
-            (JUnitTaskMirror.JUnitResultFormatterMirror) o;
         if (useFile && outFile != null) {
             out = new DelayedFileOutputStream(outFile);
         }
         r.setOutput(out);
 
-
         boolean needToSetProjectReference = true;
         try {
             Field field = r.getClass().getField("project");
@@ -335,8 +336,8 @@
         if (needToSetProjectReference) {
             Method setter;
             try {
-                setter = r.getClass().getMethod("setProject", new Class[] {Project.class});
-                setter.invoke(r, new Object[] {project});
+                setter = r.getClass().getMethod("setProject", Project.class);
+                setter.invoke(r, project);
             } catch (NoSuchMethodException e) {
                 // no setProject to invoke; just ignore
             } catch (IllegalAccessException e) {
@@ -356,6 +357,7 @@
      */
     public static class TypeAttribute extends EnumeratedAttribute {
         /** {@inheritDoc}. */
+        @Override
         public String[] getValues() {
             return new String[] {"plain", "xml", "brief", "failure"};
         }
@@ -380,7 +382,7 @@
         public void write(int b) throws IOException {
             synchronized (this) {
                 if (outputStream == null) {
-                    outputStream = new BufferedOutputStream(new FileOutputStream(file));
+                    outputStream = new BufferedOutputStream(Files.newOutputStream(file.toPath()));
                 }
             }
             outputStream.write(b);
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java
index 1497151..63370a0 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java
@@ -33,15 +33,15 @@
 public class IgnoredTestResult extends TestResult {
 
 
-    private List<IgnoredTestListener> listeners = new ArrayList<IgnoredTestListener>();
-    private List<TestIgnored> ignored = new ArrayList<TestIgnored>();
-    private List<TestIgnored> skipped = new ArrayList<TestIgnored>();
+    private List<IgnoredTestListener> listeners = new ArrayList<>();
+    private List<TestIgnored> ignored = new ArrayList<>();
+    private List<TestIgnored> skipped = new ArrayList<>();
 
     public IgnoredTestResult() {
         super();
     }
 
-
+    @Override
     public synchronized void addListener(TestListener listener) {
         if (listener instanceof IgnoredTestListener) {
             listeners.add((IgnoredTestListener) listener);
@@ -49,6 +49,7 @@
         super.addListener(listener);
     }
 
+    @Override
     public synchronized  void removeListener(TestListener listener) {
         if (listener instanceof IgnoredTestListener) {
             listeners.remove(listener);
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java
index f03a409..c797a87 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java
@@ -18,8 +18,8 @@
 
 package org.apache.tools.ant.taskdefs.optional.junit;
 
-import java.util.Iterator;
 import java.util.List;
+import java.util.function.Predicate;
 
 import junit.framework.Test;
 import junit.framework.TestResult;
@@ -41,7 +41,7 @@
  */
 public class JUnit4TestMethodAdapter implements Test {
 
-    private final Class testClass;
+    private final Class<?> testClass;
     private final String[] methodNames;
     private final Runner runner;
     private final CustomJUnit4TestAdapterCache cache;
@@ -55,7 +55,7 @@
      *             if any of the arguments is {@code null}
      *             or if any of the given method names is {@code null} or empty
      */
-    public JUnit4TestMethodAdapter(final Class testClass,
+    public JUnit4TestMethodAdapter(final Class<?> testClass,
                                    final String[] methodNames) {
         if (testClass == null) {
             throw new IllegalArgumentException("testClass is <null>");
@@ -87,6 +87,7 @@
         runner = request.getRunner();
     }
 
+    @Override
     public int countTestCases() {
         return runner.testCount();
     }
@@ -95,14 +96,15 @@
         return runner.getDescription();
     }
 
-    public List/*<Test>*/ getTests() {
+    public List<Test> getTests() {
         return cache.asTestList(getDescription());
     }
 
-    public Class getTestClass() {
+    public Class<?> getTestClass() {
         return testClass;
     }
 
+    @Override
     public void run(final TestResult result) {
         runner.run(cache.getNotifier(result));
     }
@@ -126,10 +128,10 @@
     private static final class MultipleMethodsFilter extends Filter {
 
         private final Description methodsListDescription;
-        private final Class testClass;
+        private final Class<?> testClass;
         private final String[] methodNames;
 
-        private MultipleMethodsFilter(Class testClass, String[] methodNames) {
+        private MultipleMethodsFilter(Class<?> testClass, String[] methodNames) {
             if (testClass == null) {
                 throw new IllegalArgumentException("testClass is <null>");
             }
@@ -151,23 +153,10 @@
                 return false;
             }
             if (description.isTest()) {
-                Iterator/*<Description>*/ it = methodsListDescription.getChildren().iterator();
-                while (it.hasNext()) {
-                    Description methodDescription = (Description) it.next();
-                    if (methodDescription.equals(description)) {
-                        return true;
-                    }
-                }
-            } else {
-                Iterator/*<Description>*/ it = description.getChildren().iterator();
-                while (it.hasNext()) {
-                    Description each = (Description) it.next();
-                    if (shouldRun(each)) {
-                        return true;
-                    }
-                }
+                return methodsListDescription.getChildren().stream()
+                    .anyMatch(Predicate.isEqual(description));
             }
-            return false;
+            return description.getChildren().stream().anyMatch(this::shouldRun);
         }
 
         @Override
@@ -189,5 +178,4 @@
 
     }
 
-
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
index dcf66c1..cf7d06b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
@@ -21,8 +21,6 @@
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FilenameFilter;
-import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
@@ -30,10 +28,12 @@
 import java.io.PrintStream;
 import java.lang.reflect.Constructor;
 import java.net.URL;
+import java.nio.file.Files;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
@@ -136,10 +136,26 @@
     private static final String LINE_SEP
         = System.getProperty("line.separator");
     private static final String CLASSPATH = "CLASSPATH";
+
+    private static final int STRING_BUFFER_SIZE = 128;
+    /**
+     * @since Ant 1.7
+     */
+    public static final String TESTLISTENER_PREFIX =
+        "junit.framework.TestListener: ";
+
+    /**
+     * Name of magic property that enables test listener events.
+     */
+    public static final String ENABLE_TESTLISTENER_EVENTS =
+        "ant.junit.enabletestlistenerevents";
+
+    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
     private CommandlineJava commandline;
-    private final Vector<JUnitTest> tests = new Vector<JUnitTest>();
-    private final Vector<BatchTest> batchTests = new Vector<BatchTest>();
-    private final Vector<FormatterElement> formatters = new Vector<FormatterElement>();
+    private final List<JUnitTest> tests = new Vector<>();
+    private final List<BatchTest> batchTests = new Vector<>();
+    private final Vector<FormatterElement> formatters = new Vector<>();
     private File dir = null;
 
     private Integer timeout = null;
@@ -187,21 +203,6 @@
     private String  failureProperty;
     private String  errorProperty;
 
-    private static final int STRING_BUFFER_SIZE = 128;
-    /**
-     * @since Ant 1.7
-     */
-    public static final String TESTLISTENER_PREFIX =
-        "junit.framework.TestListener: ";
-
-    /**
-     * Name of magic property that enables test listener events.
-     */
-    public static final String ENABLE_TESTLISTENER_EVENTS =
-        "ant.junit.enabletestlistenerevents";
-
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-
     /**
      * If true, force ant to re-classload all classes for each JUnit TestCase
      *
@@ -588,7 +589,7 @@
      * @since Ant 1.2
      */
     public void addTest(final JUnitTest test) {
-        tests.addElement(test);
+        tests.add(test);
         preConfigure(test);
     }
 
@@ -601,7 +602,7 @@
      */
     public BatchTest createBatchTest() {
         final BatchTest test = new BatchTest(getProject());
-        batchTests.addElement(test);
+        batchTests.add(test);
         preConfigure(test);
         return test;
     }
@@ -613,7 +614,7 @@
      * @since Ant 1.2
      */
     public void addFormatter(final FormatterElement fe) {
-        formatters.addElement(fe);
+        formatters.add(fe);
     }
 
     /**
@@ -721,11 +722,9 @@
      * @since Ant 1.6
      */
     public void setTempdir(final File tmpDir) {
-        if (tmpDir != null) {
-            if (!tmpDir.exists() || !tmpDir.isDirectory()) {
-                throw new BuildException(tmpDir.toString()
-                                         + " is not a valid temp directory");
-            }
+        if (tmpDir != null && (!tmpDir.exists() || !tmpDir.isDirectory())) {
+            throw new BuildException("%s is not a valid temp directory",
+                tmpDir);
         }
         this.tmpDir = tmpDir;
     }
@@ -786,12 +785,12 @@
                     e, task.getLocation());
         }
         try {
-            final Class c = loader.loadClass(JUnitTaskMirror.class.getName() + "Impl");
+            final Class<? extends JUnitTaskMirror> c = loader.loadClass(JUnitTaskMirror.class.getName() + "Impl").asSubclass(JUnitTaskMirror.class);
             if (c.getClassLoader() != loader) {
                 throw new BuildException("Overdelegating loader", task.getLocation());
             }
-            final Constructor cons = c.getConstructor(new Class[] {JUnitTask.class});
-            return (JUnitTaskMirror) cons.newInstance(new Object[] {task});
+            final Constructor<? extends JUnitTaskMirror> cons = c.getConstructor(JUnitTask.class);
+            return cons.newInstance(task);
         } catch (final Exception e) {
             throw new BuildException(e, task.getLocation());
         }
@@ -817,18 +816,16 @@
             if (extra != null && !hasJunit(path)) {
                 path.add(expandModulePath(extra));
             }
-            mirrorLoader = (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
-                public Object run() {
-                    return new SplitClassLoader(myLoader, path, getProject(),
-                            new String[] {"BriefJUnitResultFormatter", "JUnit4TestMethodAdapter",
-                                    "JUnitResultFormatter", "JUnitTaskMirrorImpl", "JUnitTestRunner",
-                                    "JUnitVersionHelper", "OutErrSummaryJUnitResultFormatter",
-                                    "PlainJUnitResultFormatter", "SummaryJUnitResultFormatter",
-                                    "TearDownOnVmCrash", "XMLJUnitResultFormatter", "IgnoredTestListener",
-                                    "IgnoredTestResult", "CustomJUnit4TestAdapterCache",
-                                    "TestListenerWrapper"});
-                }
-            });
+            mirrorLoader = AccessController.doPrivileged(
+                (PrivilegedAction<ClassLoader>) () -> new SplitClassLoader(
+                    myLoader, path, getProject(),
+                    new String[] {"BriefJUnitResultFormatter", "JUnit4TestMethodAdapter",
+                            "JUnitResultFormatter", "JUnitTaskMirrorImpl", "JUnitTestRunner",
+                            "JUnitVersionHelper", "OutErrSummaryJUnitResultFormatter",
+                            "PlainJUnitResultFormatter", "SummaryJUnitResultFormatter",
+                            "TearDownOnVmCrash", "XMLJUnitResultFormatter", "IgnoredTestListener",
+                            "IgnoredTestResult", "CustomJUnit4TestAdapterCache",
+                            "TestListenerWrapper"}));
         } else {
             mirrorLoader = myLoader;
         }
@@ -847,23 +844,20 @@
         checkModules();
         setupJUnitDelegate();
 
-        final List<List> testLists = new ArrayList<List>();
+        final List<List<JUnitTest>> testLists = new ArrayList<>();
         /* parallel test execution is only supported for multi-process execution */
         final int threads = !fork || forkMode.getValue().equals(ForkMode.ONCE) ? 1 : this.threads;
 
-        final boolean forkPerTest = forkMode.getValue().equals(ForkMode.PER_TEST);
-        if (forkPerTest || forkMode.getValue().equals(ForkMode.ONCE)) {
+        final boolean forkPerTest = ForkMode.PER_TEST.equals(forkMode.getValue());
+        if (forkPerTest || ForkMode.ONCE.equals(forkMode.getValue())) {
             testLists.addAll(executeOrQueue(getIndividualTests(),
                                             forkPerTest));
         } else { /* forkMode.getValue().equals(ForkMode.PER_BATCH) */
-            final int count = batchTests.size();
-            for (int i = 0; i < count; i++) {
-                final BatchTest batchtest = batchTests.elementAt(i);
-                testLists.addAll(executeOrQueue(batchtest.elements(), false));
-            }
-            testLists.addAll(executeOrQueue(tests.elements(), forkPerTest));
+            batchTests.stream().map(b -> executeOrQueue(b.elements(), false))
+                .forEach(testLists::addAll);
+            testLists.addAll(
+                executeOrQueue(Collections.enumeration(tests), forkPerTest));
         }
-
         try {
             /* prior to parallel the code in 'oneJunitThread' used to be here. */
             runTestsInThreads(testLists, threads);
@@ -888,12 +882,13 @@
      */
     private class JunitTestThread implements Runnable {
 
-        JunitTestThread(final JUnitTask master, final Iterator<List> iterator, final int id) {
+        JunitTestThread(final JUnitTask master, final Iterator<List<JUnitTest>> iterator, final int id) {
             this.masterTask = master;
             this.iterator = iterator;
             this.id = id;
         }
 
+        @Override
         public void run() {
             try {
                 masterTask.oneJunitThread(iterator, id);
@@ -904,7 +899,7 @@
         }
 
         private final JUnitTask masterTask;
-        private final Iterator<List> iterator;
+        private final Iterator<List<JUnitTest>> iterator;
         private final int id;
     }
 
@@ -915,8 +910,8 @@
      * threads get the same test, or two threads simultaneously pop the list so that a test
      * gets skipped!
      */
-    private List getNextTest(final Iterator<List> iter) {
-        synchronized(iter) {
+    private List<JUnitTest> getNextTest(final Iterator<List<JUnitTest>> iter) {
+        synchronized (iter) {
             if (iter.hasNext()) {
                 return iter.next();
             }
@@ -935,14 +930,14 @@
      * fatal reason, no new tests/batches will be started but the running threads will be
      * permitted to complete.  Additional tests may start in already-running batch-test threads.
      */
-    private void oneJunitThread(final Iterator<List> iter, final int threadId) {
+    private void oneJunitThread(final Iterator<List<JUnitTest>> iter, final int threadId) {
 
-        List l;
+        List<JUnitTest> l;
         log("Starting test thread " + threadId, Project.MSG_VERBOSE);
         while ((caughtBuildException == null) && ((l = getNextTest(iter)) != null)) {
             log("Running test " + l.get(0).toString() + "(" + l.size() + ") in thread " + threadId, Project.MSG_VERBOSE);
             if (l.size() == 1) {
-                execute((JUnitTest) l.get(0), threadId);
+                execute(l.get(0), threadId);
             } else {
                 execute(l, threadId);
             }
@@ -951,9 +946,9 @@
     }
 
 
-    private void runTestsInThreads(final List<List> testList, final int numThreads) {
+    private void runTestsInThreads(final List<List<JUnitTest>> testList, final int numThreads) {
 
-        Iterator<List> iter = testList.iterator();
+        Iterator<List<JUnitTest>> iter = testList.iterator();
 
         if (numThreads == 1) {
             /* with just one thread just run the test - don't create any threads */
@@ -966,24 +961,25 @@
             /* Need to split apart tests, which are still grouped in batches */
             /* is there a simpler Java mechanism to do this? */
             /* I assume we don't want to do this with "per batch" forking. */
-            List<List> newlist = new ArrayList<List>();
+            List<List<JUnitTest>> newlist = new ArrayList<>();
             if (forkMode.getValue().equals(ForkMode.PER_TEST)) {
-                final Iterator<List> i1 = testList.iterator();
+                final Iterator<List<JUnitTest>> i1 = testList.iterator();
                 while (i1.hasNext()) {
-                    final List l = i1.next();
+                    final List<JUnitTest> l = i1.next();
                     if (l.size() == 1) {
-                         newlist.add(l);
+                        newlist.add(l);
                     } else {
-                         final Iterator i2 = l.iterator();
-                         while (i2.hasNext()) {
-                             final List tmpSingleton = new ArrayList();
-                             tmpSingleton.add(i2.next());
-                             newlist.add(tmpSingleton);
-                         }
+                        final Iterator<JUnitTest> i2 = l.iterator();
+                        while (i2.hasNext()) {
+                            final List<JUnitTest> tmpSingleton =
+                                new ArrayList<>();
+                            tmpSingleton.add(i2.next());
+                            newlist.add(tmpSingleton);
+                        }
                     }
                 }
             } else {
-                 newlist = testList;
+                newlist = testList;
             }
             iter = newlist.iterator();
 
@@ -1026,7 +1022,7 @@
     protected void execute(final JUnitTest arg, final int thread) throws BuildException {
         validateTestName(arg.getName());
 
-        final JUnitTest test = (JUnitTest) arg.clone();
+        final JUnitTest test = arg.clone();
         test.setThread(thread);
 
         // set the default values if not specified
@@ -1040,13 +1036,13 @@
         }
 
         // execute the test and get the return code
-        TestResultHolder result = null;
-        if (!test.getFork()) {
-            result = executeInVM(test);
-        } else {
+        TestResultHolder result;
+        if (test.getFork()) {
             final ExecuteWatchdog watchdog = createWatchdog();
             result = executeAsForked(test, watchdog, null);
             // null watchdog means no timeout, you'd better not check with null
+        } else {
+            result = executeInVM(test);
         }
         actOnTestResult(result, test, "Test " + test.getName());
     }
@@ -1068,8 +1064,8 @@
      * @throws BuildException if <code>testName</code> is not a valid test name
      */
     private void validateTestName(final String testName) throws BuildException {
-        if (testName == null || testName.length() == 0
-            || testName.equals("null")) {
+        if (testName == null || testName.isEmpty()
+            || "null".equals(testName)) {
             throw new BuildException("test name must be specified");
         }
     }
@@ -1080,23 +1076,21 @@
      * @param thread Identifies which thread is test running in (0 for single-threaded runs)
      * @throws BuildException on error.
      */
-    protected void execute(final List testList, final int thread) throws BuildException {
-        JUnitTest test = null;
+    protected void execute(final List<JUnitTest> testList, final int thread) throws BuildException {
         // Create a temporary file to pass the test cases to run to
         // the runner (one test case per line)
         final File casesFile = createTempPropertiesFile("junittestcases");
-        BufferedWriter writer = null;
-        try {
-            writer = new BufferedWriter(new FileWriter(casesFile));
+        try (BufferedWriter writer =
+            new BufferedWriter(new FileWriter(casesFile))) {
 
             log("Creating casesfile '" + casesFile.getAbsolutePath()
                 + "' with content: ", Project.MSG_VERBOSE);
             final PrintStream logWriter =
                 new PrintStream(new LogOutputStream(this, Project.MSG_VERBOSE));
 
-            final Iterator iter = testList.iterator();
-            while (iter.hasNext()) {
-                test = (JUnitTest) iter.next();
+            JUnitTest test = null;
+            for (JUnitTest t : testList) {
+                test = t;
                 test.setThread(thread);
                 printDual(writer, logWriter, test.getName());
                 if (test.getMethods() != null) {
@@ -1117,8 +1111,6 @@
                 }
             }
             writer.flush();
-            writer.close();
-            writer = null;
 
             // execute the test and get the return code
             final ExecuteWatchdog watchdog = createWatchdog();
@@ -1129,8 +1121,6 @@
             log(e.toString(), Project.MSG_ERR);
             throw new BuildException(e);
         } finally {
-            FileUtils.close(writer);
-
             try {
                 FILE_UTILS.tryHardToDelete(casesFile);
             } catch (final Exception e) {
@@ -1144,7 +1134,7 @@
      * @param testList the list of tests to execute.
      * @throws BuildException on error.
      */
-    protected void execute(final List testList) throws BuildException {
+    protected void execute(final List<JUnitTest> testList) throws BuildException {
         execute(testList, 0);
     }
 
@@ -1175,7 +1165,7 @@
 
         CommandlineJava cmd;
         try {
-            cmd = (CommandlineJava) (getCommandline().clone());
+            cmd = getCommandline().clone();
         } catch (final CloneNotSupportedException e) {
             throw new BuildException("This shouldn't happen", e, getLocation());
         }
@@ -1211,7 +1201,7 @@
         cmd.createArgument().setValue(Constants.LOGTESTLISTENEREVENTS
                                       + String.valueOf(getEnableTestListenerEvents()));
 
-        StringBuffer formatterArg = new StringBuffer(STRING_BUFFER_SIZE);
+        StringBuilder formatterArg = new StringBuilder(STRING_BUFFER_SIZE);
         final FormatterElement[] feArray = mergeFormatters(test);
         for (int i = 0; i < feArray.length; i++) {
             final FormatterElement fe = feArray[i];
@@ -1224,7 +1214,7 @@
                     formatterArg.append(outFile);
                 }
                 cmd.createArgument().setValue(formatterArg.toString());
-                formatterArg = new StringBuffer();
+                formatterArg = new StringBuilder();
             }
         }
 
@@ -1234,17 +1224,14 @@
         final File propsFile = createTempPropertiesFile("junit");
         cmd.createArgument().setValue(Constants.PROPSFILE
                                       + propsFile.getAbsolutePath());
-        final Hashtable p = getProject().getProperties();
+        final Hashtable<String, Object> p = getProject().getProperties();
         final Properties props = new Properties();
-        for (final Enumeration e = p.keys(); e.hasMoreElements();) {
-            final Object key = e.nextElement();
-            props.put(key, p.get(key));
-        }
+        p.forEach(props::put);
         try {
-            final FileOutputStream outstream = new FileOutputStream(propsFile);
+            final OutputStream outstream = Files.newOutputStream(propsFile.toPath());
             props.store(outstream, "Ant JUnitTask generated properties file");
             outstream.close();
-        } catch (final java.io.IOException e) {
+        } catch (final IOException e) {
             FILE_UTILS.tryHardToDelete(propsFile);
             throw new BuildException("Error creating temporary properties "
                                      + "file.", e, getLocation());
@@ -1326,9 +1313,9 @@
                     + propsFile.getAbsolutePath() + "'.";
                 if (success) {
                     throw new BuildException(msg); //NOSONAR
-                } else { // don't hide inner exception
-                    log(msg, Project.MSG_ERR);
                 }
+                // don't hide inner exception
+                log(msg, Project.MSG_ERR);
             }
         }
 
@@ -1341,8 +1328,8 @@
      */
     private void checkIncludeAntRuntime(final CommandlineJava cmd) {
         if (includeAntRuntime) {
-            final Map/*<String, String>*/ env = Execute.getEnvironmentVariables();
-            final String cp = (String) env.get(CLASSPATH);
+            final Map<String, String> env = Execute.getEnvironmentVariables();
+            final String cp = env.get(CLASSPATH);
             if (cp != null) {
                 cmd.createClasspath(getProject()).createPath()
                     .append(new Path(getProject(), cp));
@@ -1354,7 +1341,6 @@
         }
     }
 
-
     /**
      * check for the parameter being "withoutanderr" in a locale-independent way.
      * @param summaryOption the summary option -can be null
@@ -1390,19 +1376,17 @@
         if (!cmd.haveClasspath()) {
             return;
         }
-        AntClassLoader loader = null;
-        try {
-            loader =
-                AntClassLoader.newAntClassLoader(null, getProject(),
-                                                 cmd.createClasspath(getProject()),
-                                                 true);
+        try (AntClassLoader loader =
+             AntClassLoader.newAntClassLoader(null, getProject(),
+                                              cmd.createClasspath(getProject()),
+                                              true)) {
             final String projectResourceName =
                 LoaderUtils.classNameToResource(Project.class.getName());
             URL previous = null;
             try {
-                for (final Enumeration e = loader.getResources(projectResourceName);
+                for (final Enumeration<URL> e = loader.getResources(projectResourceName);
                      e.hasMoreElements();) {
-                    final URL current = (URL) e.nextElement();
+                    final URL current = e.nextElement();
                     if (previous != null && !urlEquals(current, previous)) {
                         log("WARNING: multiple versions of ant detected "
                             + "in path for junit "
@@ -1416,10 +1400,6 @@
             } catch (final Exception ex) {
                 // Ignore exception
             }
-        } finally {
-            if (loader != null) {
-                loader.cleanup();
-            }
         }
     }
 
@@ -1505,9 +1485,8 @@
         throws IOException {
         if (runner != null) {
             return runner.handleInput(buffer, offset, length);
-        } else {
-            return super.handleInput(buffer, offset, length);
         }
+        return super.handleInput(buffer, offset, length);
     }
 
 
@@ -1584,7 +1563,7 @@
             setupJUnitDelegate();
         }
 
-        final JUnitTest test = (JUnitTest) arg.clone();
+        final JUnitTest test = arg.clone();
         test.setProperties(getProject().getProperties());
         if (dir != null) {
             log("dir attribute ignored if running in the same VM",
@@ -1695,12 +1674,14 @@
      */
     protected Enumeration<JUnitTest> getIndividualTests() {
         final int count = batchTests.size();
-        final Enumeration[] enums = new Enumeration[ count + 1];
+        @SuppressWarnings("unchecked")
+        final Enumeration<JUnitTest>[] enums = new Enumeration[ count + 1];
+
         for (int i = 0; i < count; i++) {
-            final BatchTest batchtest = batchTests.elementAt(i);
+            final BatchTest batchtest = batchTests.get(i);
             enums[i] = batchtest.elements();
         }
-        enums[enums.length - 1] = tests.elements();
+        enums[enums.length - 1] = Collections.enumeration(tests);
         return Enumerations.fromCompound(enums);
     }
 
@@ -1717,10 +1698,7 @@
         if (tests.isEmpty()) {
             return;
         }
-
-        final Enumeration<JUnitTest> testsEnum = tests.elements();
-        while (testsEnum.hasMoreElements()) {
-            final JUnitTest test = testsEnum.nextElement();
+        for (JUnitTest test : tests) {
             if (test.hasMethodsSpecified() && test.shouldRun(getProject())) {
                 test.resolveMethods();
             }
@@ -1734,15 +1712,10 @@
     private void checkModules() {
         if (hasPath(getCommandline().getModulepath()) ||
             hasPath(getCommandline().getUpgrademodulepath())) {
-            for (int i = 0, count = batchTests.size(); i < count; i++) {
-                if(!batchTests.elementAt(i).getFork()) {
-                    throw new BuildException("The module path requires fork attribute to be set to true.");
-                }
-            }
-            for (int i = 0, count = tests.size(); i < count; i++) {
-                if (!tests.elementAt(i).getFork()) {
-                    throw new BuildException("The module path requires fork attribute to be set to true.");
-                }
+            if (!(batchTests.stream().allMatch(BaseTest::getFork)
+                && tests.stream().allMatch(BaseTest::getFork))) {
+                throw new BuildException(
+                    "The module path requires fork attribute to be set to true.");
             }
         }
     }
@@ -1754,23 +1727,17 @@
      * @since 1.9.8
      */
     private boolean hasJunit(final Path path) {
-        AntClassLoader loader = null;
-        try {
-            loader = AntClassLoader.newAntClassLoader(
+        try (AntClassLoader loader = AntClassLoader.newAntClassLoader(
                 null,
                 getProject(),
                 path,
-                true);
+                true)) {
             try {
                 loader.loadClass("junit.framework.Test");
                 return true;
             } catch (final Exception ex) {
                 return false;
             }
-        } finally {
-            if (loader != null) {
-                loader.close();
-            }
         }
     }
 
@@ -1785,11 +1752,8 @@
         for (String path : modulePath.list()) {
             final File modulePathEntry = getProject().resolveFile(path);
             if (modulePathEntry.isDirectory() && !hasModuleInfo(modulePathEntry)) {
-                final File[] modules = modulePathEntry.listFiles(new FilenameFilter() {
-                        public boolean accept(File dir, String name) {
-                            return name.toLowerCase(Locale.ENGLISH).endsWith(".jar");
-                        }
-                    });
+                final File[] modules = modulePathEntry.listFiles((dir,
+                    name) -> name.toLowerCase(Locale.ENGLISH).endsWith(".jar"));
                 if (modules != null) {
                     for (File module : modules) {
                         expanded.add(new Path(getProject(), String.format(
@@ -1811,9 +1775,9 @@
      * @return enumeration
      * @since Ant 1.3
      */
-    protected Enumeration<JUnitTest> allTests() {
-        final Enumeration[] enums = {tests.elements(), batchTests.elements()};
-        return Enumerations.fromCompound(enums);
+    protected Enumeration<BaseTest> allTests() {
+        return Enumerations.fromCompound(Collections.enumeration(tests),
+            Collections.enumeration(batchTests));
     }
 
     /**
@@ -1822,6 +1786,7 @@
      * @since Ant 1.3
      */
     private FormatterElement[] mergeFormatters(final JUnitTest test) {
+        @SuppressWarnings("unchecked")
         final Vector<FormatterElement> feVector = (Vector<FormatterElement>) formatters.clone();
         test.addFormattersTo(feVector);
         final FormatterElement[] feArray = new FormatterElement[feVector.size()];
@@ -1967,7 +1932,7 @@
                         final File outFile = getOutput(fe, test);
                         if (outFile != null) {
                             try {
-                                out = new FileOutputStream(outFile);
+                                out = Files.newOutputStream(outFile.toPath());
                             } catch (final IOException e) {
                                 // ignore
                             }
@@ -2209,9 +2174,10 @@
      * @return a list of tasks to be executed.
      * @since 1.6.2
      */
-    protected Collection<List> executeOrQueue(final Enumeration<JUnitTest> testList,
-                                        final boolean runIndividual) {
-        final Map<ForkedTestConfiguration, List> testConfigurations = new HashMap<ForkedTestConfiguration, List>();
+    protected Collection<List<JUnitTest>> executeOrQueue(
+        final Enumeration<JUnitTest> testList, final boolean runIndividual) {
+        final Map<ForkedTestConfiguration, List<JUnitTest>> testConfigurations =
+            new HashMap<>();
         while (testList.hasMoreElements()) {
             final JUnitTest test = testList.nextElement();
             if (test.shouldRun(getProject())) {
@@ -2220,14 +2186,10 @@
                 if ((runIndividual || !test.getFork()) && (threads == 1)) {
                     execute(test, 0);
                 } else {
-                    final ForkedTestConfiguration c =
-                        new ForkedTestConfiguration(test);
-                    List<JUnitTest> l = testConfigurations.get(c);
-                    if (l == null) {
-                        l = new ArrayList<JUnitTest>();
-                        testConfigurations.put(c, l);
-                    }
-                    l.add(test);
+                    testConfigurations
+                        .computeIfAbsent(new ForkedTestConfiguration(test),
+                            k -> new ArrayList<>())
+                        .add(test);
                 }
             }
         }
@@ -2375,7 +2337,7 @@
      * @see "https://issues.apache.org/bugzilla/show_bug.cgi?id=45227"
      */
     private static JUnitTest createDummyTestForBatchTest(final JUnitTest test) {
-        final JUnitTest t = (JUnitTest) test.clone();
+        final JUnitTest t = test.clone();
         final int index = test.getName().lastIndexOf('.');
         // make sure test looks as if it was in the same "package" as
         // the last test of the batch
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java
index c7dae25..894b6a0 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java
@@ -35,6 +35,7 @@
  */
 public final class JUnitTaskMirrorImpl implements JUnitTaskMirror {
 
+    @SuppressWarnings("unused")
     private final JUnitTask task;
 
     /**
@@ -46,6 +47,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void addVmExit(JUnitTest test, JUnitTaskMirror.JUnitResultFormatterMirror aFormatter,
             OutputStream out, String message, String testCase) {
         JUnitResultFormatter formatter = (JUnitResultFormatter) aFormatter;
@@ -61,6 +63,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public JUnitTaskMirror.JUnitTestRunnerMirror newJUnitTestRunner(JUnitTest test,
             String[] methods,
             boolean haltOnError, boolean filterTrace, boolean haltOnFailure,
@@ -70,6 +73,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public JUnitTaskMirror.SummaryJUnitResultFormatterMirror newSummaryJUnitResultFormatter() {
         return new SummaryJUnitResultFormatter();
     }
@@ -86,14 +90,17 @@
             testCase = aTestCase;
         }
 
+        @Override
         public int countTestCases() {
             return 1;
         }
 
+        @Override
         public void run(TestResult r) {
             throw new AssertionFailedError(message);
         }
 
+        @Override
         public String getName() {
             return testCase;
         }
@@ -102,6 +109,7 @@
             return test.getName();
         }
 
+        @Override
         public String toString() {
             return test.getName() + ":" + testCase;
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java
index eb969d5..8d4a75d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java
@@ -18,7 +18,6 @@
 
 package org.apache.tools.ant.taskdefs.optional.junit;
 
-import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.Properties;
 import java.util.Vector;
@@ -228,7 +227,7 @@
             } else if (methods.length == 1) {
                 methodsList = methods[0];
             } else {
-                StringBuffer buf = new StringBuffer(methods.length * 16);
+                StringBuilder buf = new StringBuilder(methods.length * 16);
                 buf.append(methods[0]);
                 for (int i = 1; i < methods.length; i++) {
                     buf.append(',').append(methods[i]);
@@ -482,12 +481,9 @@
      * @param p the properties.
      *          This is a copy of the projects ant properties.
      */
-    public void setProperties(Hashtable p) {
+    public void setProperties(Hashtable<?, ?> p) {
         props = new Properties();
-        for (Enumeration e = p.keys(); e.hasMoreElements();) {
-            Object key = e.nextElement();
-            props.put(key, p.get(key));
-        }
+        p.forEach(props::put);
     }
 
     /**
@@ -516,7 +512,7 @@
     /**
      * Convenient method to add formatters to a vector
      */
-    void addFormattersTo(Vector v) {
+    void addFormattersTo(Vector<? super FormatterElement> v) {
         final int count = formatters.size();
         for (int i = 0; i < count; i++) {
             v.addElement(formatters.elementAt(i));
@@ -527,12 +523,13 @@
      * @since Ant 1.5
      * @return a clone of this test.
      */
+    @SuppressWarnings("unchecked")
     @Override
-    public Object clone() {
+    public JUnitTest clone() {
         try {
             JUnitTest t = (JUnitTest) super.clone();
             t.props = props == null ? null : (Properties) props.clone();
-            t.formatters = (Vector) formatters.clone();
+            t.formatters = (Vector<FormatterElement>) formatters.clone();
             return t;
         } catch (CloneNotSupportedException e) {
             // plain impossible
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
index 2eb2316..164ce33 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
@@ -22,18 +22,20 @@
 import java.io.BufferedWriter;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintStream;
 import java.io.StringReader;
 import java.io.StringWriter;
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.Enumeration;
-import java.util.Hashtable;
 import java.util.Properties;
 import java.util.StringTokenizer;
 import java.util.Vector;
@@ -72,34 +74,6 @@
  */
 
 public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestRunnerMirror {
-
-    /**
-     * Holds the registered formatters.
-     */
-    private final Vector<JUnitTaskMirror.JUnitResultFormatterMirror> formatters = new Vector();
-
-    /**
-     * Collects TestResults.
-     */
-    private IgnoredTestResult res;
-
-    /**
-     * Do we filter junit.*.* stack frames out of failure and error exceptions.
-     */
-    private static boolean filtertrace = true;
-
-    /**
-     * Do we send output to System.out/.err in addition to the formatters?
-     */
-    private boolean showOutput = false;
-
-    private boolean outputToFormatters = true;
-
-    /**
-     * The permissions set for the test to run.
-     */
-    private Permissions perm = null;
-
     private static final String JUNIT_4_TEST_ADAPTER = "junit.framework.JUnit4TestAdapter";
 
     private static final String[] DEFAULT_TRACE_FILTERS = new String[] {"junit.framework.TestCase",
@@ -117,6 +91,41 @@
             "junit.framework.JUnit4TestAdapter",
             " more"};
 
+    /**
+     * Do we filter junit.*.* stack frames out of failure and error exceptions.
+     */
+    private static boolean filtertrace = true;
+
+    /** Running more than one test suite? */
+    private static boolean multipleTests = false;
+
+    /**
+     * The file used to indicate that the build crashed.
+     * File will be empty in case the build did not crash.
+     */
+    private static String crashFile = null;
+
+    /**
+     * Holds the registered formatters.
+     */
+    private final Vector<JUnitTaskMirror.JUnitResultFormatterMirror> formatters = new Vector<>();
+
+    /**
+     * Collects TestResults.
+     */
+    private IgnoredTestResult res;
+
+    /**
+     * Do we send output to System.out/.err in addition to the formatters?
+     */
+    private boolean showOutput = false;
+
+    private boolean outputToFormatters = true;
+
+    /**
+     * The permissions set for the test to run.
+     */
+    private Permissions perm = null;
 
     /**
      * Do we stop on errors.
@@ -147,9 +156,6 @@
     /** is this runner running in forked mode? */
     private boolean forked = false;
 
-    /** Running more than one test suite? */
-    private static boolean multipleTests = false;
-
     /** ClassLoader passed in in non-forked mode. */
     private final ClassLoader loader;
 
@@ -159,12 +165,6 @@
     /** Turned on if we are using JUnit 4 for this test suite. see #38811 */
     private boolean junit4;
 
-    /**
-     * The file used to indicate that the build crashed.
-     * File will be empty in case the build did not crash.
-     */
-    private static String crashFile = null;
-
     /** Names of test methods to execute */
     private String[] methods = null;
 
@@ -361,6 +361,7 @@
     /**
      * Run the test.
      */
+    @Override
     public void run() {
         res = new IgnoredTestResult();
         res.addListener(wrapListener(this));
@@ -381,7 +382,7 @@
         try {
 
             try {
-                Class testClass = null;
+                Class<?> testClass;
                 if (loader == null) {
                     testClass = Class.forName(junitTest.getName());
                 } else {
@@ -395,24 +396,24 @@
                 // JUnit 4
                 Method suiteMethod = null;
                 if (!testMethodsSpecified) {
-                try {
-                    // check if there is a suite method
-                    suiteMethod = testClass.getMethod("suite", new Class[0]);
-                } catch (final NoSuchMethodException e) {
-                    // no appropriate suite method found. We don't report any
-                    // error here since it might be perfectly normal.
-                }
+                    try {
+                        // check if there is a suite method
+                        suiteMethod = testClass.getMethod("suite");
+                    } catch (final NoSuchMethodException e) {
+                        // no appropriate suite method found. We don't report any
+                        // error here since it might be perfectly normal.
+                    }
                 }
 
                 if (suiteMethod != null) {
                     // if there is a suite method available, then try
                     // to extract the suite from it. If there is an error
                     // here it will be caught below and reported.
-                    suite = (Test) suiteMethod.invoke(null, new Object[0]);
+                    suite = (Test) suiteMethod.invoke(null);
 
                 } else {
-                    Class junit4TestAdapterClass = null;
-                    Class junit4TestAdapterCacheClass = null;
+                    Class<?> junit4TestAdapterClass = null;
+                    Class<?> junit4TestAdapterCacheClass = null;
                     boolean useSingleMethodAdapter = false;
 
                     if (junit.framework.TestCase.class.isAssignableFrom(testClass)) {
@@ -438,50 +439,49 @@
                     // In that case first C.fN will fail with CNFE and we
                     // will avoid UnsupportedClassVersionError.
 
-                    try {
-                        Class.forName("java.lang.annotation.Annotation");
-                        junit4TestAdapterCacheClass = Class.forName("org.apache.tools.ant.taskdefs.optional.junit.CustomJUnit4TestAdapterCache");
-                        if (loader == null) {
-                            junit4TestAdapterClass =
-                                Class.forName(JUNIT_4_TEST_ADAPTER);
-                            if (testMethodsSpecified) {
-                                /*
-                                 * We cannot try to load the JUnit4TestAdapter
-                                 * before trying to load JUnit4TestMethodAdapter
-                                 * because it might fail with
-                                 * NoClassDefFoundException, instead of plain
-                                 * ClassNotFoundException.
-                                 */
-                                junit4TestAdapterClass = Class.forName(
-                                    "org.apache.tools.ant.taskdefs.optional.junit.JUnit4TestMethodAdapter");
-                                useSingleMethodAdapter = true;
+                        try {
+                            Class.forName("java.lang.annotation.Annotation");
+                            junit4TestAdapterCacheClass = Class.forName(
+                                "org.apache.tools.ant.taskdefs.optional.junit.CustomJUnit4TestAdapterCache");
+                            if (loader == null) {
+                                junit4TestAdapterClass = Class.forName(JUNIT_4_TEST_ADAPTER);
+                                if (testMethodsSpecified) {
+                                    /*
+                                     * We cannot try to load the JUnit4TestAdapter
+                                     * before trying to load JUnit4TestMethodAdapter
+                                     * because it might fail with
+                                     * NoClassDefFoundException, instead of plain
+                                     * ClassNotFoundException.
+                                     */
+                                    junit4TestAdapterClass = Class.forName(
+                                        "org.apache.tools.ant.taskdefs.optional.junit.JUnit4TestMethodAdapter");
+                                    useSingleMethodAdapter = true;
+                                }
+                            } else {
+                                junit4TestAdapterClass =
+                                    Class.forName(JUNIT_4_TEST_ADAPTER,
+                                                  true, loader);
+                                if (testMethodsSpecified) {
+                                    junit4TestAdapterClass = Class.forName(
+                                            "org.apache.tools.ant.taskdefs.optional.junit.JUnit4TestMethodAdapter",
+                                            true, loader);
+                                    useSingleMethodAdapter = true;
+                                }
                             }
-                        } else {
-                            junit4TestAdapterClass = Class.forName(JUNIT_4_TEST_ADAPTER,
-                                              true, loader);
-                            if (testMethodsSpecified) {
-                                junit4TestAdapterClass = Class.forName(
-                                        "org.apache.tools.ant.taskdefs.optional.junit.JUnit4TestMethodAdapter",
-                                        true, loader);
-                                useSingleMethodAdapter = true;
-                            }
+                        } catch (final ClassNotFoundException e) {
+                            // OK, fall back to JUnit 3.
                         }
-                    } catch (final ClassNotFoundException e) {
-                        // OK, fall back to JUnit 3.
-                    }
                     }
                     junit4 = junit4TestAdapterClass != null;
 
-                    if (junitTest.isSkipNonTests()) {
-                       if (!containsTests(testClass, junit4)) {
-                           return;
-                       }
+                    if (junitTest.isSkipNonTests()
+                        && !containsTests(testClass, junit4)) {
+                        return;
                     }
 
-
                     if (junit4) {
                         // Let's use it!
-                        Class[] formalParams;
+                        Class<?>[] formalParams;
                         Object[] actualParams;
                         if (useSingleMethodAdapter) {
                             formalParams = new Class[] {Class.class, String[].class};
@@ -492,8 +492,8 @@
                             actualParams = new Object[] {testClass, junit4TestAdapterCacheClass
                                     .getMethod("getInstance").invoke(null)};
                         }
-                        suite = (Test) junit4TestAdapterClass.getConstructor(formalParams)
-                                .newInstance(actualParams);
+                        suite = junit4TestAdapterClass.asSubclass(Test.class)
+                                .getConstructor(formalParams).newInstance(actualParams);
                     } else {
                         // Use JUnit 3.
 
@@ -513,9 +513,7 @@
                             suite = testSuite;
                         }
                     }
-
                 }
-
             } catch (final Throwable e) {
                 retCode = ERRORS;
                 exception = e;
@@ -589,12 +587,13 @@
     }
 
     private static boolean containsTests(final Class<?> testClass, final boolean isJUnit4) {
-        Class testAnnotation = null;
-        Class suiteAnnotation = null;
-        Class runWithAnnotation = null;
+        Class<? extends Annotation> testAnnotation = null;
+        Class<? extends Annotation> suiteAnnotation = null;
+        Class<? extends Annotation> runWithAnnotation = null;
 
         try {
-            testAnnotation = Class.forName("org.junit.Test");
+            testAnnotation =
+                Class.forName("org.junit.Test").asSubclass(Annotation.class);
         } catch (final ClassNotFoundException e) {
             if (isJUnit4) {
                 // odd - we think we're JUnit4 but don't support the test annotation. We therefore can't have any tests!
@@ -604,17 +603,18 @@
         }
 
         try {
-            suiteAnnotation = Class.forName("org.junit.Suite.SuiteClasses");
+            suiteAnnotation = Class.forName("org.junit.Suite.SuiteClasses")
+                .asSubclass(Annotation.class);
         } catch (final ClassNotFoundException ex) {
             // ignore - we don't have this annotation so make sure we don't check for it
         }
         try {
-            runWithAnnotation = Class.forName("org.junit.runner.RunWith");
+            runWithAnnotation = Class.forName("org.junit.runner.RunWith")
+                .asSubclass(Annotation.class);
         } catch (final ClassNotFoundException ex) {
             // also ignore as this annotation doesn't exist so tests can't use it
         }
 
-
         if (!isJUnit4 && !TestCase.class.isAssignableFrom(testClass)) {
             //a test we think is JUnit3 but does not extend TestCase. Can't really be a test.
             return false;
@@ -627,16 +627,17 @@
             }
         }
 
-        if (Modifier.isAbstract(testClass.getModifiers()) || Modifier.isInterface(testClass.getModifiers())) {
+        if (Modifier.isAbstract(testClass.getModifiers())
+                || Modifier.isInterface(testClass.getModifiers())) {
             // can't instantiate class and no inner classes are tests either
             return false;
         }
 
         if (isJUnit4) {
-             if (suiteAnnotation != null && testClass.getAnnotation(suiteAnnotation) != null) {
+            if (suiteAnnotation != null && testClass.getAnnotation(suiteAnnotation) != null) {
                 // class is marked as a suite. Let JUnit try and work its magic on it.
                 return true;
-             }
+            }
             if (runWithAnnotation != null && testClass.getAnnotation(runWithAnnotation) != null) {
                 /* Class is marked with @RunWith. If this class is badly written (no test methods,
                  * multiple constructors, private constructor etc) then the class is automatically
@@ -659,16 +660,19 @@
             } else {
                 // check if JUnit3 class have public or protected no-args methods starting with
                 // names starting with test
-                if (m.getName().startsWith("test") && m.getParameterTypes().length == 0
-                        && (Modifier.isProtected(m.getModifiers()) || Modifier.isPublic(m.getModifiers()))) {
+                if (m.getName().startsWith("test")
+                    && m.getParameterTypes().length == 0
+                    && (Modifier.isProtected(m.getModifiers())
+                        || Modifier.isPublic(m.getModifiers()))) {
                     return true;
                 }
             }
             // check if JUnit3 or JUnit4 test have a public or protected, static,
             // no-args 'suite' method
-            if (m.getName().equals("suite") && m.getParameterTypes().length == 0
-                    && (Modifier.isProtected(m.getModifiers()) || Modifier.isPublic(m.getModifiers()))
-                    && Modifier.isStatic(m.getModifiers())) {
+            if ("suite".equals(m.getName()) && m.getParameterTypes().length == 0
+                && (Modifier.isProtected(m.getModifiers())
+                    || Modifier.isPublic(m.getModifiers()))
+                && Modifier.isStatic(m.getModifiers())) {
                 return true;
             }
         }
@@ -682,6 +686,7 @@
      *
      * @return 2 if errors occurred, 1 if tests failed else 0.
      */
+    @Override
     public int getRetCode() {
         return retCode;
     }
@@ -692,6 +697,7 @@
      * <p>A new Test is started.
      * @param t the test.
      */
+    @Override
     public void startTest(final Test t) {
         final String testName = JUnitVersionHelper.getTestCaseName(t);
         logTestListenerEvent("startTest(" + testName + ")");
@@ -703,6 +709,7 @@
      * <p>A Test is finished.
      * @param test the test.
      */
+    @Override
     public void endTest(final Test test) {
         final String testName = JUnitVersionHelper.getTestCaseName(test);
         logTestListenerEvent("endTest(" + testName + ")");
@@ -713,10 +720,8 @@
             @SuppressWarnings("resource")
             final PrintStream out = savedOut != null ? savedOut : System.out;
             out.flush();
-            if (msg == null) {
-                msg = "null";
-            }
-            final StringTokenizer msgLines = new StringTokenizer(msg, "\r\n", false);
+            final StringTokenizer msgLines =
+                new StringTokenizer(String.valueOf(msg), "\r\n", false);
             while (msgLines.hasMoreTokens()) {
                 out.println(JUnitTask.TESTLISTENER_PREFIX + msgLines.nextToken());
             }
@@ -746,6 +751,7 @@
      * @param test the test.
      * @param t    the assertion thrown by the test.
      */
+    @Override
     public void addFailure(final Test test, final AssertionFailedError t) {
         addFailure(test, (Throwable) t);
     }
@@ -757,6 +763,7 @@
      * @param test the test.
      * @param t    the error thrown by the test.
      */
+    @Override
     public void addError(final Test test, final Throwable t) {
         final String testName = JUnitVersionHelper.getTestCaseName(test);
         logTestListenerEvent("addError(" + testName + ", " + t.getMessage() + ")");
@@ -770,6 +777,7 @@
      * @since Ant 1.6
      * @param permissions the permissions to use.
      */
+    @Override
     public void setPermissions(final Permissions permissions) {
         perm = permissions;
     }
@@ -778,6 +786,7 @@
      * Handle a string destined for standard output.
      * @param output the string to output
      */
+    @Override
     public void handleOutput(final String output) {
         if (!logTestListenerEvents && output.startsWith(JUnitTask.TESTLISTENER_PREFIX)) {
             // ignore
@@ -797,12 +806,14 @@
      *
      * @since Ant 1.6
      */
+    @Override
     public int handleInput(final byte[] buffer, final int offset, final int length)
         throws IOException {
         return -1;
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void handleErrorOutput(final String output) {
         if (systemError != null) {
             systemError.print(output);
@@ -810,6 +821,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void handleFlush(final String output) {
         if (systemOut != null) {
             systemOut.print(output);
@@ -817,6 +829,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void handleErrorFlush(final String output) {
         if (systemError != null) {
             systemError.print(output);
@@ -827,7 +840,7 @@
         final int size = formatters.size();
         for (int i = 0; i < size; i++) {
             final JUnitResultFormatter formatter =
-                ((JUnitResultFormatter) formatters.elementAt(i));
+                (JUnitResultFormatter) formatters.get(i);
 
             formatter.setSystemOutput(out);
             formatter.setSystemError(err);
@@ -857,6 +870,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void addFormatter(final JUnitTaskMirror.JUnitResultFormatterMirror f) {
         formatters.addElement(f);
     }
@@ -949,8 +963,8 @@
                     System.exit(ERRORS);
                 }
             } else if (args[i].startsWith(Constants.PROPSFILE)) {
-                final FileInputStream in = new FileInputStream(args[i]
-                        .substring(Constants.PROPSFILE.length()));
+                final InputStream in = Files.newInputStream(Paths.get(args[i]
+                        .substring(Constants.PROPSFILE.length())));
                 props.load(in);
                 in.close();
             } else if (args[i].startsWith(Constants.SHOWOUTPUT)) {
@@ -973,18 +987,11 @@
         }
 
         // Add/overlay system properties on the properties from the Ant project
-        final Hashtable p = System.getProperties();
-        for (final Enumeration e = p.keys(); e.hasMoreElements();) {
-            final Object key = e.nextElement();
-            props.put(key, p.get(key));
-        }
+        System.getProperties().forEach(props::put);
 
         int returnCode = SUCCESS;
         if (multipleTests) {
-            try {
-                final BufferedReader reader = new BufferedReader(new FileReader(args[0]));
-                String testCaseName;
-                String[] testMethodNames;
+            try (final BufferedReader reader = new BufferedReader(new FileReader(args[0]))) {
                 int code = 0;
                 boolean errorOccurred = false;
                 boolean failureOccurred = false;
@@ -993,6 +1000,8 @@
                     final StringTokenizer st = new StringTokenizer(line, ",");
                     final String testListSpec = st.nextToken();
                     final int colonIndex = testListSpec.indexOf(':');
+                    String testCaseName;
+                    String[] testMethodNames;
                     if (colonIndex == -1) {
                         testCaseName = testListSpec;
                         testMethodNames = null;
@@ -1044,43 +1053,52 @@
         System.exit(returnCode);
     }
 
-    private static Vector fromCmdLine = new Vector();
+    private static Vector<FormatterElement> fromCmdLine = new Vector<>();
 
     private static void transferFormatters(final JUnitTestRunner runner,
                                            final JUnitTest test) {
         runner.addFormatter(new JUnitResultFormatter() {
 
+            @Override
             public void startTestSuite(final JUnitTest suite) throws BuildException {
             }
 
+            @Override
             public void endTestSuite(final JUnitTest suite) throws BuildException {
             }
 
+            @Override
             public void setOutput(final OutputStream out) {
             }
 
+            @Override
             public void setSystemOutput(final String out) {
             }
 
+            @Override
             public void setSystemError(final String err) {
             }
 
+            @Override
             public void addError(final Test arg0, final Throwable arg1) {
             }
 
+            @Override
             public void addFailure(final Test arg0, final AssertionFailedError arg1) {
             }
 
+            @Override
             public void endTest(final Test arg0) {
             }
 
+            @Override
             public void startTest(final Test arg0) {
                 registerTestCase(JUnitVersionHelper.getTestCaseName(arg0));
             }
         });
         final int size = fromCmdLine.size();
         for (int i = 0; i < size; i++) {
-            final FormatterElement fe = (FormatterElement) fromCmdLine.elementAt(i);
+            final FormatterElement fe = fromCmdLine.elementAt(i);
             if (multipleTests && fe.getUseFile()) {
                 final File destFile = new File(test.getTodir(),
                         test.getOutfile() + fe.getExtension());
@@ -1282,14 +1300,19 @@
     private int[] findJUnit4FailureErrorCount(final TestResult result) {
         int failures = 0;
         int errors = 0;
-        Enumeration e = result.failures();
-        while (e.hasMoreElements()) {
-            e.nextElement();
-            failures++;
+        {
+            @SuppressWarnings("unchecked")
+            Enumeration<TestFailure> e = result.failures();
+            while (e.hasMoreElements()) {
+                e.nextElement();
+                failures++;
+            }
         }
-        e = result.errors();
+        @SuppressWarnings("unchecked")
+        Enumeration<TestFailure> e = result.errors();
         while (e.hasMoreElements()) {
-            final Throwable t = ((TestFailure) e.nextElement()).thrownException();
+            final Throwable t =
+                e.nextElement().thrownException();
             if (t instanceof AssertionFailedError
                 || t instanceof AssertionError) {
                 failures++;
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitVersionHelper.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitVersionHelper.java
index f0d7433..c214681 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitVersionHelper.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitVersionHelper.java
@@ -82,9 +82,8 @@
             if (name.endsWith(")")) {
                 int paren = name.lastIndexOf('(');
                 return name.substring(0, paren);
-            } else {
-                return name;
             }
+            return name;
         }
         if (t instanceof TestCase && testCaseName != null) {
             try {
@@ -94,17 +93,16 @@
             }
         } else {
             try {
-                Method getNameMethod = null;
+                Method getNameMethod;
                 try {
                     getNameMethod =
-                        t.getClass().getMethod("getName", new Class [0]);
+                        t.getClass().getMethod("getName");
                 } catch (NoSuchMethodException e) {
-                    getNameMethod = t.getClass().getMethod("name",
-                                                           new Class [0]);
+                    getNameMethod = t.getClass().getMethod("name");
                 }
                 if (getNameMethod != null
                     && getNameMethod.getReturnType() == String.class) {
-                    return (String) getNameMethod.invoke(t, new Object[0]);
+                    return (String) getNameMethod.invoke(t);
                 }
             } catch (Throwable ignored) {
                 // ignore
@@ -125,8 +123,7 @@
         String className = test.getClass().getName();
         if (test instanceof JUnitTaskMirrorImpl.VmExitErrorTest) {
             className = ((JUnitTaskMirrorImpl.VmExitErrorTest) test).getClassName();
-        } else
-        if (className.equals(JUNIT_FRAMEWORK_JUNIT4_TEST_CASE_FACADE)) {
+        } else if (className.equals(JUNIT_FRAMEWORK_JUNIT4_TEST_CASE_FACADE)) {
             // JUnit 4 wraps solo tests this way. We can extract
             // the original test name with a little hack.
             String name = test.toString();
@@ -152,28 +149,22 @@
                 Class<?> testClass = Class.forName(JUnitVersionHelper.getTestCaseClassName(test));
 
                 Method testMethod = testClass.getMethod(JUnitVersionHelper.getTestCaseName(test));
-                Class ignoreAnnotation = Class.forName("org.junit.Ignore");
+                Class<? extends Annotation> ignoreAnnotation = Class
+                    .forName("org.junit.Ignore").asSubclass(Annotation.class);
                 Annotation annotation = testMethod.getAnnotation(ignoreAnnotation);
                 if (annotation != null) {
-                    Method valueMethod = annotation.getClass().getMethod("value");
+                    Method valueMethod = annotation.annotationType().getMethod("value");
                     String value = (String) valueMethod.invoke(annotation);
                     if (value != null && value.length() > 0) {
                         message = value;
                     }
                 }
-
             }
-        } catch (NoSuchMethodException e) {
-            // silently ignore - we'll report a skip with no message
-        } catch (ClassNotFoundException e) {
-            // silently ignore - we'll report a skip with no message
-        } catch (InvocationTargetException e) {
-            // silently ignore - we'll report a skip with no message
-        } catch (IllegalAccessException e) {
+        } catch (NoSuchMethodException | ClassNotFoundException
+                | InvocationTargetException | IllegalAccessException e) {
             // silently ignore - we'll report a skip with no message
         }
         return message;
-
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java
index 6eedf53..0d71cd2 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java
@@ -24,6 +24,7 @@
 import java.io.StringWriter;
 import java.text.NumberFormat;
 import java.util.Hashtable;
+import java.util.Map;
 
 import junit.framework.AssertionFailedError;
 import junit.framework.Test;
@@ -37,7 +38,6 @@
  * Prints plain text output of the test to a specified Writer.
  *
  */
-
 public class PlainJUnitResultFormatter implements JUnitResultFormatter, IgnoredTestListener {
 
     private static final double ONE_SECOND = 1000.0;
@@ -49,7 +49,7 @@
     /**
      * Timing helper.
      */
-    private Hashtable testStarts = new Hashtable();
+    private Map<Test, Long> testStarts = new Hashtable<>();
     /**
      * Where to write the log to.
      */
@@ -65,7 +65,7 @@
     /**
      * Suppress endTest if testcase failed.
      */
-    private Hashtable failed = new Hashtable();
+    private Map<Test, Boolean> failed = new Hashtable<>();
 
     private String systemOutput = null;
     private String systemError = null;
@@ -77,16 +77,19 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void setOutput(OutputStream out) {
         this.out = out;
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void setSystemOutput(String out) {
         systemOutput = out;
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void setSystemError(String err) {
         systemError = err;
     }
@@ -96,15 +99,14 @@
      * @param suite the test suite
      * @throws BuildException if unable to write the output
      */
+    @Override
     public void startTestSuite(JUnitTest suite) throws BuildException {
         if (out == null) {
             return; // Quick return - no output do nothing.
         }
-        StringBuffer sb = new StringBuffer("Testsuite: ");
-        sb.append(suite.getName());
-        sb.append(StringUtils.LINE_SEP);
         try {
-            out.write(sb.toString().getBytes());
+            out.write(new StringBuilder("Testsuite: ").append(suite.getName())
+                .append(StringUtils.LINE_SEP).toString().getBytes());
             out.flush();
         } catch (IOException ex) {
             throw new BuildException("Unable to write output", ex);
@@ -116,10 +118,11 @@
      * @param suite the test suite
      * @throws BuildException if unable to write the output
      */
+    @Override
     public void endTestSuite(JUnitTest suite) throws BuildException {
         boolean success = false;
         try {
-            StringBuffer sb = new StringBuffer("Tests run: ");
+            StringBuilder sb = new StringBuilder("Tests run: ");
             sb.append(suite.runCount());
             sb.append(", Failures: ");
             sb.append(suite.failureCount());
@@ -185,6 +188,7 @@
      * <p>A new Test is started.
      * @param t the test.
      */
+    @Override
     public void startTest(Test t) {
         testStarts.put(t, new Long(System.currentTimeMillis()));
         failed.put(t, Boolean.FALSE);
@@ -196,6 +200,7 @@
      * <p>A Test is finished.
      * @param test the test.
      */
+    @Override
     public void endTest(Test test) {
         if (Boolean.TRUE.equals(failed.get(test))) {
             return;
@@ -204,7 +209,7 @@
             try {
                 wri.write("Testcase: "
                           + JUnitVersionHelper.getTestCaseName(test));
-                Long l = (Long) testStarts.get(test);
+                Long l = testStarts.get(test);
                 double seconds = 0;
                 // can be null if an error occurred in setUp
                 if (l != null) {
@@ -238,6 +243,7 @@
      * @param test the test.
      * @param t  the assertion that failed.
      */
+    @Override
     public void addFailure(Test test, AssertionFailedError t) {
         addFailure(test, (Throwable) t);
     }
@@ -249,6 +255,7 @@
      * @param test the test.
      * @param t    the exception.
      */
+    @Override
     public void addError(Test test, Throwable t) {
         formatError("\tCaused an ERROR", test, t);
     }
@@ -274,6 +281,7 @@
         }
     }
 
+    @Override
     public void testIgnored(Test test) {
         formatSkip(test, JUnitVersionHelper.getIgnoreMessage(test));
     }
@@ -297,6 +305,7 @@
 
     }
 
+    @Override
     public void testAssumptionFailure(Test test, Throwable throwable) {
         formatSkip(test, throwable.getMessage());
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java
index 4eb30fb..27239d6 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java
@@ -52,12 +52,6 @@
     private String systemError = null;
 
     /**
-     * Empty
-     */
-    public SummaryJUnitResultFormatter() {
-    }
-
-    /**
      *  Insures that a line of log output is written and flushed as a single
      *  operation, to prevent lines from being spliced into other lines.
      *  (Hopefully this solves the issue of run on lines -
@@ -81,9 +75,10 @@
      * The testsuite started.
      * @param suite the testsuite.
      */
+    @Override
     public void startTestSuite(JUnitTest suite) {
         String newLine = System.getProperty("line.separator");
-        StringBuffer sb = new StringBuffer("Running ");
+        StringBuilder sb = new StringBuilder("Running ");
         int antThreadID = suite.getThread();
 
         sb.append(suite.getName());
@@ -99,12 +94,14 @@
      * Empty
      * @param t not used.
      */
+    @Override
     public void startTest(Test t) {
     }
     /**
      * Empty
      * @param test not used.
      */
+    @Override
     public void endTest(Test test) {
     }
     /**
@@ -121,6 +118,7 @@
      * @param test not used.
      * @param t not used.
      */
+    @Override
     public void addFailure(Test test, AssertionFailedError t) {
         addFailure(test, (Throwable) t);
     }
@@ -129,20 +127,24 @@
      * @param test not used.
      * @param t not used.
      */
+    @Override
     public void addError(Test test, Throwable t) {
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void setOutput(OutputStream out) {
         this.out = out;
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void setSystemOutput(String out) {
         systemOutput = out;
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void setSystemError(String err) {
         systemError = err;
     }
@@ -152,6 +154,7 @@
      * the summary.
      * @param value if true write System.out and System.err to the summary.
      */
+    @Override
     public void setWithOutAndErr(boolean value) {
         withOutAndErr = value;
     }
@@ -161,9 +164,10 @@
      * @param suite the testsuite.
      * @throws BuildException if there is an error.
      */
+    @Override
     public void endTestSuite(JUnitTest suite) throws BuildException {
         String newLine = System.getProperty("line.separator");
-        StringBuffer sb = new StringBuffer("Tests run: ");
+        StringBuilder sb = new StringBuilder("Tests run: ");
         sb.append(suite.runCount());
         sb.append(", Failures: ");
         sb.append(suite.failureCount());
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/TearDownOnVmCrash.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/TearDownOnVmCrash.java
index 7bf8816..7b61117 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/TearDownOnVmCrash.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/TearDownOnVmCrash.java
@@ -19,7 +19,6 @@
 package org.apache.tools.ant.taskdefs.optional.junit;
 
 import java.io.OutputStream;
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
 import junit.framework.AssertionFailedError;
@@ -43,6 +42,7 @@
      * Records the suite's name to later determine the class to invoke
      * tearDown on.
      */
+    @Override
     public void startTestSuite(final JUnitTest suite) {
         suiteName = suite.getName();
         if (suiteName != null && suiteName.endsWith(JUnitTask.NAME_OF_DUMMY_TEST)) {
@@ -56,6 +56,7 @@
      * test we get when a Batch fails and the error is an actual
      * error generated by Ant.
      */
+    @Override
     public void addError(final Test fakeTest, final Throwable t) {
         if (suiteName != null && fakeTest instanceof JUnitTaskMirrorImpl.VmExitErrorTest) {
             tearDown();
@@ -66,24 +67,31 @@
     public void addFailure(Test test, Throwable t) {
     }
 
+    @Override
     public void addFailure(Test test, AssertionFailedError t) {
     }
 
+    @Override
     public void startTest(Test test) {
     }
 
+    @Override
     public void endTest(Test test) {
     }
 
+    @Override
     public void endTestSuite(JUnitTest suite) {
     }
 
+    @Override
     public void setOutput(OutputStream out) {
     }
 
+    @Override
     public void setSystemOutput(String out) {
     }
 
+    @Override
     public void setSystemError(String err) {
     }
 
@@ -91,7 +99,7 @@
         try {
             // first try to load the class and let's hope it is on our
             // classpath
-            Class testClass = null;
+            Class<?> testClass = null;
             if (Thread.currentThread().getContextClassLoader() != null) {
                 try {
                     testClass = Thread.currentThread().getContextClassLoader()
@@ -116,7 +124,7 @@
             // which test of the executed suite timed out, ignore it
             try {
                 // check if there is a suite method
-                testClass.getMethod("suite", new Class[0]);
+                testClass.getMethod("suite");
                 return;
             } catch (NoSuchMethodException e) {
                 // no suite method
@@ -127,9 +135,9 @@
             // doesn't have any tearDown method.
 
             try {
-                Method td = testClass.getMethod("tearDown", new Class[0]);
+                Method td = testClass.getMethod("tearDown");
                 if (td.getReturnType() == Void.TYPE) {
-                    td.invoke(testClass.newInstance(), new Object[0]);
+                    td.invoke(testClass.newInstance());
                 }
             } catch (NoSuchMethodException nsme) {
                 // no tearDown, fine
@@ -138,9 +146,6 @@
         } catch (ClassNotFoundException cnfe) {
             // class probably is not in our classpath, there is
             // nothing we can do
-        } catch (InvocationTargetException ite) {
-            System.err.println("Caught an exception while trying to invoke"
-                               + " tearDown: " + ite.getMessage());
         } catch (Throwable t) {
             System.err.println("Caught an exception while trying to invoke"
                                + " tearDown: " + t.getMessage());
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java
index 692e4fc..d65b7f2 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java
@@ -32,31 +32,38 @@
         wrapped = listener;
     }
 
+    @Override
     public void addError(Test test, Throwable throwable) {
         wrapped.addError(test, throwable);
     }
 
+    @Override
     public void addFailure(Test test, AssertionFailedError assertionFailedError) {
         wrapped.addFailure(test, assertionFailedError);
     }
 
+    @Override
     public void endTest(Test test) {
         wrapped.endTest(test);
     }
 
+    @Override
     public void startTest(Test test) {
         wrapped.startTest(test);
     }
 
+    @Override
     public void testIgnored(Test test) {
         if (wrapped instanceof IgnoredTestListener) {
-            ((IgnoredTestListener)wrapped).testIgnored(test);
+            ((IgnoredTestListener) wrapped).testIgnored(test);
         }
     }
 
+    @Override
     public void testAssumptionFailure(Test test, Throwable throwable) {
         if (wrapped instanceof IgnoredTestListener) {
-            ((IgnoredTestListener)wrapped).testAssumptionFailure(test, throwable);
+            ((IgnoredTestListener) wrapped).testAssumptionFailure(test,
+                throwable);
         }
     }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java
index 171348f..ed28220 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java
@@ -26,8 +26,8 @@
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.Date;
-import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.Map;
 import java.util.Properties;
 
 import javax.xml.parsers.DocumentBuilder;
@@ -50,7 +50,6 @@
  *
  * @see FormatterElement
  */
-
 public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstants, IgnoredTestListener {
 
     private static final double ONE_SECOND = 1000.0;
@@ -84,45 +83,44 @@
      * so we can't easily match Test objects without manually iterating over all keys and checking
      * individual fields.
      */
-    private final Hashtable<String, Element> testElements = new Hashtable<String, Element>();
+    private final Hashtable<String, Element> testElements = new Hashtable<>();
 
     /**
      * tests that failed.
      */
-    private final Hashtable failedTests = new Hashtable();
+    private final Map<Test, Test> failedTests = new Hashtable<>();
 
     /**
      * Tests that were skipped.
      */
-    private final Hashtable<String, Test> skippedTests = new Hashtable<String, Test>();
+    private final Map<String, Test> skippedTests = new Hashtable<>();
     /**
      * Tests that were ignored. See the note above about the key being a bit of a hack.
      */
-    private final Hashtable<String, Test> ignoredTests = new Hashtable<String, Test>();
+    private final Map<String, Test> ignoredTests = new Hashtable<>();
     /**
      * Timing helper.
      */
-    private final Hashtable<String, Long> testStarts = new Hashtable<String, Long>();
+    private final Map<String, Long> testStarts = new Hashtable<>();
     /**
      * Where to write the log to.
      */
     private OutputStream out;
 
-    /** No arg constructor. */
-    public XMLJUnitResultFormatter() {
-    }
-
     /** {@inheritDoc}. */
+    @Override
     public void setOutput(final OutputStream out) {
         this.out = out;
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void setSystemOutput(final String out) {
         formatOutput(SYSTEM_OUT, out);
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void setSystemError(final String out) {
         formatOutput(SYSTEM_ERR, out);
     }
@@ -131,6 +129,7 @@
      * The whole testsuite started.
      * @param suite the testsuite.
      */
+    @Override
     public void startTestSuite(final JUnitTest suite) {
         doc = getDocumentBuilder().newDocument();
         rootElement = doc.createElement(TESTSUITE);
@@ -149,9 +148,7 @@
         rootElement.appendChild(propsElement);
         final Properties props = suite.getProperties();
         if (props != null) {
-            final Enumeration e = props.propertyNames();
-            while (e.hasMoreElements()) {
-                final String name = (String) e.nextElement();
+            for (String name : props.stringPropertyNames()) {
                 final Element propElement = doc.createElement(PROPERTY);
                 propElement.setAttribute(ATTR_NAME, name);
                 propElement.setAttribute(ATTR_VALUE, props.getProperty(name));
@@ -182,19 +179,20 @@
      * @param suite the testsuite.
      * @throws BuildException on error.
      */
+    @Override
     public void endTestSuite(final JUnitTest suite) throws BuildException {
-        rootElement.setAttribute(ATTR_TESTS, "" + suite.runCount());
-        rootElement.setAttribute(ATTR_FAILURES, "" + suite.failureCount());
-        rootElement.setAttribute(ATTR_ERRORS, "" + suite.errorCount());
-        rootElement.setAttribute(ATTR_SKIPPED, "" + suite.skipCount());
+        rootElement.setAttribute(ATTR_TESTS, Long.toString(suite.runCount()));
+        rootElement.setAttribute(ATTR_FAILURES, Long.toString(suite.failureCount()));
+        rootElement.setAttribute(ATTR_ERRORS, Long.toString(suite.errorCount()));
+        rootElement.setAttribute(ATTR_SKIPPED, Long.toString(suite.skipCount()));
         rootElement.setAttribute(
-            ATTR_TIME, "" + (suite.getRunTime() / ONE_SECOND));
+            ATTR_TIME, Double.toString(suite.getRunTime() / ONE_SECOND));
         if (out != null) {
             Writer wri = null;
             try {
                 wri = new BufferedWriter(new OutputStreamWriter(out, "UTF8"));
                 wri.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
-                (new DOMElementWriter()).write(rootElement, wri, 0, "  ");
+                new DOMElementWriter().write(rootElement, wri, 0, "  ");
             } catch (final IOException exc) {
                 throw new BuildException("Unable to write log file", exc);
             } finally {
@@ -218,12 +216,14 @@
      * <p>A new Test is started.
      * @param t the test.
      */
+    @Override
     public void startTest(final Test t) {
         testStarts.put(createDescription(t), System.currentTimeMillis());
     }
 
     private static String createDescription(final Test test) throws BuildException {
-        return JUnitVersionHelper.getTestCaseName(test) + "(" + JUnitVersionHelper.getTestCaseClassName(test) + ")";
+        return JUnitVersionHelper.getTestCaseName(test) + "("
+            + JUnitVersionHelper.getTestCaseClassName(test) + ")";
     }
 
     /**
@@ -232,6 +232,7 @@
      * <p>A Test is finished.
      * @param test the test.
      */
+    @Override
     public void endTest(final Test test) {
         final String testDescription = createDescription(test);
 
@@ -242,7 +243,9 @@
             startTest(test);
         }
         Element currentTest;
-        if (!failedTests.containsKey(test) && !skippedTests.containsKey(testDescription) && !ignoredTests.containsKey(testDescription)) {
+        if (!failedTests.containsKey(test)
+            && !skippedTests.containsKey(testDescription)
+            && !ignoredTests.containsKey(testDescription)) {
             currentTest = doc.createElement(TESTCASE);
             final String n = JUnitVersionHelper.getTestCaseName(test);
             currentTest.setAttribute(ATTR_NAME,
@@ -259,7 +262,7 @@
 
         final Long l = testStarts.get(createDescription(test));
         currentTest.setAttribute(ATTR_TIME,
-            "" + ((System.currentTimeMillis() - l) / ONE_SECOND));
+            Double.toString((System.currentTimeMillis() - l) / ONE_SECOND));
     }
 
     /**
@@ -280,6 +283,7 @@
      * @param test the test.
      * @param t the assertion.
      */
+    @Override
     public void addFailure(final Test test, final AssertionFailedError t) {
         addFailure(test, (Throwable) t);
     }
@@ -291,6 +295,7 @@
      * @param test the test.
      * @param t the error.
      */
+    @Override
     public void addError(final Test test, final Throwable t) {
         formatError(ERROR, test, t);
     }
@@ -302,12 +307,8 @@
         }
 
         final Element nested = doc.createElement(type);
-        Element currentTest;
-        if (test != null) {
-            currentTest = testElements.get(createDescription(test));
-        } else {
-            currentTest = rootElement;
-        }
+        Element currentTest = test == null ? rootElement
+            : testElements.get(createDescription(test));
 
         currentTest.appendChild(nested);
 
@@ -328,6 +329,7 @@
         nested.appendChild(doc.createCDATASection(output));
     }
 
+    @Override
     public void testIgnored(final Test test) {
         formatSkip(test, JUnitVersionHelper.getIgnoreMessage(test));
         if (test != null) {
@@ -335,7 +337,6 @@
         }
     }
 
-
     public void formatSkip(final Test test, final String message) {
         if (test != null) {
             endTest(test);
@@ -347,17 +348,14 @@
             nested.setAttribute("message", message);
         }
 
-        Element currentTest;
-        if (test != null) {
-            currentTest = testElements.get(createDescription(test));
-        } else {
-            currentTest = rootElement;
-        }
+        Element currentTest = test == null ? rootElement
+            : testElements.get(createDescription(test));
 
         currentTest.appendChild(nested);
 
     }
 
+    @Override
     public void testAssumptionFailure(final Test test, final Throwable failure) {
         formatSkip(test, failure.getMessage());
         skippedTests.put(createDescription(test), test);
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLResultAggregator.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLResultAggregator.java
index 1ba6ff6..71cd828 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLResultAggregator.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLResultAggregator.java
@@ -19,13 +19,13 @@
 
 import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
-import java.util.Enumeration;
+import java.nio.file.Files;
 import java.util.Vector;
+import java.util.stream.Stream;
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -61,7 +61,7 @@
 
     // CheckStyle:VisibilityModifier OFF - bc
     /** the list of all filesets, that should contains the xml to aggregate */
-    protected Vector filesets = new Vector();
+    protected Vector<FileSet> filesets = new Vector<>();
 
     /** the name of the result file */
     protected String toFile;
@@ -69,7 +69,7 @@
     /** the directory to write the file to */
     protected File toDir;
 
-    protected Vector transformers = new Vector();
+    protected Vector<AggregateTransformer> transformers = new Vector<>();
 
     /** The default directory: <tt>&#046;</tt>. It is resolved from the project directory */
     public static final String DEFAULT_DIR = ".";
@@ -103,7 +103,7 @@
      */
     public AggregateTransformer createReport() {
         AggregateTransformer transformer = new AggregateTransformer(this);
-        transformers.addElement(transformer);
+        transformers.add(transformer);
         return transformer;
     }
 
@@ -133,7 +133,7 @@
      * @param    fs      the new fileset of xml results.
      */
     public void addFileSet(FileSet fs) {
-        filesets.addElement(fs);
+        filesets.add(fs);
     }
 
     /**
@@ -142,6 +142,7 @@
      * @throws  BuildException  thrown if there is a serious error while writing
      *          the document.
      */
+    @Override
     public void execute() throws BuildException {
         Element rootElement = createDocument();
         File destFile = getDestinationFile();
@@ -152,10 +153,7 @@
             throw new BuildException("Unable to write test aggregate to '" + destFile + "'", e);
         }
         // apply transformation
-        Enumeration e = transformers.elements();
-        while (e.hasMoreElements()) {
-            AggregateTransformer transformer =
-                (AggregateTransformer) e.nextElement();
+        for (AggregateTransformer transformer : transformers) {
             transformer.setXmlDocument(rootElement.getOwnerDocument());
             transformer.transform();
         }
@@ -182,26 +180,16 @@
      * @return all files in the fileset that end with a '.xml'.
      */
     protected File[] getFiles() {
-        Vector v = new Vector();
-        final int size = filesets.size();
-        for (int i = 0; i < size; i++) {
-            FileSet fs = (FileSet) filesets.elementAt(i);
-            DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+        Project p = getProject();
+        return filesets.stream().flatMap(fs -> {
+            DirectoryScanner ds = fs.getDirectoryScanner(p);
             ds.scan();
-            String[] f = ds.getIncludedFiles();
-            for (int j = 0; j < f.length; j++) {
-                String pathname = f[j];
-                if (pathname.endsWith(".xml")) {
-                    File file = new File(ds.getBasedir(), pathname);
-                    file = getProject().resolveFile(file.getPath());
-                    v.addElement(file);
-                }
-            }
-        }
-
-        File[] files = new File[v.size()];
-        v.copyInto(files);
-        return files;
+            return Stream.of(ds.getIncludedFiles())
+                .filter(pathname -> pathname.endsWith(".xml")).map(pathname -> {
+                    return p.resolveFile(
+                        new File(ds.getBasedir(), pathname).getPath());
+                });
+        }).toArray(File[]::new);
     }
 
     //----- from now, the methods are all related to DOM tree manipulation
@@ -213,18 +201,16 @@
      * @throws IOException thrown if there is an error while writing the content.
      */
     protected void writeDOMTree(Document doc, File file) throws IOException {
-        OutputStream os = new FileOutputStream(file);
-        try {
-            PrintWriter wri = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(os), "UTF8"));
+        try (OutputStream os = Files.newOutputStream(file.toPath());
+             PrintWriter wri = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(os), "UTF8"))) {
             wri.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
-            (new DOMElementWriter()).write(doc.getDocumentElement(), wri, 0, "  ");
+            new DOMElementWriter().write(doc.getDocumentElement(), wri, 0,
+                "  ");
             wri.flush();
             // writers do not throw exceptions, so check for them.
             if (wri.checkError()) {
                 throw new IOException("Error while writing DOM content");
             }
-        } finally {
-            os.close();
         }
     }
 
@@ -250,9 +236,8 @@
             try {
                 log("Parsing file: '" + file + "'", Project.MSG_VERBOSE);
                 if (file.length() > 0) {
-                    Document testsuiteDoc
-                            = builder.parse(
-                                FileUtils.getFileUtils().toURI(files[i].getAbsolutePath()));
+                    Document testsuiteDoc = builder.parse(FileUtils
+                        .getFileUtils().toURI(files[i].getAbsolutePath()));
                     Element elem = testsuiteDoc.getDocumentElement();
                     // make sure that this is REALLY a testsuite.
                     if (TESTSUITE.equals(elem.getNodeName())) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/BuiltinNative2Ascii.java b/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/BuiltinNative2Ascii.java
index db91a26..6cdf903 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/BuiltinNative2Ascii.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/BuiltinNative2Ascii.java
@@ -20,20 +20,19 @@
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
 import java.io.Writer;
+import java.nio.file.Files;
+import java.util.function.UnaryOperator;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.taskdefs.optional.Native2Ascii;
-import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.Native2AsciiUtils;
-import org.apache.tools.ant.util.StringUtils;
 
 /**
  * Encapsulates the built-in Native2Ascii implementation.
@@ -44,23 +43,16 @@
 
     static final String IMPLEMENTATION_NAME = "builtin";
 
+    @Override
     public final boolean convert(Native2Ascii args, File srcFile,
                                  File destFile) throws BuildException {
         boolean reverse = args.getReverse();
         String encoding = args.getEncoding();
-        BufferedReader input = null;
-        try {
-            input = getReader(srcFile, encoding, reverse);
-            try {
-                Writer output = getWriter(destFile, encoding, reverse);
-                try {
-                    translate(input, output, reverse);
-                } finally {
-                    FileUtils.close(output);
-                }
-            } finally {
-                FileUtils.close(input);
-            }
+        try (BufferedReader input = getReader(srcFile, encoding, reverse);
+                Writer output = getWriter(destFile, encoding, reverse)) {
+
+            translate(input, output, reverse ? Native2AsciiUtils::ascii2native
+                : Native2AsciiUtils::native2ascii);
             return true;
         } catch (IOException ex) {
             throw new BuildException("Exception trying to translate data", ex);
@@ -71,7 +63,7 @@
                                      boolean reverse) throws IOException {
         if (!reverse && encoding != null) {
             return new BufferedReader(new InputStreamReader(
-                new FileInputStream(srcFile), encoding));
+                Files.newInputStream(srcFile.toPath()), encoding));
         }
         return new BufferedReader(new FileReader(srcFile));
     }
@@ -83,22 +75,19 @@
         }
         if (encoding != null) {
             return new BufferedWriter(
-                new OutputStreamWriter(new FileOutputStream(destFile),
+                new OutputStreamWriter(Files.newOutputStream(destFile.toPath()),
                                        encoding));
         }
         return new BufferedWriter(new FileWriter(destFile));
     }
 
     private void translate(BufferedReader input, Writer output,
-                           boolean reverse) throws IOException {
-        String line = null;
-        while ((line = input.readLine()) != null) {
-            if (!reverse) {
-                output.write(Native2AsciiUtils.native2ascii(line));
-            } else {
-                output.write(Native2AsciiUtils.ascii2native(line));
-            }
-            output.write(StringUtils.LINE_SEP);
+        UnaryOperator<String> translation) throws IOException {
+        PrintWriter pw = new PrintWriter(output);
+
+        for (String line : (Iterable<String>) () -> input.lines()
+            .map(translation).iterator()) {
+            pw.println(line);
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/DefaultNative2Ascii.java b/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/DefaultNative2Ascii.java
index c16a1a3..51ff3f9 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/DefaultNative2Ascii.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/DefaultNative2Ascii.java
@@ -47,6 +47,7 @@
      * (delegated to {@link #addFiles addFiles}) and running the tool
      * (delegated to {@link #run run}).
      */
+    @Override
     public final boolean convert(Native2Ascii args, File srcFile,
                                  File destFile) throws BuildException {
         Commandline cmd = new Commandline();
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/KaffeNative2Ascii.java b/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/KaffeNative2Ascii.java
index da4836f..e29634a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/KaffeNative2Ascii.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/KaffeNative2Ascii.java
@@ -43,6 +43,7 @@
     public static final String IMPLEMENTATION_NAME = "kaffe";
 
     /** {@inheritDoc} */
+    @Override
     protected void setup(Commandline cmd, Native2Ascii args)
         throws BuildException {
         if (args.getReverse()) {
@@ -52,13 +53,14 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected boolean run(Commandline cmd, ProjectComponent log)
         throws BuildException {
         ExecuteJava ej = new ExecuteJava();
-        Class c = getN2aClass();
+        Class<?> c = getN2aClass();
         if (c == null) {
-            throw new BuildException("Couldn't load Kaffe's Native2Ascii"
-                                     + " class");
+            throw new BuildException(
+                "Couldn't load Kaffe's Native2Ascii class");
         }
 
         cmd.setExecutable(c.getName());
@@ -74,7 +76,7 @@
      *
      * @return null if neither class can get loaded.
      */
-    private static Class getN2aClass() {
+    private static Class<?> getN2aClass() {
         for (int i = 0; i < N2A_CLASSNAMES.length; i++) {
             try {
                 return Class.forName(N2A_CLASSNAMES[i]);
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapterFactory.java b/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapterFactory.java
index e8bd74d..74bb323 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapterFactory.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapterFactory.java
@@ -43,9 +43,6 @@
         if (shouldUseKaffee()) {
             return KaffeNative2Ascii.IMPLEMENTATION_NAME;
         }
-        if (shouldUseSun()) {
-            return SunNative2Ascii.IMPLEMENTATION_NAME;
-        }
         return BuiltinNative2Ascii.IMPLEMENTATION_NAME;
     }
 
@@ -85,8 +82,7 @@
         if ((shouldUseKaffee() && choice == null)
             || KaffeNative2Ascii.IMPLEMENTATION_NAME.equals(choice)) {
             return new KaffeNative2Ascii();
-        } else if ((shouldUseSun() && choice == null)
-                   || SunNative2Ascii.IMPLEMENTATION_NAME.equals(choice)) {
+        } else if (SunNative2Ascii.IMPLEMENTATION_NAME.equals(choice)) {
             return new SunNative2Ascii();
         } else if (BuiltinNative2Ascii.IMPLEMENTATION_NAME.equals(choice)) {
             return new BuiltinNative2Ascii();
@@ -121,11 +117,4 @@
     private static final boolean shouldUseKaffee() {
         return JavaEnvUtils.isKaffe() || JavaEnvUtils.isClasspathBased();
     }
-
-    private static final boolean shouldUseSun() {
-        return JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_5)
-            || JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_6)
-            || JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_7)
-            || JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_8);
-    }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/SunNative2Ascii.java b/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/SunNative2Ascii.java
index fac94b1..268006e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/SunNative2Ascii.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/SunNative2Ascii.java
@@ -36,7 +36,10 @@
      */
     public static final String IMPLEMENTATION_NAME = "sun";
 
+    private static final String SUN_TOOLS_NATIVE2ASCII_MAIN = "sun.tools.native2ascii.Main";
+
     /** {@inheritDoc} */
+    @Override
     protected void setup(Commandline cmd, Native2Ascii args)
         throws BuildException {
         if (args.getReverse()) {
@@ -46,23 +49,20 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected boolean run(Commandline cmd, ProjectComponent log)
         throws BuildException {
         try {
-            Class n2aMain = Class.forName("sun.tools.native2ascii.Main");
-            Class[] param = new Class[] {String[].class};
-            Method convert = n2aMain.getMethod("convert", param);
-            if (convert == null) {
-                throw new BuildException("Could not find convert() method in "
-                                         + "sun.tools.native2ascii.Main");
-            }
-            Object o = n2aMain.newInstance();
-            return ((Boolean) convert.invoke(o,
-                                             new Object[] {cmd.getArguments()})
-                    ).booleanValue();
+            Class<?> n2aMain = Class.forName(SUN_TOOLS_NATIVE2ASCII_MAIN);
+            Method convert = n2aMain.getMethod("convert", String[].class);
+            return Boolean.TRUE.equals(convert.invoke(n2aMain.newInstance(),
+                (Object) cmd.getArguments()));
         } catch (BuildException ex) {
             //rethrow
             throw ex;
+        } catch (NoSuchMethodException ex) {
+            throw new BuildException("Could not find convert() method in %s",
+                SUN_TOOLS_NATIVE2ASCII_MAIN);
         } catch (Exception ex) {
             //wrap
            throw new BuildException("Error starting Sun's native2ascii: ", ex);
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java b/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java
index c552344..9aa1b49 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java
@@ -21,25 +21,24 @@
 import java.io.BufferedOutputStream;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.file.Files;
 import java.text.SimpleDateFormat;
 import java.util.Collection;
 import java.util.Date;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.Vector;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 import org.apache.commons.net.ftp.FTPClient;
 import org.apache.commons.net.ftp.FTPClientConfig;
@@ -120,8 +119,8 @@
     private long granularityMillis = 0L;
     private boolean timeDiffAuto = false;
     private int action = SEND_FILES;
-    private Vector filesets = new Vector();
-    private Set dirCache = new HashSet();
+    private Vector<FileSet> filesets = new Vector<>();
+    private Set<File> dirCache = new HashSet<>();
     private int transferred = 0;
     private String remoteFileSep = "/";
     private int port = DEFAULT_FTP_PORT;
@@ -183,6 +182,7 @@
      *
      */
     protected static class FTPFileProxy extends File {
+        private static final long serialVersionUID = 1L;
 
         private final FTPFile file;
         private final String[] parts;
@@ -214,6 +214,7 @@
         /* (non-Javadoc)
          * @see java.io.File#exists()
          */
+        @Override
         public boolean exists() {
             return true;
         }
@@ -222,6 +223,7 @@
         /* (non-Javadoc)
          * @see java.io.File#getAbsolutePath()
          */
+        @Override
         public String getAbsolutePath() {
             return name;
         }
@@ -230,6 +232,7 @@
         /* (non-Javadoc)
          * @see java.io.File#getName()
          */
+        @Override
         public String getName() {
             return parts.length > 0 ? parts[parts.length - 1] : name;
         }
@@ -238,6 +241,7 @@
         /* (non-Javadoc)
          * @see java.io.File#getParent()
          */
+        @Override
         public String getParent() {
             String result = "";
             for(int i = 0; i < parts.length - 1; i++){
@@ -250,6 +254,7 @@
         /* (non-Javadoc)
          * @see java.io.File#getPath()
          */
+        @Override
         public String getPath() {
             return name;
         }
@@ -259,6 +264,7 @@
          * FTP files are stored as absolute paths
          * @return true
          */
+        @Override
         public boolean isAbsolute() {
             return true;
         }
@@ -267,6 +273,7 @@
         /* (non-Javadoc)
          * @see java.io.File#isDirectory()
          */
+        @Override
         public boolean isDirectory() {
             return file == null;
         }
@@ -275,6 +282,7 @@
         /* (non-Javadoc)
          * @see java.io.File#isFile()
          */
+        @Override
         public boolean isFile() {
             return file != null;
         }
@@ -285,6 +293,7 @@
          *
          * @return  false
          */
+        @Override
         public boolean isHidden() {
             return false;
         }
@@ -293,6 +302,7 @@
         /* (non-Javadoc)
          * @see java.io.File#lastModified()
          */
+        @Override
         public long lastModified() {
             if (file != null) {
                 return file.getTimestamp().getTimeInMillis();
@@ -304,6 +314,7 @@
         /* (non-Javadoc)
          * @see java.io.File#length()
          */
+        @Override
         public long length() {
             if (file != null) {
                 return file.getSize();
@@ -349,6 +360,7 @@
          * scans the remote directory,
          * storing internally the included files, directories, ...
          */
+        @Override
         public void scan() {
             if (includes == null) {
                 // No includes supplied, so set it to 'matches all'
@@ -359,12 +371,12 @@
                 excludes = new String[0];
             }
 
-            filesIncluded = new VectorSet();
-            filesNotIncluded = new Vector();
-            filesExcluded = new VectorSet();
-            dirsIncluded = new VectorSet();
-            dirsNotIncluded = new Vector();
-            dirsExcluded = new VectorSet();
+            filesIncluded = new VectorSet<>();
+            filesNotIncluded = new Vector<>();
+            filesExcluded = new VectorSet<>();
+            dirsIncluded = new VectorSet<>();
+            dirsNotIncluded = new Vector<>();
+            dirsExcluded = new VectorSet<>();
 
             try {
                 String cwd = ftp.printWorkingDirectory();
@@ -387,7 +399,7 @@
          */
         private void checkIncludePatterns() {
 
-            Hashtable newroots = new Hashtable();
+            Map<String, String> newroots = new HashMap<>();
             // put in the newroots vector the include patterns without
             // wildcard tokens
             for (int icounter = 0; icounter < includes.length; icounter++) {
@@ -412,69 +424,70 @@
             } else {
                 // only scan directories that can include matched files or
                 // directories
-                Enumeration enum2 = newroots.keys();
+                newroots.forEach((k, v) -> scanRoots(baseFTPFile, k, v));
+            }
+        }
 
-                while (enum2.hasMoreElements()) {
-                    String currentelement = (String) enum2.nextElement();
-                    String originalpattern = (String) newroots.get(currentelement);
-                    AntFTPFile myfile = new AntFTPFile(baseFTPFile, currentelement);
-                    boolean isOK = true;
-                    boolean traversesSymlinks = false;
-                    String path = null;
+        private void scanRoots(AntFTPFile baseFTPFile, String currentelement, String originalpattern) {
+            AntFTPFile myfile = new AntFTPFile(baseFTPFile, currentelement);
+            boolean isOK = true;
+            boolean traversesSymlinks = false;
+            String path = null;
 
-                    if (myfile.exists()) {
-                        forceRemoteSensitivityCheck();
-                        if (remoteSensitivityChecked
-                            && remoteSystemCaseSensitive && isFollowSymlinks()) {
-                            // cool case,
-                            //we do not need to scan all the subdirs in the relative path
-                            path = myfile.getFastRelativePath();
-                        } else {
-                            // may be on a case insensitive file system.  We want
-                            // the results to show what's really on the disk, so
-                            // we need to double check.
-                            try {
-                                path = myfile.getRelativePath();
-                                traversesSymlinks = myfile.isTraverseSymlinks();
-                            }  catch (IOException be) {
-                                throw new BuildException(be, getLocation());
-                            } catch (BuildException be) {
-                                isOK = false;
-                            }
-                        }
-                    } else {
+            if (myfile.exists()) {
+                forceRemoteSensitivityCheck();
+                if (remoteSensitivityChecked
+                    && remoteSystemCaseSensitive && isFollowSymlinks()) {
+                    // cool case,
+                    //we do not need to scan all the subdirs in the relative path
+                    path = myfile.getFastRelativePath();
+                } else {
+                    // may be on a case insensitive file system.  We want
+                    // the results to show what's really on the disk, so
+                    // we need to double check.
+                    try {
+                        path = myfile.getRelativePath();
+                        traversesSymlinks = myfile.isTraverseSymlinks();
+                    } catch (IOException be) {
+                        throw new BuildException(be, getLocation());
+                    } catch (BuildException be) {
                         isOK = false;
                     }
-                    if (isOK) {
-                        currentelement = path.replace(remoteFileSep.charAt(0), File.separatorChar);
-                        if (!isFollowSymlinks() && traversesSymlinks) {
-                            continue;
-                        }
+                }
+            } else {
+                isOK = false;
+            }
+            if (isOK) {
+                currentelement = path.replace(remoteFileSep.charAt(0), File.separatorChar);
+                if (!isFollowSymlinks() && traversesSymlinks) {
+                    return;
+                }
 
-                        if (myfile.isDirectory()) {
-                            if (isIncluded(currentelement) && currentelement.length() > 0) {
-                                accountForIncludedDir(currentelement, myfile, true);
-                            }  else {
-                                if (currentelement.length() > 0) {
-                                    if (currentelement.charAt(currentelement.length() - 1)
-                                        != File.separatorChar) {
-                                        currentelement = currentelement + File.separatorChar;
-                                    }
-                                }
-                                scandir(myfile.getAbsolutePath(), currentelement, true);
-                            }
-                        } else {
-                            if (isCaseSensitive && originalpattern.equals(currentelement)) {
-                                accountForIncludedFile(currentelement);
-                            } else if (!isCaseSensitive
-                                       && originalpattern.equalsIgnoreCase(currentelement)) {
-                                accountForIncludedFile(currentelement);
+                if (myfile.isDirectory()) {
+                    if (isIncluded(currentelement)
+                        && currentelement.length() > 0) {
+                        accountForIncludedDir(currentelement, myfile, true);
+                    }  else {
+                        if (currentelement.length() > 0) {
+                            if (currentelement.charAt(currentelement
+                                                      .length() - 1)
+                                != File.separatorChar) {
+                                currentelement =
+                                    currentelement + File.separatorChar;
                             }
                         }
+                        scandir(myfile.getAbsolutePath(), currentelement, true);
                     }
+                } else if (isCaseSensitive
+                    && originalpattern.equals(currentelement)) {
+                    accountForIncludedFile(currentelement);
+                } else if (!isCaseSensitive && originalpattern
+                    .equalsIgnoreCase(currentelement)) {
+                    accountForIncludedFile(currentelement);
                 }
             }
         }
+
         /**
          * scans a particular directory. populates the scannedDirs cache.
          *
@@ -493,7 +506,7 @@
                     return;
                 }
                 String completePath = null;
-                if (!vpath.equals("")) {
+                if (!vpath.isEmpty()) {
                     completePath = rootPath + remoteFileSep
                         + vpath.replace(File.separatorChar, remoteFileSep.charAt(0));
                 } else {
@@ -556,7 +569,7 @@
 
                 if (isIncluded(name)) {
                     if (!isExcluded(name)
-                        && isSelected(name, (File) scannedDirs.get(name))) {
+                        && isSelected(name, scannedDirs.get(name))) {
                         filesIncluded.addElement(name);
                     } else {
                         filesExcluded.addElement(name);
@@ -618,14 +631,14 @@
          *
          * @since Ant 1.6
          */
-        private Map fileListMap = new HashMap();
+        private Map<String, FTPFile[]> fileListMap = new HashMap<>();
         /**
          * List of all scanned directories.
          *
          * @since Ant 1.6
          */
 
-        private Map scannedDirs = new HashMap();
+        private Map<String, FTPFileProxy> scannedDirs = new HashMap<>();
 
         /**
          * Has the directory with the given path relative to the base
@@ -653,12 +666,10 @@
          * @return array of FTPFile
          */
         public FTPFile[] listFiles(String directory, boolean changedir) {
-            //getProject().log("listing files in directory " + directory, Project.MSG_DEBUG);
             String currentPath = directory;
             if (changedir) {
                 try {
-                    boolean result = ftp.changeWorkingDirectory(directory);
-                    if (!result) {
+                    if (!ftp.changeWorkingDirectory(directory)) {
                         return null;
                     }
                     currentPath = ftp.printWorkingDirectory();
@@ -668,9 +679,9 @@
             }
             if (fileListMap.containsKey(currentPath)) {
                 getProject().log("filelist map used in listing files", Project.MSG_DEBUG);
-                return ((FTPFile[]) fileListMap.get(currentPath));
+                return fileListMap.get(currentPath);
             }
-            FTPFile[] result = null;
+            FTPFile[] result;
             try {
                 result = ftp.listFiles();
             } catch (IOException ioe) {
@@ -701,6 +712,7 @@
         public FTPFile[] listFiles(String directory) {
             return listFiles(directory, true);
         }
+
         private void checkRemoteSensitivity(FTPFile[] array, String directory) {
             if (array == null) {
                 return;
@@ -709,8 +721,8 @@
             String target = null;
             for (int icounter = 0; icounter < array.length; icounter++) {
                 if (array[icounter] != null && array[icounter].isDirectory()) {
-                    if (!array[icounter].getName().equals(".")
-                        && !array[icounter].getName().equals("..")) {
+                    if (!".".equals(array[icounter].getName())
+                        && !"..".equals(array[icounter].getName())) {
                         candidateFound = true;
                         target = fiddleName(array[icounter].getName());
                         getProject().log("will try to cd to "
@@ -749,8 +761,9 @@
                 remoteSensitivityChecked = true;
             }
         }
+
         private String fiddleName(String origin) {
-            StringBuffer result = new StringBuffer();
+            StringBuilder result = new StringBuilder();
             for (int icounter = 0; icounter < origin.length(); icounter++) {
                 if (Character.isLowerCase(origin.charAt(icounter))) {
                     result.append(Character.toUpperCase(origin.charAt(icounter)));
@@ -762,6 +775,7 @@
             }
             return result.toString();
         }
+
         /**
          * an AntFTPFile is a representation of a remote file
          * @since Ant 1.6
@@ -805,46 +819,47 @@
             public AntFTPFile(AntFTPFile parent, String path) {
                 this.parent = parent;
                 this.client = parent.client;
-                Vector pathElements = SelectorUtils.tokenizePath(path);
+                List<String> pathElements = SelectorUtils.tokenizePath(path);
                 try {
-                    boolean result = this.client.changeWorkingDirectory(parent.getAbsolutePath());
                     //this should not happen, except if parent has been deleted by another process
-                    if (!result) {
+                    if (!this.client.changeWorkingDirectory(parent.getAbsolutePath())) {
                         return;
                     }
                     this.curpwd = parent.getAbsolutePath();
                 } catch (IOException ioe) {
-                    throw new BuildException("could not change working dir to "
-                                             + parent.curpwd);
+                    throw new BuildException(
+                        "could not change working dir to %s", parent.curpwd);
                 }
                 final int size = pathElements.size();
                 for (int fcount = 0; fcount < size - 1; fcount++) {
-                    String currentPathElement = (String) pathElements.elementAt(fcount);
+                    String currentPathElement = pathElements.get(fcount);
                     try {
-                        boolean result = this.client.changeWorkingDirectory(currentPathElement);
-                        if (!result && !isCaseSensitive()
-                            && (remoteSystemCaseSensitive || !remoteSensitivityChecked)) {
-                            currentPathElement = findPathElementCaseUnsensitive(this.curpwd,
-                                                                                currentPathElement);
-                            if (currentPathElement == null) {
-                                return;
+                        if (!this.client
+                            .changeWorkingDirectory(currentPathElement)) {
+                            if (!isCaseSensitive() && (remoteSystemCaseSensitive
+                                || !remoteSensitivityChecked)) {
+                                currentPathElement =
+                                    findPathElementCaseUnsensitive(this.curpwd,
+                                        currentPathElement);
+                                if (currentPathElement == null) {
+                                    return;
+                                }
                             }
-                        } else if (!result) {
                             return;
                         }
-                        this.curpwd = getCurpwdPlusFileSep()
-                            + currentPathElement;
+                        this.curpwd =
+                            getCurpwdPlusFileSep() + currentPathElement;
                     } catch (IOException ioe) {
-                        throw new BuildException("could not change working dir to "
-                                                 + (String) pathElements.elementAt(fcount)
-                                                 + " from " + this.curpwd);
+                        throw new BuildException(
+                            "could not change working dir to %s from %s",
+                            currentPathElement, curpwd);
                     }
-
                 }
-                String lastpathelement = (String) pathElements.elementAt(size - 1);
-                FTPFile [] theFiles = listFiles(this.curpwd);
+                String lastpathelement = pathElements.get(pathElements.size() - 1);
+                FTPFile[] theFiles = listFiles(this.curpwd);
                 this.ftpFile = getFile(theFiles, lastpathelement);
             }
+
             /**
              * find a file in a directory in case insensitive way
              * @param parentPath        where we are
@@ -859,14 +874,15 @@
                 if (theFiles == null) {
                     return null;
                 }
-                for (int icounter = 0; icounter < theFiles.length; icounter++) {
-                    if (theFiles[icounter] != null
-                        && theFiles[icounter].getName().equalsIgnoreCase(soughtPathElement)) {
-                        return theFiles[icounter].getName();
+                for (FTPFile f : theFiles) {
+                    if (f != null
+                        && f.getName().equalsIgnoreCase(soughtPathElement)) {
+                        return f.getName();
                     }
                 }
                 return null;
             }
+
             /**
              * find out if the file exists
              * @return  true if the file exists
@@ -874,6 +890,7 @@
             public boolean exists() {
                 return (ftpFile != null);
             }
+
             /**
              * if the file is a symbolic link, find out to what it is pointing
              * @return the target of the symbolic link
@@ -881,6 +898,7 @@
             public String getLink() {
                 return ftpFile.getLink();
             }
+
             /**
              * get the name of the file
              * @return the name of the file
@@ -888,6 +906,7 @@
             public String getName() {
                 return ftpFile.getName();
             }
+
             /**
              * find out the absolute path of the file
              * @return absolute path as string
@@ -895,6 +914,7 @@
             public String getAbsolutePath() {
                 return getCurpwdPlusFileSep() + ftpFile.getName();
             }
+
             /**
              * find out the relative path assuming that the path used to construct
              * this AntFTPFile was spelled properly with regards to case.
@@ -908,6 +928,7 @@
                 }
                 return null;
             }
+
             /**
              * find out the relative path to the rootPath of the enclosing scanner.
              * this relative path is spelled exactly like on disk,
@@ -934,6 +955,7 @@
                 }
                 return relativePath;
             }
+
             /**
              * get the relative path of this file
              * @param currentPath          base path
@@ -941,18 +963,18 @@
              * @return relative path
              */
             private String getRelativePath(String currentPath, String currentRelativePath) {
-                Vector pathElements = SelectorUtils.tokenizePath(getAbsolutePath(), remoteFileSep);
-                Vector pathElements2 = SelectorUtils.tokenizePath(currentPath, remoteFileSep);
+                List<String> pathElements = SelectorUtils.tokenizePath(getAbsolutePath(), remoteFileSep);
+                List<String> pathElements2 = SelectorUtils.tokenizePath(currentPath, remoteFileSep);
                 String relPath = currentRelativePath;
                 final int size = pathElements.size();
                 for (int pcount = pathElements2.size(); pcount < size; pcount++) {
-                    String currentElement = (String) pathElements.elementAt(pcount);
+                    String currentElement = pathElements.get(pcount);
                     FTPFile[] theFiles = listFiles(currentPath);
                     FTPFile theFile = null;
                     if (theFiles != null) {
                         theFile = getFile(theFiles, currentElement);
                     }
-                    if (!relPath.equals("")) {
+                    if (!"".equals(relPath)) {
                         relPath = relPath + remoteFileSep;
                     }
                     if (theFile == null) {
@@ -970,6 +992,7 @@
                 }
                 return relPath;
             }
+
             /**
              * find a file matching a string in an array of FTPFile.
              * This method will find "alpha" when requested for "ALPHA"
@@ -983,19 +1006,13 @@
                 if (theFiles == null) {
                     return null;
                 }
-                for (int fcount = 0; fcount < theFiles.length; fcount++) {
-                    if (theFiles[fcount] != null) {
-                        if (theFiles[fcount].getName().equals(lastpathelement)) {
-                            return theFiles[fcount];
-                        } else if (!isCaseSensitive()
-                                   && theFiles[fcount].getName().equalsIgnoreCase(
-                                                                                  lastpathelement)) {
-                            return theFiles[fcount];
-                        }
-                    }
-                }
-                return null;
+                Predicate<String> test =
+                    isCaseSensitive() ? lastpathelement::equals
+                        : lastpathelement::equalsIgnoreCase;
+                return Stream.of(theFiles).filter(f -> test.test(f.getName()))
+                    .findFirst().orElse(null);
             }
+
             /**
              * tell if a file is a directory.
              * note that it will return false for symbolic links pointing to directories.
@@ -1004,6 +1021,7 @@
             public boolean isDirectory() {
                 return ftpFile.isDirectory();
             }
+
             /**
              * tell if a file is a symbolic link
              * @return <code>true</code> for symbolic links
@@ -1011,6 +1029,7 @@
             public boolean isSymbolicLink() {
                 return ftpFile.isSymbolicLink();
             }
+
             /**
              * return the attached FTP client object.
              * Warning : this instance is really shared with the enclosing class.
@@ -1027,6 +1046,7 @@
             protected void setCurpwd(String curpwd) {
                 this.curpwd = curpwd;
             }
+
             /**
              * returns the path of the directory containing the AntFTPFile.
              * of the full path of the file itself in case of AntFTPRootFile
@@ -1035,6 +1055,7 @@
             public String getCurpwd() {
                 return curpwd;
             }
+
             /**
              * returns the path of the directory containing the AntFTPFile.
              * of the full path of the file itself in case of AntFTPRootFile
@@ -1046,6 +1067,7 @@
                 return curpwd.endsWith(remoteFileSep) ? curpwd
                     : curpwd + remoteFileSep;
             }
+
             /**
              * find out if a symbolic link is encountered in the relative path of this file
              * from rootPath.
@@ -1066,16 +1088,19 @@
              * Get a string rep of this object.
              * @return a string containing the pwd and the file.
              */
+            @Override
             public String toString() {
                 return "AntFtpFile: " + curpwd + "%" + ftpFile;
             }
         }
+
         /**
          * special class to represent the remote directory itself
          * @since Ant 1.6
          */
         protected class AntFTPRootFile extends AntFTPFile {
             private String remotedir;
+
             /**
              * constructor
              * @param aclient FTP client
@@ -1091,24 +1116,29 @@
                     throw new BuildException(ioe, getLocation());
                 }
             }
+
             /**
              * find the absolute path
              * @return absolute path
              */
+            @Override
             public String getAbsolutePath() {
                 return this.getCurpwd();
             }
+
             /**
              * find out the relative path to root
              * @return empty string
              * @throws BuildException actually never
              * @throws IOException  actually never
              */
+            @Override
             public String getRelativePath() throws BuildException, IOException {
                 return "";
             }
         }
     }
+
     /**
      * check FTPFiles to check whether they function as directories too
      * the FTPFile API seem to make directory and symbolic links incompatible
@@ -1119,13 +1149,13 @@
      * @since ant 1.6
      */
     private boolean isFunctioningAsDirectory(FTPClient ftp, String dir, FTPFile file) {
-        boolean result = false;
-        String currentWorkingDir = null;
         if (file.isDirectory()) {
             return true;
-        } else if (file.isFile()) {
+        }
+        if (file.isFile()) {
             return false;
         }
+        String currentWorkingDir = null;
         try {
             currentWorkingDir = ftp.printWorkingDirectory();
         } catch (IOException ioe) {
@@ -1133,6 +1163,7 @@
                              + " while checking a symlink",
                              Project.MSG_DEBUG);
         }
+        boolean result = false;
         if (currentWorkingDir != null) {
             try {
                 result = ftp.changeWorkingDirectory(file.getLink());
@@ -1149,14 +1180,16 @@
                                      Project.MSG_ERR);
                 } finally {
                     if (!comeback) {
-                        throw new BuildException("could not cd back to " + dir //NOSONAR
-                                                 + " while checking a symlink");
+                        throw new BuildException(
+                            "could not cd back to %s while checking a symlink",
+                            dir);
                     }
                 }
             }
         }
         return result;
     }
+
     /**
      * check FTPFiles to check whether they function as directories too
      * the FTPFile API seem to make directory and symbolic links incompatible
@@ -1169,11 +1202,13 @@
     private boolean isFunctioningAsFile(FTPClient ftp, String dir, FTPFile file) {
         if (file.isDirectory()) {
             return false;
-        } else if (file.isFile()) {
+        }
+        if (file.isFile()) {
             return true;
         }
         return !isFunctioningAsDirectory(ftp, dir, file);
     }
+
     /**
      * Sets the remote directory where files will be placed. This may be a
      * relative or absolute path, and must be in the path syntax expected by
@@ -1185,7 +1220,6 @@
         this.remotedir = dir;
     }
 
-
     /**
      * Sets the FTP server to send files to.
      *
@@ -1392,9 +1426,9 @@
      *
      * @throws BuildException if the action is not a valid action.
      */
+    @Deprecated
     public void setAction(String action) throws BuildException {
-        log("DEPRECATED - The setAction(String) method has been deprecated."
-            + " Use setAction(FTP.Action) instead.");
+        log("DEPRECATED - The setAction(String) method has been deprecated. Use setAction(FTP.Action) instead.");
 
         Action a = new Action();
 
@@ -1463,7 +1497,7 @@
      * @see org.apache.commons.net.ftp.FTPClientConfig
      */
     public void setSystemTypeKey(FTPSystemType systemKey) {
-        if (systemKey != null && !systemKey.getValue().equals("")) {
+        if (systemKey != null && !"".equals(systemKey.getValue())) {
             this.systemTypeKey = systemKey;
             configurationHasBeenSet();
         }
@@ -1476,7 +1510,7 @@
      * @see org.apache.commons.net.ftp.FTPClientConfig
      */
     public void setDefaultDateFormatConfig(String defaultDateFormat) {
-        if (defaultDateFormat != null && !defaultDateFormat.equals("")) {
+        if (defaultDateFormat != null && !"".equals(defaultDateFormat)) {
             this.defaultDateFormatConfig = defaultDateFormat;
             configurationHasBeenSet();
         }
@@ -1489,7 +1523,7 @@
      * @see org.apache.commons.net.ftp.FTPClientConfig
      */
     public void setRecentDateFormatConfig(String recentDateFormat) {
-        if (recentDateFormat != null && !recentDateFormat.equals("")) {
+        if (recentDateFormat != null && !"".equals(recentDateFormat)) {
             this.recentDateFormatConfig = recentDateFormat;
             configurationHasBeenSet();
         }
@@ -1502,7 +1536,7 @@
      * @see org.apache.commons.net.ftp.FTPClientConfig
      */
     public void setServerLanguageCodeConfig(LanguageCode serverLanguageCode) {
-        if (serverLanguageCode != null && !"".equals(serverLanguageCode.getValue())) {
+        if (serverLanguageCode != null && !serverLanguageCode.getValue().isEmpty()) {
             this.serverLanguageCodeConfig = serverLanguageCode;
             configurationHasBeenSet();
         }
@@ -1515,7 +1549,7 @@
      * @see org.apache.commons.net.ftp.FTPClientConfig
      */
     public void setServerTimeZoneConfig(String serverTimeZoneId) {
-        if (serverTimeZoneId != null && !serverTimeZoneId.equals("")) {
+        if (serverTimeZoneId != null && !"".equals(serverTimeZoneId)) {
             this.serverTimeZoneConfig = serverTimeZoneId;
             configurationHasBeenSet();
         }
@@ -1529,7 +1563,7 @@
      * @see org.apache.commons.net.ftp.FTPClientConfig
      */
     public void setShortMonthNamesConfig(String shortMonthNames) {
-        if (shortMonthNames != null && !shortMonthNames.equals("")) {
+        if (shortMonthNames != null && !"".equals(shortMonthNames)) {
             this.shortMonthNamesConfig = shortMonthNames;
             configurationHasBeenSet();
         }
@@ -1553,62 +1587,73 @@
                 int retries = Integer.parseInt(retriesAllowed);
                 if (retries < Retryable.RETRY_FOREVER) {
                     throw new BuildException(
-                                             "Invalid value for retriesAllowed attribute: "
-                                             + retriesAllowed);
-
+                        "Invalid value for retriesAllowed attribute: %s",
+                        retriesAllowed);
                 }
                 this.retriesAllowed = retries;
             } catch (NumberFormatException px) {
                 throw new BuildException(
-                                         "Invalid value for retriesAllowed attribute: "
-                                         + retriesAllowed);
-
+                    "Invalid value for retriesAllowed attribute: %s",
+                    retriesAllowed);
             }
-
         }
     }
+
     /**
      * @return Returns the systemTypeKey.
      */
+    @Override
     public String getSystemTypeKey() {
         return systemTypeKey.getValue();
     }
+
     /**
      * @return Returns the defaultDateFormatConfig.
      */
+    @Override
     public String getDefaultDateFormatConfig() {
         return defaultDateFormatConfig;
     }
+
     /**
      * @return Returns the recentDateFormatConfig.
      */
+    @Override
     public String getRecentDateFormatConfig() {
         return recentDateFormatConfig;
     }
+
     /**
      * @return Returns the serverLanguageCodeConfig.
      */
+    @Override
     public String getServerLanguageCodeConfig() {
         return serverLanguageCodeConfig.getValue();
     }
+
     /**
      * @return Returns the serverTimeZoneConfig.
      */
+    @Override
     public String getServerTimeZoneConfig() {
         return serverTimeZoneConfig;
     }
+
     /**
      * @return Returns the shortMonthNamesConfig.
      */
+    @Override
     public String getShortMonthNamesConfig() {
         return shortMonthNamesConfig;
     }
+
     /**
      * @return Returns the timestampGranularity.
      */
     Granularity getTimestampGranularity() {
         return timestampGranularity;
     }
+
     /**
      * Sets the timestampGranularity attribute
      * @param timestampGranularity The timestampGranularity to set.
@@ -1619,6 +1664,7 @@
         }
         this.timestampGranularity = timestampGranularity;
     }
+
     /**
      * Sets the siteCommand attribute.  This attribute
      * names the command that will be executed if the action
@@ -1628,6 +1674,7 @@
     public void setSiteCommand(String siteCommand) {
         this.siteCommand = siteCommand;
     }
+
     /**
      * Sets the initialSiteCommand attribute.  This attribute
      * names a site command that will be executed immediately
@@ -1666,32 +1713,30 @@
         }
 
         if ((action == LIST_FILES) && (listing == null)) {
-            throw new BuildException("listing attribute must be set for list "
-                                     + "action!");
+            throw new BuildException(
+                "listing attribute must be set for list action!");
         }
 
         if (action == MK_DIR && remotedir == null) {
-            throw new BuildException("remotedir attribute must be set for "
-                                     + "mkdir action!");
+            throw new BuildException(
+                "remotedir attribute must be set for mkdir action!");
         }
 
         if (action == CHMOD && chmod == null) {
-            throw new BuildException("chmod attribute must be set for chmod "
-                                     + "action!");
+            throw new BuildException(
+                "chmod attribute must be set for chmod action!");
         }
         if (action == SITE_CMD && siteCommand == null) {
-            throw new BuildException("sitecommand attribute must be set for site "
-                                     + "action!");
+            throw new BuildException(
+                "sitecommand attribute must be set for site action!");
         }
 
-
         if (this.isConfigurationSet) {
             try {
                 Class.forName("org.apache.commons.net.ftp.FTPClientConfig");
             } catch (ClassNotFoundException e) {
                 throw new BuildException(
-                                         "commons-net.jar >= 1.4.0 is required for at least one"
-                                         + " of the attributes specified.");
+                    "commons-net.jar >= 1.4.0 is required for at least one of the attributes specified.");
             }
         }
     }
@@ -1734,7 +1779,7 @@
             ds.scan();
         }
 
-        String[] dsfiles = null;
+        String[] dsfiles;
         if (action == RM_DIR) {
             dsfiles = ds.getIncludedDirectories();
         } else {
@@ -1744,12 +1789,11 @@
 
         if ((ds.getBasedir() == null)
             && ((action == SEND_FILES) || (action == GET_FILES))) {
-            throw new BuildException("the dir attribute must be set for send "
-                                     + "and get actions");
-        } else {
-            if ((action == SEND_FILES) || (action == GET_FILES)) {
-                dir = ds.getBasedir().getAbsolutePath();
-            }
+            throw new BuildException(
+                "the dir attribute must be set for send and get actions");
+        }
+        if ((action == SEND_FILES) || (action == GET_FILES)) {
+            dir = ds.getBasedir().getAbsolutePath();
         }
 
         // If we are doing a listing, we need the output stream created now.
@@ -1770,11 +1814,7 @@
                 // the trunk does not let itself be removed before the leaves
                 for (int i = dsfiles.length - 1; i >= 0; i--) {
                     final String dsfile = dsfiles[i];
-                    executeRetryable(h, new Retryable() {
-                            public void execute() throws IOException {
-                                rmDir(ftp, dsfile);
-                            }
-                        }, dsfile);
+                    executeRetryable(h, () -> rmDir(ftp, dsfile), dsfile);
                 }
             } else {
                 final BufferedWriter fbw = bw;
@@ -1785,31 +1825,29 @@
                 }
                 for (int i = 0; i < dsfiles.length; i++) {
                     final String dsfile = dsfiles[i];
-                    executeRetryable(h, new Retryable() {
-                            public void execute() throws IOException {
-                                switch (action) {
-                                case SEND_FILES:
-                                    sendFile(ftp, fdir, dsfile);
-                                    break;
-                                case GET_FILES:
-                                    getFile(ftp, fdir, dsfile);
-                                    break;
-                                case DEL_FILES:
-                                    delFile(ftp, dsfile);
-                                    break;
-                                case LIST_FILES:
-                                    listFile(ftp, fbw, dsfile);
-                                    break;
-                                case CHMOD:
-                                    doSiteCommand(ftp, "chmod " + chmod
-                                                  + " " + resolveFile(dsfile));
-                                    transferred++;
-                                    break;
-                                default:
-                                    throw new BuildException("unknown ftp action " + action);
-                                }
-                            }
-                        }, dsfile);
+                    executeRetryable(h, () -> {
+                        switch (action) {
+                            case SEND_FILES:
+                                sendFile(ftp, fdir, dsfile);
+                                break;
+                            case GET_FILES:
+                                getFile(ftp, fdir, dsfile);
+                                break;
+                            case DEL_FILES:
+                                delFile(ftp, dsfile);
+                                break;
+                            case LIST_FILES:
+                                listFile(ftp, fbw, dsfile);
+                                break;
+                            case CHMOD:
+                                doSiteCommand(ftp, "chmod " + chmod
+                                        + " " + resolveFile(dsfile));
+                                transferred++;
+                                break;
+                            default:
+                                throw new BuildException("unknown ftp action " + action);
+                        }
+                    }, dsfile);
                 }
             }
         } finally {
@@ -1819,7 +1857,6 @@
         return dsfiles.length;
     }
 
-
     /**
      * Sends all files specified by the configured filesets to the remote
      * server.
@@ -1834,17 +1871,12 @@
         transferred = 0;
         skipped = 0;
 
-        if (filesets.size() == 0) {
+        if (filesets.isEmpty()) {
             throw new BuildException("at least one fileset must be specified.");
-        } else {
-            // get files from filesets
-            final int size = filesets.size();
-            for (int i = 0; i < size; i++) {
-                FileSet fs = (FileSet) filesets.elementAt(i);
-
-                if (fs != null) {
-                    transferFiles(ftp, fs);
-                }
+        }
+        for (FileSet fs : filesets) {
+            if (fs != null) {
+                transferFiles(ftp, fs);
             }
         }
 
@@ -1856,7 +1888,6 @@
         }
     }
 
-
     /**
      * Correct a file path to correspond to the remote host requirements. This
      * implementation currently assumes that the remote end can handle
@@ -1873,7 +1904,6 @@
                             remoteFileSep.charAt(0));
     }
 
-
     /**
      * Creates all parent directories specified in a complete relative
      * pathname. Attempts to create existing directories will not cause
@@ -1894,7 +1924,7 @@
             return;
         }
 
-        Vector parents = new Vector();
+        List<File> parents = new Vector<>();
         String dirname;
 
         while ((dirname = dir.getParent()) != null) {
@@ -1903,7 +1933,7 @@
                 break;
             }
             dir = checkDir;
-            parents.addElement(dir);
+            parents.add(dir);
         }
 
         // find first non cached dir
@@ -1912,15 +1942,14 @@
         if (i >= 0) {
             String cwd = ftp.printWorkingDirectory();
             String parent = dir.getParent();
-            if (parent != null) {
-                if (!ftp.changeWorkingDirectory(resolveFile(parent))) {
-                    throw new BuildException("could not change to "
-                                             + "directory: " + ftp.getReplyString());
-                }
+            if (parent != null
+                && !ftp.changeWorkingDirectory(resolveFile(parent))) {
+                throw new BuildException("could not change to directory: %s",
+                    ftp.getReplyString());
             }
 
             while (i >= 0) {
-                dir = (File) parents.elementAt(i--);
+                dir = parents.get(i--);
                 // check if dir exists by trying to change into it.
                 if (!ftp.changeWorkingDirectory(dir.getName())) {
                     // could not change to it - try to create it
@@ -1930,8 +1959,9 @@
                         handleMkDirFailure(ftp);
                     }
                     if (!ftp.changeWorkingDirectory(dir.getName())) {
-                        throw new BuildException("could not change to "
-                                                 + "directory: " + ftp.getReplyString());
+                        throw new BuildException(
+                            "could not change to directory: %s",
+                            ftp.getReplyString());
                     }
                 }
                 dirCache.add(dir);
@@ -1952,7 +1982,7 @@
             // create a local temporary file
             FILE_UTILS.createNewFile(tempFile);
             long localTimeStamp = tempFile.lastModified();
-            BufferedInputStream instream = new BufferedInputStream(new FileInputStream(tempFile));
+            BufferedInputStream instream = new BufferedInputStream(Files.newInputStream(tempFile.toPath()));
             ftp.storeFile(tempFile.getName(), instream);
             instream.close();
             boolean success = FTPReply.isPositiveCompletion(ftp.getReplyCode());
@@ -1975,11 +2005,12 @@
         }
         return returnValue;
     }
+
     /**
      *  find a suitable name for local and remote temporary file
      */
     private File findFileName(FTPClient ftp) {
-        FTPFile [] theFiles = null;
+        FTPFile[] theFiles = null;
         final int maxIterations = 1000;
         for (int counter = 1; counter < maxIterations; counter++) {
             File localFile = FILE_UTILS.createTempFile(
@@ -2037,10 +2068,9 @@
                 log("Could not date test remote file: " + remoteFile
                     + "assuming out of date.", Project.MSG_VERBOSE);
                 return false;
-            } else {
-                throw new BuildException("could not date test remote file: "
-                                         + ftp.getReplyString());
             }
+            throw new BuildException("could not date test remote file: %s",
+                ftp.getReplyString());
         }
 
         long remoteTimestamp = files[0].getTimestamp().getTime().getTime();
@@ -2048,38 +2078,36 @@
         long adjustedRemoteTimestamp =
             remoteTimestamp + this.timeDiffMillis + this.granularityMillis;
 
-        StringBuffer msg;
-        synchronized(TIMESTAMP_LOGGING_SDF) {
-            msg = new StringBuffer("   [")
+        StringBuilder msg;
+        synchronized (TIMESTAMP_LOGGING_SDF) {
+            msg = new StringBuilder("   [")
                 .append(TIMESTAMP_LOGGING_SDF.format(new Date(localTimestamp)))
                 .append("] local");
         }
         log(msg.toString(), Project.MSG_VERBOSE);
 
-        synchronized(TIMESTAMP_LOGGING_SDF) {
-            msg = new StringBuffer("   [")
-                .append(TIMESTAMP_LOGGING_SDF.format(new Date(adjustedRemoteTimestamp)))
+        synchronized (TIMESTAMP_LOGGING_SDF) {
+            msg = new StringBuilder("   [")
+                .append(TIMESTAMP_LOGGING_SDF
+                    .format(new Date(adjustedRemoteTimestamp)))
                 .append("] remote");
         }
         if (remoteTimestamp != adjustedRemoteTimestamp) {
-            synchronized(TIMESTAMP_LOGGING_SDF) {
+            synchronized (TIMESTAMP_LOGGING_SDF) {
                 msg.append(" - (raw: ")
-                    .append(TIMESTAMP_LOGGING_SDF.format(new Date(remoteTimestamp)))
+                    .append(
+                        TIMESTAMP_LOGGING_SDF.format(new Date(remoteTimestamp)))
                     .append(")");
             }
         }
         log(msg.toString(), Project.MSG_VERBOSE);
 
-
-
         if (this.action == SEND_FILES) {
             return adjustedRemoteTimestamp >= localTimestamp;
-        } else {
-            return localTimestamp >= adjustedRemoteTimestamp;
         }
+        return localTimestamp >= adjustedRemoteTimestamp;
     }
 
-
     /**
      * Sends a site command to the ftp server
      * @param ftp ftp client
@@ -2089,28 +2117,20 @@
      */
     protected void doSiteCommand(FTPClient ftp, String theCMD)
         throws IOException, BuildException {
-        boolean rc;
-        String[] myReply = null;
 
         log("Doing Site Command: " + theCMD, Project.MSG_VERBOSE);
 
-        rc = ftp.sendSiteCommand(theCMD);
-
-        if (!rc) {
+        if (!ftp.sendSiteCommand(theCMD)) {
             log("Failed to issue Site Command: " + theCMD, Project.MSG_WARN);
         } else {
-
-            myReply = ftp.getReplyStrings();
-
-            for (int x = 0; x < myReply.length; x++) {
-                if (myReply[x] != null && myReply[x].indexOf("200") == -1) {
-                    log(myReply[x], Project.MSG_WARN);
+            for (String reply : ftp.getReplyStrings()) {
+                if (reply != null && reply.indexOf("200") == -1) {
+                    log(reply, Project.MSG_WARN);
                 }
             }
         }
     }
 
-
     /**
      * Sends a single file to the remote host. <code>filename</code> may
      * contain a relative path specification. When this is the case, <code>sendFile</code>
@@ -2143,7 +2163,7 @@
                 log("transferring " + file.getAbsolutePath());
             }
 
-            instream = new BufferedInputStream(new FileInputStream(file));
+            instream = new BufferedInputStream(Files.newInputStream(file.toPath()));
 
             createParents(ftp, filename);
 
@@ -2175,7 +2195,6 @@
         }
     }
 
-
     /**
      * Delete a file from the remote host.
      * @param ftp ftp client
@@ -2255,10 +2274,9 @@
      */
     protected void getFile(FTPClient ftp, String dir, String filename)
         throws IOException, BuildException {
+        File file = getProject().resolveFile(new File(dir, filename).getPath());
         OutputStream outstream = null;
         try {
-            File file = getProject().resolveFile(new File(dir, filename).getPath());
-
             if (newerOnly && isUpToDate(ftp, file, resolveFile(filename))) {
                 return;
             }
@@ -2273,7 +2291,7 @@
             if (!pdir.exists()) {
                 pdir.mkdirs();
             }
-            outstream = new BufferedOutputStream(new FileOutputStream(file));
+            outstream = new BufferedOutputStream(Files.newOutputStream(file.toPath()));
             ftp.retrieveFile(resolveFile(filename), outstream);
 
             if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
@@ -2306,7 +2324,6 @@
         }
     }
 
-
     /**
      * List information about a single file from the remote host. <code>filename</code>
      * may contain a relative path specification. <p>
@@ -2351,41 +2368,41 @@
     protected void makeRemoteDir(FTPClient ftp, String dir)
         throws IOException, BuildException {
         String workingDirectory = ftp.printWorkingDirectory();
+        boolean absolute = dir.startsWith("/");
         if (verbose) {
-            if (dir.startsWith("/") || workingDirectory == null) {
+            if (absolute || workingDirectory == null) {
                 log("Creating directory: " + dir + " in /");
             } else {
                 log("Creating directory: " + dir + " in " + workingDirectory);
             }
         }
-        if (dir.startsWith("/")) {
+        if (absolute) {
             ftp.changeWorkingDirectory("/");
         }
-        String subdir = "";
         StringTokenizer st = new StringTokenizer(dir, "/");
         while (st.hasMoreTokens()) {
-            subdir = st.nextToken();
+            String subdir = st.nextToken();
             log("Checking " + subdir, Project.MSG_DEBUG);
             if (!ftp.changeWorkingDirectory(subdir)) {
-                if (!ftp.makeDirectory(subdir)) {
-                    // codes 521, 550 and 553 can be produced by FTP Servers
-                    //  to indicate that an attempt to create a directory has
-                    //  failed because the directory already exists.
-                    int rc = ftp.getReplyCode();
-                    if (!(ignoreNoncriticalErrors
-                          && (rc == CODE_550 || rc == CODE_553
-                              || rc == CODE_521))) {
-                        throw new BuildException("could not create directory: "
-                                                 + ftp.getReplyString());
-                    }
-                    if (verbose) {
-                        log("Directory already exists");
-                    }
-                } else {
+                if (ftp.makeDirectory(subdir)) {
                     if (verbose) {
                         log("Directory created OK");
                     }
                     ftp.changeWorkingDirectory(subdir);
+                } else {
+                    // codes 521, 550 and 553 can be produced by FTP Servers
+                    //  to indicate that an attempt to create a directory has
+                    //  failed because the directory already exists.
+                    int rc = ftp.getReplyCode();
+                    if (!(ignoreNoncriticalErrors && (rc == CODE_550
+                        || rc == CODE_553 || rc == CODE_521))) {
+                        throw new BuildException(
+                            "could not create directory: %s",
+                            ftp.getReplyString());
+                    }
+                    if (verbose) {
+                        log("Directory already exists");
+                    }
                 }
             }
         }
@@ -2405,8 +2422,8 @@
         int rc = ftp.getReplyCode();
         if (!(ignoreNoncriticalErrors
               && (rc == CODE_550 || rc == CODE_553 || rc == CODE_521))) {
-            throw new BuildException("could not create directory: "
-                                     + ftp.getReplyString());
+            throw new BuildException("could not create directory: %s",
+                ftp.getReplyString());
         }
     }
 
@@ -2416,6 +2433,7 @@
      * @throws BuildException if the task fails or is not configured
      *         correctly.
      */
+    @Override
     public void execute() throws BuildException {
         checkAttributes();
 
@@ -2432,8 +2450,8 @@
             ftp.setRemoteVerificationEnabled(enableRemoteVerification);
             ftp.connect(server, port);
             if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
-                throw new BuildException("FTP connection failed: "
-                                         + ftp.getReplyString());
+                throw new BuildException("FTP connection failed: %s",
+                    ftp.getReplyString());
             }
 
             log("connected", Project.MSG_VERBOSE);
@@ -2449,14 +2467,14 @@
             if (binary) {
                 ftp.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
                 if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
-                    throw new BuildException("could not set transfer type: "
-                                             + ftp.getReplyString());
+                    throw new BuildException("could not set transfer type: %s",
+                        ftp.getReplyString());
                 }
             } else {
                 ftp.setFileType(org.apache.commons.net.ftp.FTP.ASCII_FILE_TYPE);
                 if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
-                    throw new BuildException("could not set transfer type: "
-                                             + ftp.getReplyString());
+                    throw new BuildException("could not set transfer type: %s",
+                        ftp.getReplyString());
                 }
             }
 
@@ -2464,8 +2482,9 @@
                 log("entering passive mode", Project.MSG_VERBOSE);
                 ftp.enterLocalPassiveMode();
                 if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
-                    throw new BuildException("could not enter into passive "
-                                             + "mode: " + ftp.getReplyString());
+                    throw new BuildException(
+                        "could not enter into passive mode: %s",
+                        ftp.getReplyString());
                 }
             }
 
@@ -2474,56 +2493,43 @@
             // E.G. switching between a UNIX file system mode and
             // a legacy file system.
             if (this.initialSiteCommand != null) {
-                RetryHandler h = new RetryHandler(this.retriesAllowed, this);
                 final FTPClient lftp = ftp;
-                executeRetryable(h, new Retryable() {
-                        public void execute() throws IOException {
-                            doSiteCommand(lftp, FTP.this.initialSiteCommand);
-                        }
-                    }, "initial site command: " + this.initialSiteCommand);
+                executeRetryable(new RetryHandler(this.retriesAllowed, this),
+                    () -> doSiteCommand(lftp, FTP.this.initialSiteCommand),
+                    "initial site command: " + this.initialSiteCommand);
             }
 
-
             // For a unix ftp server you can set the default mask for all files
             // created.
 
             if (umask != null) {
-                RetryHandler h = new RetryHandler(this.retriesAllowed, this);
                 final FTPClient lftp = ftp;
-                executeRetryable(h, new Retryable() {
-                        public void execute() throws IOException {
-                            doSiteCommand(lftp, "umask " + umask);
-                        }
-                    }, "umask " + umask);
+                executeRetryable(new RetryHandler(this.retriesAllowed, this),
+                    () -> doSiteCommand(lftp, "umask " + umask),
+                    "umask " + umask);
             }
 
             // If the action is MK_DIR, then the specified remote
             // directory is the directory to create.
 
             if (action == MK_DIR) {
-                RetryHandler h = new RetryHandler(this.retriesAllowed, this);
                 final FTPClient lftp = ftp;
-                executeRetryable(h, new Retryable() {
-                        public void execute() throws IOException {
-                            makeRemoteDir(lftp, remotedir);
-                        }
-                    }, remotedir);
+                executeRetryable(new RetryHandler(this.retriesAllowed, this),
+                    () -> makeRemoteDir(lftp, remotedir), remotedir);
             } else if (action == SITE_CMD) {
-                RetryHandler h = new RetryHandler(this.retriesAllowed, this);
                 final FTPClient lftp = ftp;
-                executeRetryable(h, new Retryable() {
-                        public void execute() throws IOException {
-                            doSiteCommand(lftp, FTP.this.siteCommand);
-                        }
-                    }, "Site Command: " + this.siteCommand);
+                executeRetryable(new RetryHandler(this.retriesAllowed, this),
+                    () -> doSiteCommand(lftp, FTP.this.siteCommand),
+                    "Site Command: " + this.siteCommand);
             } else {
                 if (remotedir != null) {
                     log("changing the remote directory to " + remotedir,
                         Project.MSG_VERBOSE);
                     ftp.changeWorkingDirectory(remotedir);
                     if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
-                        throw new BuildException("could not change remote "
-                                                 + "directory: " + ftp.getReplyString());
+                        throw new BuildException(
+                            "could not change remote directory: %s",
+                            ftp.getReplyString());
                     }
                 }
                 if (newerOnly && timeDiffAuto) {
@@ -2550,7 +2556,6 @@
         }
     }
 
-
     /**
      * an action to perform, one of
      * "send", "put", "recv", "get", "del", "delete", "list", "mkdir", "chmod",
@@ -2563,44 +2568,47 @@
             "chmod", "rmdir", "site"
         };
 
-
         /**
          * Get the valid values
          *
          * @return an array of the valid FTP actions.
          */
+        @Override
         public String[] getValues() {
             return VALID_ACTIONS;
         }
 
-
         /**
          * Get the symbolic equivalent of the action value.
          *
          * @return the SYMBOL representing the given action.
          */
         public int getAction() {
-            String actionL = getValue().toLowerCase(Locale.ENGLISH);
-            if (actionL.equals("send") || actionL.equals("put")) {
+            switch (getValue().toLowerCase(Locale.ENGLISH)) {
+            case "send":
+            case "put":
                 return SEND_FILES;
-            } else if (actionL.equals("recv") || actionL.equals("get")) {
+            case "recv":
+            case "get":
                 return GET_FILES;
-            } else if (actionL.equals("del") || actionL.equals("delete")) {
+            case "del":
+            case "delete":
                 return DEL_FILES;
-            } else if (actionL.equals("list")) {
+            case "list":
                 return LIST_FILES;
-            } else if (actionL.equals("chmod")) {
+            case "chmod":
                 return CHMOD;
-            } else if (actionL.equals("mkdir")) {
+            case "mkdir":
                 return MK_DIR;
-            } else if (actionL.equals("rmdir")) {
+            case "rmdir":
                 return RM_DIR;
-            } else if (actionL.equals("site")) {
+            case "site":
                 return SITE_CMD;
             }
             return SEND_FILES;
         }
     }
+
     /**
      * represents one of the valid timestamp adjustment values
      * recognized by the <code>timestampGranularity</code> attribute.<p>
@@ -2626,9 +2634,11 @@
          * Get the valid values.
          * @return the list of valid Granularity values
          */
+        @Override
         public String[] getValues() {
             return VALID_GRANULARITIES;
         }
+
         /**
          * returns the number of milliseconds associated with
          * the attribute, which can vary in some cases depending
@@ -2648,13 +2658,14 @@
             }
             return 0L;
         }
+
         static final Granularity getDefault() {
             Granularity g = new Granularity();
             g.setValue("");
             return g;
         }
-
     }
+
     /**
      * one of the valid system type keys recognized by the systemTypeKey
      * attribute.
@@ -2671,6 +2682,7 @@
          * Get the valid values.
          * @return the list of valid system types.
          */
+        @Override
         public String[] getValues() {
             return VALID_SYSTEM_TYPES;
         }
@@ -2681,31 +2693,32 @@
             return ftpst;
         }
     }
+
     /**
      * Enumerated class for languages.
      */
     public static class LanguageCode extends EnumeratedAttribute {
 
-
         private static final String[] VALID_LANGUAGE_CODES =
             getValidLanguageCodes();
 
         private static String[] getValidLanguageCodes() {
-            Collection c = FTPClientConfig.getSupportedLanguageCodes();
+            @SuppressWarnings("unchecked")
+            Collection<String> c = FTPClientConfig.getSupportedLanguageCodes();
             String[] ret = new String[c.size() + 1];
             int i = 0;
             ret[i++] = "";
-            for (Iterator it = c.iterator(); it.hasNext(); i++) {
-                ret[i] = (String) it.next();
+            for (String element : c) {
+                ret[i++] = element;
             }
             return ret;
         }
 
-
         /**
          * Return the value values.
          * @return the list of valid language types.
          */
+        @Override
         public String[] getValues() {
             return VALID_LANGUAGE_CODES;
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTask.java
index d53f16d..c96d16a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTask.java
@@ -83,7 +83,7 @@
     private long granularityMillis = 0L;
     private boolean timeDiffAuto = false;
     private int action = SEND_FILES;
-    private Vector filesets = new Vector();
+    private Vector<FileSet> filesets = new Vector<>();
     private String remoteFileSep = "/";
     private int port = DEFAULT_FTP_PORT;
     private boolean skipFailedTransfers = false;
@@ -396,7 +396,7 @@
         filesets.addElement(set);
     }
 
-    public Vector getFilesets() {
+    public Vector<FileSet> getFilesets() {
         return filesets;
     }
 
@@ -415,6 +415,7 @@
      *
      * @throws BuildException if the action is not a valid action.
      */
+    @Deprecated
     public void setAction(String action) throws BuildException {
         log("DEPRECATED - The setAction(String) method has been deprecated."
             + " Use setAction(FTP.Action) instead.");
@@ -503,7 +504,7 @@
      * @see org.apache.commons.net.ftp.FTPClientConfig
      */
     public void setSystemTypeKey(FTPSystemType systemKey) {
-        if (systemKey != null && !systemKey.getValue().equals("")) {
+        if (systemKey != null && !"".equals(systemKey.getValue())) {
             this.systemTypeKey = systemKey;
             configurationHasBeenSet();
         }
@@ -516,7 +517,7 @@
      * @see org.apache.commons.net.ftp.FTPClientConfig
      */
     public void setDefaultDateFormatConfig(String defaultDateFormat) {
-        if (defaultDateFormat != null && !defaultDateFormat.equals("")) {
+        if (defaultDateFormat != null && !"".equals(defaultDateFormat)) {
             this.defaultDateFormatConfig = defaultDateFormat;
             configurationHasBeenSet();
         }
@@ -529,7 +530,7 @@
      * @see org.apache.commons.net.ftp.FTPClientConfig
      */
     public void setRecentDateFormatConfig(String recentDateFormat) {
-        if (recentDateFormat != null && !recentDateFormat.equals("")) {
+        if (recentDateFormat != null && !"".equals(recentDateFormat)) {
             this.recentDateFormatConfig = recentDateFormat;
             configurationHasBeenSet();
         }
@@ -542,7 +543,7 @@
      * @see org.apache.commons.net.ftp.FTPClientConfig
      */
     public void setServerLanguageCodeConfig(String serverLanguageCode) {
-        if (serverLanguageCode != null && !"".equals(serverLanguageCode)) {
+        if (serverLanguageCode != null && !serverLanguageCode.equals("")) {
             this.serverLanguageCodeConfig = serverLanguageCode;
             configurationHasBeenSet();
         }
@@ -555,7 +556,7 @@
      * @see org.apache.commons.net.ftp.FTPClientConfig
      */
     public void setServerTimeZoneConfig(String serverTimeZoneId) {
-        if (serverTimeZoneId != null && !serverTimeZoneId.equals("")) {
+        if (serverTimeZoneId != null && !"".equals(serverTimeZoneId)) {
             this.serverTimeZoneConfig = serverTimeZoneId;
             configurationHasBeenSet();
         }
@@ -569,7 +570,7 @@
      * @see org.apache.commons.net.ftp.FTPClientConfig
      */
     public void setShortMonthNamesConfig(String shortMonthNames) {
-        if (shortMonthNames != null && !shortMonthNames.equals("")) {
+        if (shortMonthNames != null && !"".equals(shortMonthNames)) {
             this.shortMonthNamesConfig = shortMonthNames;
             configurationHasBeenSet();
         }
@@ -593,16 +594,14 @@
                 int retries = Integer.parseInt(retriesAllowed);
                 if (retries < Retryable.RETRY_FOREVER) {
                     throw new BuildException(
-                                             "Invalid value for retriesAllowed attribute: "
-                                             + retriesAllowed);
-
+                        "Invalid value for retriesAllowed attribute: %s",
+                        retriesAllowed);
                 }
                 this.retriesAllowed = retries;
             } catch (NumberFormatException px) {
                 throw new BuildException(
-                                         "Invalid value for retriesAllowed attribute: "
-                                         + retriesAllowed);
-
+                    "Invalid value for retriesAllowed attribute: %s",
+                    retriesAllowed);
             }
 
         }
@@ -615,45 +614,58 @@
     /**
      * @return Returns the systemTypeKey.
      */
+    @Override
     public String getSystemTypeKey() {
         return systemTypeKey.getValue();
     }
+
     /**
      * @return Returns the defaultDateFormatConfig.
      */
+    @Override
     public String getDefaultDateFormatConfig() {
         return defaultDateFormatConfig;
     }
+
     /**
      * @return Returns the recentDateFormatConfig.
      */
+    @Override
     public String getRecentDateFormatConfig() {
         return recentDateFormatConfig;
     }
+
     /**
      * @return Returns the serverLanguageCodeConfig.
      */
+    @Override
     public String getServerLanguageCodeConfig() {
         return serverLanguageCodeConfig;
     }
+
     /**
      * @return Returns the serverTimeZoneConfig.
      */
+    @Override
     public String getServerTimeZoneConfig() {
         return serverTimeZoneConfig;
     }
+
     /**
      * @return Returns the shortMonthNamesConfig.
      */
+    @Override
     public String getShortMonthNamesConfig() {
         return shortMonthNamesConfig;
     }
+
     /**
      * @return Returns the timestampGranularity.
      */
     public Granularity getTimestampGranularity() {
         return timestampGranularity;
     }
+
     /**
      * Sets the timestampGranularity attribute
      * @param timestampGranularity The timestampGranularity to set.
@@ -664,6 +676,7 @@
         }
         this.timestampGranularity = timestampGranularity;
     }
+
     /**
      * Sets the siteCommand attribute.  This attribute
      * names the command that will be executed if the action
@@ -732,32 +745,30 @@
         }
 
         if ((action == LIST_FILES) && (listing == null)) {
-            throw new BuildException("listing attribute must be set for list "
-                                     + "action!");
+            throw new BuildException(
+                "listing attribute must be set for list action!");
         }
 
         if (action == MK_DIR && remotedir == null) {
-            throw new BuildException("remotedir attribute must be set for "
-                                     + "mkdir action!");
+            throw new BuildException(
+                "remotedir attribute must be set for mkdir action!");
         }
 
         if (action == CHMOD && chmod == null) {
-            throw new BuildException("chmod attribute must be set for chmod "
-                                     + "action!");
+            throw new BuildException(
+                "chmod attribute must be set for chmod action!");
         }
         if (action == SITE_CMD && siteCommand == null) {
-            throw new BuildException("sitecommand attribute must be set for site "
-                                     + "action!");
+            throw new BuildException(
+                "sitecommand attribute must be set for site action!");
         }
 
-
         if (this.isConfigurationSet) {
             try {
                 Class.forName("org.apache.commons.net.ftp.FTPClientConfig");
             } catch (ClassNotFoundException e) {
                 throw new BuildException(
-                                         "commons-net.jar >= 1.4.0 is required for at least one"
-                                         + " of the attributes specified.");
+                    "commons-net.jar >= 1.4.0 is required for at least one of the attributes specified.");
             }
         }
     }
@@ -768,6 +779,7 @@
      * @throws BuildException if the task fails or is not configured
      *         correctly.
      */
+    @Override
     public void execute() throws BuildException {
         checkAttributes();
         try {
@@ -815,18 +827,21 @@
         try {
             loader.loadClass("org.apache.commons.net.ftp.FTP"); // sanity check
         } catch (ClassNotFoundException e) {
-            throw new BuildException("The <classpath> for <ftp> must include"
-                                     + " commons-net.jar if not in Ant's own "
-                                     + " classpath", e, task.getLocation());
+            throw new BuildException(
+                "The <classpath> for <ftp> must include commons-net.jar if not in Ant's own classpath",
+                e, task.getLocation());
         }
         try {
-            Class c = loader.loadClass(FTPTaskMirror.class.getName() + "Impl");
+            Class<? extends FTPTaskMirror> c =
+                loader.loadClass(FTPTaskMirror.class.getName() + "Impl")
+                    .asSubclass(FTPTaskMirror.class);
             if (c.getClassLoader() != loader) {
                 throw new BuildException("Overdelegating loader",
-                                         task.getLocation());
+                    task.getLocation());
             }
-            Constructor cons = c.getConstructor(new Class[] {FTPTask.class});
-            return (FTPTaskMirror) cons.newInstance(new Object[] {task});
+            Constructor<? extends FTPTaskMirror> cons =
+                c.getConstructor(FTPTask.class);
+            return cons.newInstance(task);
         } catch (Exception e) {
             throw new BuildException(e, task.getLocation());
         }
@@ -844,17 +859,16 @@
             "chmod", "rmdir", "site"
         };
 
-
         /**
          * Get the valid values
          *
          * @return an array of the valid FTP actions.
          */
+        @Override
         public String[] getValues() {
             return VALID_ACTIONS;
         }
 
-
         /**
          * Get the symbolic equivalent of the action value.
          *
@@ -862,26 +876,31 @@
          */
         public int getAction() {
             String actionL = getValue().toLowerCase(Locale.ENGLISH);
-            if (actionL.equals("send") || actionL.equals("put")) {
+            switch (actionL) {
+            case "send":
+            case "put":
                 return SEND_FILES;
-            } else if (actionL.equals("recv") || actionL.equals("get")) {
+            case "recv":
+            case "get":
                 return GET_FILES;
-            } else if (actionL.equals("del") || actionL.equals("delete")) {
+            case "del":
+            case "delete":
                 return DEL_FILES;
-            } else if (actionL.equals("list")) {
+            case "list":
                 return LIST_FILES;
-            } else if (actionL.equals("chmod")) {
+            case "chmod":
                 return CHMOD;
-            } else if (actionL.equals("mkdir")) {
+            case "mkdir":
                 return MK_DIR;
-            } else if (actionL.equals("rmdir")) {
+            case "rmdir":
                 return RM_DIR;
-            } else if (actionL.equals("site")) {
+            case "site":
                 return SITE_CMD;
             }
             return SEND_FILES;
         }
     }
+
     /**
      * represents one of the valid timestamp adjustment values
      * recognized by the <code>timestampGranularity</code> attribute.<p>
@@ -907,9 +926,11 @@
          * Get the valid values.
          * @return the list of valid Granularity values
          */
+        @Override
         public String[] getValues() {
             return VALID_GRANULARITIES;
         }
+
         /**
          * returns the number of milliseconds associated with
          * the attribute, which can vary in some cases depending
@@ -929,13 +950,14 @@
             }
             return 0L;
         }
+
         static final Granularity getDefault() {
             Granularity g = new Granularity();
             g.setValue("");
             return g;
         }
-
     }
+
     /**
      * one of the valid system type keys recognized by the systemTypeKey
      * attribute.
@@ -947,11 +969,11 @@
             "MVS"
         };
 
-
         /**
          * Get the valid values.
          * @return the list of valid system types.
          */
+        @Override
         public String[] getValues() {
             return VALID_SYSTEM_TYPES;
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskMirrorImpl.java b/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskMirrorImpl.java
index 74ef819..2ad81db 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskMirrorImpl.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskMirrorImpl.java
@@ -21,22 +21,23 @@
 import java.io.BufferedOutputStream;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.file.Files;
 import java.text.SimpleDateFormat;
 import java.util.Date;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.Vector;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 import org.apache.commons.net.ftp.FTPClient;
 import org.apache.commons.net.ftp.FTPFile;
@@ -66,7 +67,7 @@
     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
 
     private final FTPTask task;
-    private Set dirCache = new HashSet();
+    private Set<File> dirCache = new HashSet<>();
     private int transferred = 0;
     private int skipped = 0;
 
@@ -84,6 +85,7 @@
      *
      */
     protected static class FTPFileProxy extends File {
+        private static final long serialVersionUID = 1L;
 
         private final FTPFile file;
         private final String[] parts;
@@ -111,34 +113,34 @@
             parts = FileUtils.getPathStack(completePath);
         }
 
-
         /* (non-Javadoc)
          * @see java.io.File#exists()
          */
+        @Override
         public boolean exists() {
             return true;
         }
 
-
         /* (non-Javadoc)
          * @see java.io.File#getAbsolutePath()
          */
+        @Override
         public String getAbsolutePath() {
             return name;
         }
 
-
         /* (non-Javadoc)
          * @see java.io.File#getName()
          */
+        @Override
         public String getName() {
             return parts.length > 0 ? parts[parts.length - 1] : name;
         }
 
-
         /* (non-Javadoc)
          * @see java.io.File#getParent()
          */
+        @Override
         public String getParent() {
             String result = "";
             for(int i = 0; i < parts.length - 1; i++){
@@ -147,53 +149,53 @@
             return result;
         }
 
-
         /* (non-Javadoc)
          * @see java.io.File#getPath()
          */
+        @Override
         public String getPath() {
             return name;
         }
 
-
         /**
          * FTP files are stored as absolute paths
          * @return true
          */
+        @Override
         public boolean isAbsolute() {
             return true;
         }
 
-
         /* (non-Javadoc)
          * @see java.io.File#isDirectory()
          */
+        @Override
         public boolean isDirectory() {
             return file == null;
         }
 
-
         /* (non-Javadoc)
          * @see java.io.File#isFile()
          */
+        @Override
         public boolean isFile() {
             return file != null;
         }
 
-
         /**
          * FTP files cannot be hidden
          *
          * @return  false
          */
+        @Override
         public boolean isHidden() {
             return false;
         }
 
-
         /* (non-Javadoc)
          * @see java.io.File#lastModified()
          */
+        @Override
         public long lastModified() {
             if (file != null) {
                 return file.getTimestamp().getTimeInMillis();
@@ -201,10 +203,10 @@
             return 0;
         }
 
-
         /* (non-Javadoc)
          * @see java.io.File#length()
          */
+        @Override
         public long length() {
             if (file != null) {
                 return file.getSize();
@@ -245,11 +247,11 @@
             this.setFollowSymlinks(false);
         }
 
-
         /**
          * scans the remote directory,
          * storing internally the included files, directories, ...
          */
+        @Override
         public void scan() {
             if (includes == null) {
                 // No includes supplied, so set it to 'matches all'
@@ -260,12 +262,12 @@
                 excludes = new String[0];
             }
 
-            filesIncluded = new VectorSet();
-            filesNotIncluded = new Vector();
-            filesExcluded = new VectorSet();
-            dirsIncluded = new VectorSet();
-            dirsNotIncluded = new Vector();
-            dirsExcluded = new VectorSet();
+            filesIncluded = new VectorSet<>();
+            filesNotIncluded = new Vector<>();
+            filesExcluded = new VectorSet<>();
+            dirsIncluded = new VectorSet<>();
+            dirsNotIncluded = new Vector<>();
+            dirsExcluded = new VectorSet<>();
 
             try {
                 String cwd = ftp.printWorkingDirectory();
@@ -280,7 +282,6 @@
             }
         }
 
-
         /**
          * this routine is actually checking all the include patterns in
          * order to avoid scanning everything under base dir
@@ -288,7 +289,7 @@
          */
         private void checkIncludePatterns() {
 
-            Hashtable newroots = new Hashtable();
+            Map<String, String> newroots = new Hashtable<>();
             // put in the newroots vector the include patterns without
             // wildcard tokens
             for (int icounter = 0; icounter < includes.length; icounter++) {
@@ -313,75 +314,73 @@
             } else {
                 // only scan directories that can include matched files or
                 // directories
-                Enumeration enum2 = newroots.keys();
+                newroots.forEach(
+                    (k, v) -> scanRoot(new AntFTPFile(baseFTPFile, k), v));
+            }
+        }
 
-                while (enum2.hasMoreElements()) {
-                    String currentelement = (String) enum2.nextElement();
-                    String originalpattern = (String) newroots.get(currentelement);
-                    AntFTPFile myfile = new AntFTPFile(baseFTPFile, currentelement);
-                    boolean isOK = true;
-                    boolean traversesSymlinks = false;
-                    String path = null;
+        private void scanRoot(AntFTPFile myfile, String originalpattern) {
+            String currentelement;
+            boolean isOK = true;
+            boolean traversesSymlinks = false;
+            String path = null;
 
-                    if (myfile.exists()) {
-                        forceRemoteSensitivityCheck();
-                        if (remoteSensitivityChecked
-                            && remoteSystemCaseSensitive && isFollowSymlinks()) {
-                            // cool case,
-                            //we do not need to scan all the subdirs in the relative path
-                            path = myfile.getFastRelativePath();
-                        } else {
-                            // may be on a case insensitive file system.  We want
-                            // the results to show what's really on the disk, so
-                            // we need to double check.
-                            try {
-                                path = myfile.getRelativePath();
-                                traversesSymlinks = myfile.isTraverseSymlinks();
-                            } catch (IOException be) {
-                                throw new BuildException(be, task.getLocation());
-                            } catch (BuildException be) {
-                                isOK = false;
-                            }
-                        }
-                    } else {
+            if (myfile.exists()) {
+                forceRemoteSensitivityCheck();
+                if (remoteSensitivityChecked
+                    && remoteSystemCaseSensitive && isFollowSymlinks()) {
+                    // cool case,
+                    //we do not need to scan all the subdirs in the relative path
+                    path = myfile.getFastRelativePath();
+                } else {
+                    // may be on a case insensitive file system.  We want
+                    // the results to show what's really on the disk, so
+                    // we need to double check.
+                    try {
+                        path = myfile.getRelativePath();
+                        traversesSymlinks = myfile.isTraverseSymlinks();
+                    } catch (IOException be) {
+                        throw new BuildException(be, task.getLocation());
+                    } catch (BuildException be) {
                         isOK = false;
                     }
-                    if (isOK) {
-                        currentelement = path.replace(task.getSeparator().charAt(0), File.separatorChar);
-                        if (!isFollowSymlinks()
-                            && traversesSymlinks) {
-                            continue;
-                        }
+                }
+            } else {
+                isOK = false;
+            }
+            if (isOK) {
+                currentelement = path.replace(task.getSeparator().charAt(0), File.separatorChar);
+                if (!isFollowSymlinks()
+                    && traversesSymlinks) {
+                    return;
+                }
 
-                        if (myfile.isDirectory()) {
-                            if (isIncluded(currentelement)
-                                && currentelement.length() > 0) {
-                                accountForIncludedDir(currentelement, myfile, true);
-                            }  else {
-                                if (currentelement.length() > 0) {
-                                    if (currentelement.charAt(currentelement
-                                                              .length() - 1)
-                                        != File.separatorChar) {
-                                        currentelement =
-                                            currentelement + File.separatorChar;
-                                    }
-                                }
-                                scandir(myfile.getAbsolutePath(), currentelement, true);
-                            }
-                        } else {
-                            if (isCaseSensitive
-                                && originalpattern.equals(currentelement)) {
-                                accountForIncludedFile(currentelement);
-                            } else if (!isCaseSensitive
-                                       && originalpattern
-                                       .equalsIgnoreCase(currentelement)) {
-                                accountForIncludedFile(currentelement);
+                if (myfile.isDirectory()) {
+                    if (isIncluded(currentelement)
+                        && currentelement.length() > 0) {
+                        accountForIncludedDir(currentelement, myfile, true);
+                    }  else {
+                        if (currentelement.length() > 0) {
+                            if (currentelement.charAt(currentelement
+                                                      .length() - 1)
+                                != File.separatorChar) {
+                                currentelement =
+                                    currentelement + File.separatorChar;
                             }
                         }
+                        scandir(myfile.getAbsolutePath(), currentelement, true);
                     }
+                } else if (isCaseSensitive
+                    && originalpattern.equals(currentelement)) {
+                    accountForIncludedFile(currentelement);
+                } else if (!isCaseSensitive
+                           && originalpattern
+                           .equalsIgnoreCase(currentelement)) {
+                    accountForIncludedFile(currentelement);
                 }
             }
         }
+
         /**
          * scans a particular directory. populates the scannedDirs cache.
          *
@@ -399,8 +398,8 @@
                 if (!ftp.changeWorkingDirectory(dir)) {
                     return;
                 }
-                String completePath = null;
-                if (!vpath.equals("")) {
+                String completePath;
+                if (!"".equals(vpath)) {
                     completePath = rootPath + task.getSeparator()
                         + vpath.replace(File.separatorChar, task.getSeparator().charAt(0));
                 } else {
@@ -415,8 +414,8 @@
                 for (int i = 0; i < newfiles.length; i++) {
                     FTPFile file = newfiles[i];
                     if (file != null
-                        && !file.getName().equals(".")
-                        && !file.getName().equals("..")) {
+                        && !".".equals(file.getName())
+                        && !"..".equals(file.getName())) {
                         String name = vpath + file.getName();
                         scannedDirs.put(name, new FTPFileProxy(file));
                         if (isFunctioningAsDirectory(ftp, dir, file)) {
@@ -463,7 +462,7 @@
 
                 if (isIncluded(name)) {
                     if (!isExcluded(name)
-                        && isSelected(name, (File) scannedDirs.get(name))) {
+                        && isSelected(name, scannedDirs.get(name))) {
                         filesIncluded.addElement(name);
                     } else {
                         filesExcluded.addElement(name);
@@ -520,19 +519,21 @@
                 }
             }
         }
+
         /**
          * temporary table to speed up the various scanning methods below
          *
          * @since Ant 1.6
          */
-        private Map fileListMap = new HashMap();
+        private Map<String, FTPFile[]> fileListMap = new HashMap<>();
+
         /**
          * List of all scanned directories.
          *
          * @since Ant 1.6
          */
 
-        private Map scannedDirs = new HashMap();
+        private Map<String, FTPFileProxy> scannedDirs = new HashMap<>();
 
         /**
          * Has the directory with the given path relative to the base
@@ -553,6 +554,7 @@
             fileListMap.clear();
             scannedDirs.clear();
         }
+
         /**
          * list the files present in one directory.
          * @param directory full path on the remote side
@@ -564,8 +566,7 @@
             String currentPath = directory;
             if (changedir) {
                 try {
-                    boolean result = ftp.changeWorkingDirectory(directory);
-                    if (!result) {
+                    if (!ftp.changeWorkingDirectory(directory)) {
                         return null;
                     }
                     currentPath = ftp.printWorkingDirectory();
@@ -575,9 +576,9 @@
             }
             if (fileListMap.containsKey(currentPath)) {
                 task.log("filelist map used in listing files", Project.MSG_DEBUG);
-                return ((FTPFile[]) fileListMap.get(currentPath));
+                return fileListMap.get(currentPath);
             }
-            FTPFile[] result = null;
+            FTPFile[] result;
             try {
                 result = ftp.listFiles();
             } catch (IOException ioe) {
@@ -599,6 +600,7 @@
                 }
             }
         }
+
         /**
          * cd into one directory and
          * list the files present in one directory.
@@ -608,6 +610,7 @@
         public FTPFile[] listFiles(String directory) {
             return listFiles(directory, true);
         }
+
         private void checkRemoteSensitivity(FTPFile[] array, String directory) {
             if (array == null) {
                 return;
@@ -616,8 +619,8 @@
             String target = null;
             for (int icounter = 0; icounter < array.length; icounter++) {
                 if (array[icounter] != null && array[icounter].isDirectory()) {
-                    if (!array[icounter].getName().equals(".")
-                        && !array[icounter].getName().equals("..")) {
+                    if (!".".equals(array[icounter].getName())
+                        && !"..".equals(array[icounter].getName())) {
                         candidateFound = true;
                         target = fiddleName(array[icounter].getName());
                         task.log("will try to cd to "
@@ -657,8 +660,9 @@
                 remoteSensitivityChecked = true;
             }
         }
+
         private String fiddleName(String origin) {
-            StringBuffer result = new StringBuffer();
+            StringBuilder result = new StringBuilder();
             for (int icounter = 0; icounter < origin.length(); icounter++) {
                 if (Character.isLowerCase(origin.charAt(icounter))) {
                     result.append(Character.toUpperCase(origin.charAt(icounter)));
@@ -670,6 +674,7 @@
             }
             return result.toString();
         }
+
         /**
          * an AntFTPFile is a representation of a remote file
          * @since Ant 1.6
@@ -694,6 +699,7 @@
             private boolean relativePathCalculated = false;
             private boolean traversesSymlinks = false;
             private String relativePath = "";
+
             /**
              * constructor
              * @param client ftp client variable
@@ -705,6 +711,7 @@
                 this.ftpFile = ftpFile;
                 this.curpwd = curpwd;
             }
+
             /**
              * other constructor
              * @param parent the parent file
@@ -713,7 +720,7 @@
             public AntFTPFile(AntFTPFile parent, String path) {
                 this.parent = parent;
                 this.client = parent.client;
-                Vector pathElements = SelectorUtils.tokenizePath(path);
+                List<String> pathElements = SelectorUtils.tokenizePath(path);
                 try {
                     boolean result = this.client.changeWorkingDirectory(parent.getAbsolutePath());
                     //this should not happen, except if parent has been deleted by another process
@@ -722,35 +729,35 @@
                     }
                     this.curpwd = parent.getAbsolutePath();
                 } catch (IOException ioe) {
-                    throw new BuildException("could not change working dir to "
-                                             + parent.curpwd);
+                    throw new BuildException(
+                        "could not change working dir to %s", parent.curpwd);
                 }
                 final int size = pathElements.size();
                 for (int fcount = 0; fcount < size - 1; fcount++) {
-                    String currentPathElement = (String) pathElements.elementAt(fcount);
+                    String currentPathElement = pathElements.get(fcount);
                     try {
-                        boolean result = this.client.changeWorkingDirectory(currentPathElement);
-                        if (!result && !isCaseSensitive()
-                            && (remoteSystemCaseSensitive || !remoteSensitivityChecked)) {
-                            currentPathElement = findPathElementCaseUnsensitive(this.curpwd,
-                                                                                currentPathElement);
-                            if (currentPathElement == null) {
-                                return;
+                        if (!this.client.changeWorkingDirectory(currentPathElement)) {
+                            if (!isCaseSensitive() && (remoteSystemCaseSensitive
+                                || !remoteSensitivityChecked)) {
+                                currentPathElement =
+                                    findPathElementCaseUnsensitive(this.curpwd,
+                                        currentPathElement);
+                                if (currentPathElement == null) {
+                                    return;
+                                }
                             }
-                        } else if (!result) {
                             return;
                         }
-                        this.curpwd = getCurpwdPlusFileSep()
-                            + currentPathElement;
+                        this.curpwd =
+                            getCurpwdPlusFileSep() + currentPathElement;
                     } catch (IOException ioe) {
-                        throw new BuildException("could not change working dir to "
-                                                 + (String) pathElements.elementAt(fcount)
-                                                 + " from " + this.curpwd);
+                        throw new BuildException(
+                            "could not change working dir to %s from %s",
+                            currentPathElement, this.curpwd);
                     }
-
                 }
-                String lastpathelement = (String) pathElements.elementAt(size - 1);
-                FTPFile [] theFiles = listFiles(this.curpwd);
+                String lastpathelement = pathElements.get(size - 1);
+                FTPFile[] theFiles = listFiles(this.curpwd);
                 this.ftpFile = getFile(theFiles, lastpathelement);
             }
             /**
@@ -767,10 +774,10 @@
                 if (theFiles == null) {
                     return null;
                 }
-                for (int icounter = 0; icounter < theFiles.length; icounter++) {
-                    if (theFiles[icounter] != null
-                        && theFiles[icounter].getName().equalsIgnoreCase(soughtPathElement)) {
-                        return theFiles[icounter].getName();
+                for (FTPFile f : theFiles) {
+                    if (f != null
+                        && f.getName().equalsIgnoreCase(soughtPathElement)) {
+                        return f.getName();
                     }
                 }
                 return null;
@@ -780,8 +787,9 @@
              * @return  true if the file exists
              */
             public boolean exists() {
-                return (ftpFile != null);
+                return ftpFile != null;
             }
+
             /**
              * if the file is a symbolic link, find out to what it is pointing
              * @return the target of the symbolic link
@@ -789,6 +797,7 @@
             public String getLink() {
                 return ftpFile.getLink();
             }
+
             /**
              * get the name of the file
              * @return the name of the file
@@ -796,6 +805,7 @@
             public String getName() {
                 return ftpFile.getName();
             }
+
             /**
              * find out the absolute path of the file
              * @return absolute path as string
@@ -803,6 +813,7 @@
             public String getAbsolutePath() {
                 return getCurpwdPlusFileSep() + ftpFile.getName();
             }
+
             /**
              * find out the relative path assuming that the path used to construct
              * this AntFTPFile was spelled properly with regards to case.
@@ -817,6 +828,7 @@
                 }
                 return null;
             }
+
             /**
              * find out the relative path to the rootPath of the enclosing scanner.
              * this relative path is spelled exactly like on disk,
@@ -843,6 +855,7 @@
                 }
                 return relativePath;
             }
+
             /**
              * get the relative path of this file
              * @param currentPath          base path
@@ -850,19 +863,20 @@
              * @return relative path
              */
             private String getRelativePath(String currentPath, String currentRelativePath) {
-                Vector pathElements = SelectorUtils.tokenizePath(getAbsolutePath(), task.getSeparator());
-                Vector pathElements2 = SelectorUtils.tokenizePath(currentPath,
-                                                                  task.getSeparator());
+                List<String> pathElements = SelectorUtils
+                    .tokenizePath(getAbsolutePath(), task.getSeparator());
+                List<String> pathElements2 = SelectorUtils
+                    .tokenizePath(currentPath, task.getSeparator());
                 String relPath = currentRelativePath;
                 final int size = pathElements.size();
                 for (int pcount = pathElements2.size(); pcount < size; pcount++) {
-                    String currentElement = (String) pathElements.elementAt(pcount);
+                    String currentElement = pathElements.get(pcount);
                     FTPFile[] theFiles = listFiles(currentPath);
                     FTPFile theFile = null;
                     if (theFiles != null) {
                         theFile = getFile(theFiles, currentElement);
                     }
-                    if (!relPath.equals("")) {
+                    if (!"".equals(relPath)) {
                         relPath = relPath + task.getSeparator();
                     }
                     if (theFile == null) {
@@ -882,6 +896,7 @@
                 }
                 return relPath;
             }
+
             /**
              * find a file matching a string in an array of FTPFile.
              * This method will find "alpha" when requested for "ALPHA"
@@ -895,19 +910,13 @@
                 if (theFiles == null) {
                     return null;
                 }
-                for (int fcount = 0; fcount < theFiles.length; fcount++) {
-                    if (theFiles[fcount] != null) {
-                        if (theFiles[fcount].getName().equals(lastpathelement)) {
-                            return theFiles[fcount];
-                        } else if (!isCaseSensitive()
-                                   && theFiles[fcount].getName().equalsIgnoreCase(
-                                                                                  lastpathelement)) {
-                            return theFiles[fcount];
-                        }
-                    }
-                }
-                return null;
+                Predicate<String> test =
+                    isCaseSensitive() ? lastpathelement::equals
+                        : lastpathelement::equalsIgnoreCase;
+                return Stream.of(theFiles).filter(f -> test.test(f.getName()))
+                    .findFirst().orElse(null);
             }
+
             /**
              * tell if a file is a directory.
              * note that it will return false for symbolic links pointing to directories.
@@ -916,6 +925,7 @@
             public boolean isDirectory() {
                 return ftpFile.isDirectory();
             }
+
             /**
              * tell if a file is a symbolic link
              * @return <code>true</code> for symbolic links
@@ -923,6 +933,7 @@
             public boolean isSymbolicLink() {
                 return ftpFile.isSymbolicLink();
             }
+
             /**
              * return the attached FTP client object.
              * Warning : this instance is really shared with the enclosing class.
@@ -939,6 +950,7 @@
             protected void setCurpwd(String curpwd) {
                 this.curpwd = curpwd;
             }
+
             /**
              * returns the path of the directory containing the AntFTPFile.
              * of the full path of the file itself in case of AntFTPRootFile
@@ -947,6 +959,7 @@
             public String getCurpwd() {
                 return curpwd;
             }
+
             /**
              * returns the path of the directory containing the AntFTPFile.
              * of the full path of the file itself in case of AntFTPRootFile
@@ -958,6 +971,7 @@
                 String sep = task.getSeparator();
                 return curpwd.endsWith(sep) ? curpwd : curpwd + sep;
             }
+
             /**
              * find out if a symbolic link is encountered in the relative path of this file
              * from rootPath.
@@ -978,16 +992,19 @@
              * Get a string rep of this object.
              * @return a string containing the pwd and the file.
              */
+            @Override
             public String toString() {
                 return "AntFtpFile: " + curpwd + "%" + ftpFile;
             }
         }
+
         /**
          * special class to represent the remote directory itself
          * @since Ant 1.6
          */
         protected class AntFTPRootFile extends AntFTPFile {
             private String remotedir;
+
             /**
              * constructor
              * @param aclient FTP client
@@ -1003,24 +1020,29 @@
                     throw new BuildException(ioe, task.getLocation());
                 }
             }
+
             /**
              * find the absolute path
              * @return absolute path
              */
+            @Override
             public String getAbsolutePath() {
                 return this.getCurpwd();
             }
+
             /**
              * find out the relative path to root
              * @return empty string
              * @throws BuildException actually never
              * @throws IOException  actually never
              */
+            @Override
             public String getRelativePath() throws BuildException, IOException {
                 return "";
             }
         }
     }
+
     /**
      * check FTPFiles to check whether they function as directories too
      * the FTPFile API seem to make directory and symbolic links incompatible
@@ -1035,7 +1057,8 @@
         String currentWorkingDir = null;
         if (file.isDirectory()) {
             return true;
-        } else if (file.isFile()) {
+        }
+        if (file.isFile()) {
             return false;
         }
         try {
@@ -1061,14 +1084,16 @@
                                           Project.MSG_ERR);
                 } finally {
                     if (!comeback) {
-                        throw new BuildException("could not cd back to " + dir //NOSONAR
-                                                 + " while checking a symlink");
+                        throw new BuildException(
+                            "could not cd back to %s while checking a symlink",
+                            dir);
                     }
                 }
             }
         }
         return result;
     }
+
     /**
      * check FTPFiles to check whether they function as directories too
      * the FTPFile API seem to make directory and symbolic links incompatible
@@ -1081,7 +1106,8 @@
     private boolean isFunctioningAsFile(FTPClient ftp, String dir, FTPFile file) {
         if (file.isDirectory()) {
             return false;
-        } else if (file.isFile()) {
+        }
+        if (file.isFile()) {
             return true;
         }
         return !isFunctioningAsDirectory(ftp, dir, file);
@@ -1100,7 +1126,6 @@
         h.execute(r, descr);
     }
 
-
     /**
      * For each file in the fileset, do the appropriate action: send, get,
      * delete, or list.
@@ -1131,16 +1156,17 @@
         } else {
             dsfiles = ds.getIncludedFiles();
         }
-        String dir = null;
 
         if ((ds.getBasedir() == null)
-            && ((task.getAction() == FTPTask.SEND_FILES) || (task.getAction() == FTPTask.GET_FILES))) {
-            throw new BuildException("the dir attribute must be set for send "
-                                     + "and get actions");
-        } else {
-            if ((task.getAction() == FTPTask.SEND_FILES) || (task.getAction() == FTPTask.GET_FILES)) {
-                dir = ds.getBasedir().getAbsolutePath();
-            }
+            && ((task.getAction() == FTPTask.SEND_FILES)
+                || (task.getAction() == FTPTask.GET_FILES))) {
+            throw new BuildException(
+                "the dir attribute must be set for send and get actions");
+        }
+        String dir = null;
+        if ((task.getAction() == FTPTask.SEND_FILES)
+            || (task.getAction() == FTPTask.GET_FILES)) {
+            dir = ds.getBasedir().getAbsolutePath();
         }
 
         // If we are doing a listing, we need the output stream created now.
@@ -1161,11 +1187,7 @@
                 // the trunk does not let itself be removed before the leaves
                 for (int i = dsfiles.length - 1; i >= 0; i--) {
                     final String dsfile = dsfiles[i];
-                    executeRetryable(h, new Retryable() {
-                            public void execute() throws IOException {
-                                rmDir(ftp, dsfile);
-                            }
-                        }, dsfile);
+                    executeRetryable(h, () -> rmDir(ftp, dsfile), dsfile);
                 }
             } else {
                 final BufferedWriter fbw = bw;
@@ -1176,30 +1198,28 @@
                 }
                 for (int i = 0; i < dsfiles.length; i++) {
                     final String dsfile = dsfiles[i];
-                    executeRetryable(h, new Retryable() {
-                        public void execute() throws IOException {
-                            switch (task.getAction()) {
-                                case FTPTask.SEND_FILES:
-                                    sendFile(ftp, fdir, dsfile);
-                                    break;
-                                case FTPTask.GET_FILES:
-                                    getFile(ftp, fdir, dsfile);
-                                    break;
-                                case FTPTask.DEL_FILES:
-                                    delFile(ftp, dsfile);
-                                    break;
-                                case FTPTask.LIST_FILES:
-                                    listFile(ftp, fbw, dsfile);
-                                    break;
-                                case FTPTask.CHMOD:
-                                    doSiteCommand(ftp, "chmod " + task.getChmod() + " "
-                                                  + resolveFile(dsfile));
-                                    transferred++;
-                                    break;
-                                default:
-                                    throw new BuildException("unknown ftp action "
-                                                             + task.getAction());
-                            }
+                    executeRetryable(h, () -> {
+                        switch (task.getAction()) {
+                            case FTPTask.SEND_FILES:
+                                sendFile(ftp, fdir, dsfile);
+                                break;
+                            case FTPTask.GET_FILES:
+                                getFile(ftp, fdir, dsfile);
+                                break;
+                            case FTPTask.DEL_FILES:
+                                delFile(ftp, dsfile);
+                                break;
+                            case FTPTask.LIST_FILES:
+                                listFile(ftp, fbw, dsfile);
+                                break;
+                            case FTPTask.CHMOD:
+                                doSiteCommand(ftp, "chmod " + task.getChmod() + " "
+                                        + resolveFile(dsfile));
+                                transferred++;
+                                break;
+                            default:
+                                throw new BuildException("unknown ftp action %s",
+                                        task.getAction());
                         }
                     }, dsfile);
                 }
@@ -1228,29 +1248,26 @@
         transferred = 0;
         skipped = 0;
 
-        if (task.getFilesets().size() == 0) {
+        if (task.getFilesets().isEmpty()) {
             throw new BuildException("at least one fileset must be specified.");
-        } else {
-            // get files from filesets
-            final int size = task.getFilesets().size();
-            for (int i = 0; i < size; i++) {
-                FileSet fs = (FileSet) task.getFilesets().elementAt(i);
-
-                if (fs != null) {
-                    transferFiles(ftp, fs);
-                }
+        }
+        // get files from filesets
+        for (FileSet fs : task.getFilesets()) {
+            if (fs != null) {
+                transferFiles(ftp, fs);
             }
         }
-
-        task.log(transferred + " " + FTPTask.ACTION_TARGET_STRS[task.getAction()] + " "
-                 + FTPTask.COMPLETED_ACTION_STRS[task.getAction()]);
+        task.log(
+            transferred + " " + FTPTask.ACTION_TARGET_STRS[task.getAction()]
+                + " " + FTPTask.COMPLETED_ACTION_STRS[task.getAction()]);
         if (skipped != 0) {
-            task.log(skipped + " " + FTPTask.ACTION_TARGET_STRS[task.getAction()]
-                     + " were not successfully " + FTPTask.COMPLETED_ACTION_STRS[task.getAction()]);
+            task.log(
+                skipped + " " + FTPTask.ACTION_TARGET_STRS[task.getAction()]
+                    + " were not successfully "
+                    + FTPTask.COMPLETED_ACTION_STRS[task.getAction()]);
         }
     }
 
-
     /**
      * Correct a file path to correspond to the remote host requirements. This
      * implementation currently assumes that the remote end can handle
@@ -1267,7 +1284,6 @@
                             task.getSeparator().charAt(0));
     }
 
-
     /**
      * Creates all parent directories specified in a complete relative
      * pathname. Attempts to create existing directories will not cause
@@ -1288,7 +1304,7 @@
             return;
         }
 
-        Vector parents = new Vector();
+        Vector<File> parents = new Vector<>();
         String dirname;
 
         while ((dirname = dir.getParent()) != null) {
@@ -1308,13 +1324,14 @@
             String parent = dir.getParent();
             if (parent != null) {
                 if (!ftp.changeWorkingDirectory(resolveFile(parent))) {
-                    throw new BuildException("could not change to "
-                                             + "directory: " + ftp.getReplyString());
+                    throw new BuildException(
+                        "could not change to directory: %s",
+                        ftp.getReplyString());
                 }
             }
 
             while (i >= 0) {
-                dir = (File) parents.elementAt(i--);
+                dir = parents.elementAt(i--);
                 // check if dir exists by trying to change into it.
                 if (!ftp.changeWorkingDirectory(dir.getName())) {
                     // could not change to it - try to create it
@@ -1324,8 +1341,9 @@
                         handleMkDirFailure(ftp);
                     }
                     if (!ftp.changeWorkingDirectory(dir.getName())) {
-                        throw new BuildException("could not change to "
-                                                 + "directory: " + ftp.getReplyString());
+                        throw new BuildException(
+                            "could not change to directory: %s",
+                            ftp.getReplyString());
                     }
                 }
                 dirCache.add(dir);
@@ -1333,6 +1351,7 @@
             ftp.changeWorkingDirectory(cwd);
         }
     }
+
     /**
      * auto find the time difference between local and remote
      * @param ftp handle to ftp client
@@ -1346,11 +1365,10 @@
             // create a local temporary file
             FILE_UTILS.createNewFile(tempFile);
             long localTimeStamp = tempFile.lastModified();
-            BufferedInputStream instream = new BufferedInputStream(new FileInputStream(tempFile));
+            BufferedInputStream instream = new BufferedInputStream(Files.newInputStream(tempFile.toPath()));
             ftp.storeFile(tempFile.getName(), instream);
             instream.close();
-            boolean success = FTPReply.isPositiveCompletion(ftp.getReplyCode());
-            if (success) {
+            if (FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
                 FTPFile [] ftpFiles = ftp.listFiles(tempFile.getName());
                 if (ftpFiles.length == 1) {
                     long remoteTimeStamp = ftpFiles[0].getTimestamp().getTime().getTime();
@@ -1369,11 +1387,12 @@
         }
         return returnValue;
     }
+
     /**
      *  find a suitable name for local and remote temporary file
      */
     private File findFileName(FTPClient ftp) {
-        FTPFile [] theFiles = null;
+        FTPFile[] theFiles = null;
         final int maxIterations = 1000;
         for (int counter = 1; counter < maxIterations; counter++) {
             File localFile = FILE_UTILS.createTempFile(
@@ -1431,10 +1450,9 @@
                 task.log("Could not date test remote file: " + remoteFile
                          + "assuming out of date.", Project.MSG_VERBOSE);
                 return false;
-            } else {
-                throw new BuildException("could not date test remote file: "
-                                         + ftp.getReplyString());
             }
+            throw new BuildException("could not date test remote file: %s",
+                ftp.getReplyString());
         }
 
         long remoteTimestamp = files[0].getTimestamp().getTime().getTime();
@@ -1442,16 +1460,16 @@
         long adjustedRemoteTimestamp = remoteTimestamp + task.getTimeDiffMillis()
             + task.getGranularityMillis();
 
-        StringBuffer msg;
+        StringBuilder msg;
         synchronized (TIMESTAMP_LOGGING_SDF) {
-            msg = new StringBuffer("   [")
+            msg = new StringBuilder("   [")
                 .append(TIMESTAMP_LOGGING_SDF.format(new Date(localTimestamp)))
                 .append("] local");
         }
         task.log(msg.toString(), Project.MSG_VERBOSE);
 
         synchronized (TIMESTAMP_LOGGING_SDF) {
-            msg = new StringBuffer("   [")
+            msg = new StringBuilder("   [")
                 .append(TIMESTAMP_LOGGING_SDF.format(new Date(adjustedRemoteTimestamp)))
                 .append("] remote");
         }
@@ -1466,9 +1484,8 @@
 
         if (task.getAction() == FTPTask.SEND_FILES) {
             return adjustedRemoteTimestamp >= localTimestamp;
-        } else {
-            return localTimestamp >= adjustedRemoteTimestamp;
         }
+        return localTimestamp >= adjustedRemoteTimestamp;
     }
 
 
@@ -1481,28 +1498,21 @@
      */
     protected void doSiteCommand(FTPClient ftp, String theCMD)
         throws IOException, BuildException {
-        boolean rc;
-        String[] myReply = null;
 
         task.log("Doing Site Command: " + theCMD, Project.MSG_VERBOSE);
 
-        rc = ftp.sendSiteCommand(theCMD);
-
-        if (!rc) {
-            task.log("Failed to issue Site Command: " + theCMD, Project.MSG_WARN);
+        if (!ftp.sendSiteCommand(theCMD)) {
+            task.log("Failed to issue Site Command: " + theCMD,
+                Project.MSG_WARN);
         } else {
-
-            myReply = ftp.getReplyStrings();
-
-            for (int x = 0; x < myReply.length; x++) {
-                if (myReply[x].indexOf("200") == -1) {
-                    task.log(myReply[x], Project.MSG_WARN);
+            for (String reply : ftp.getReplyStrings()) {
+                if (reply.indexOf("200") == -1) {
+                    task.log(reply, Project.MSG_WARN);
                 }
             }
         }
     }
 
-
     /**
      * Sends a single file to the remote host. <code>filename</code> may
      * contain a relative path specification. When this is the case, <code>sendFile</code>
@@ -1535,15 +1545,13 @@
                 task.log("transferring " + file.getAbsolutePath());
             }
 
-            instream = new BufferedInputStream(new FileInputStream(file));
+            instream = new BufferedInputStream(Files.newInputStream(file.toPath()));
 
             createParents(ftp, filename);
 
             ftp.storeFile(resolveFile(filename), instream);
 
-            boolean success = FTPReply.isPositiveCompletion(ftp.getReplyCode());
-
-            if (!success) {
+            if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
                 String s = "could not put file: " + ftp.getReplyString();
 
                 if (task.isSkipFailedTransfers()) {
@@ -1568,7 +1576,6 @@
         }
     }
 
-
     /**
      * Delete a file from the remote host.
      * @param ftp ftp client
@@ -1629,7 +1636,6 @@
         }
     }
 
-
     /**
      * Retrieve a single file from the remote host. <code>filename</code> may
      * contain a relative path specification. <p>
@@ -1666,7 +1672,7 @@
             if (!pdir.exists()) {
                 pdir.mkdirs();
             }
-            outstream = new BufferedOutputStream(new FileOutputStream(file));
+            outstream = new BufferedOutputStream(Files.newOutputStream(file.toPath()));
             ftp.retrieveFile(resolveFile(filename), outstream);
 
             if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
@@ -1700,7 +1706,6 @@
         }
     }
 
-
     /**
      * List information about a single file from the remote host. <code>filename</code>
      * may contain a relative path specification. <p>
@@ -1729,7 +1734,6 @@
         }
     }
 
-
     /**
      * Create the specified directory on the remote host.
      *
@@ -1755,10 +1759,9 @@
         if (dir.startsWith("/")) {
             ftp.changeWorkingDirectory("/");
         }
-        String subdir = "";
         StringTokenizer st = new StringTokenizer(dir, "/");
         while (st.hasMoreTokens()) {
-            subdir = st.nextToken();
+            String subdir = st.nextToken();
             task.log("Checking " + subdir, Project.MSG_DEBUG);
             if (!ftp.changeWorkingDirectory(subdir)) {
                 if (!ftp.makeDirectory(subdir)) {
@@ -1805,6 +1808,7 @@
         }
     }
 
+    @Override
     public void doFTP() throws BuildException {
         FTPClient ftp = null;
 
@@ -1819,8 +1823,8 @@
             ftp.setRemoteVerificationEnabled(task.getEnableRemoteVerification());
             ftp.connect(task.getServer(), task.getPort());
             if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
-                throw new BuildException("FTP connection failed: "
-                                         + ftp.getReplyString());
+                throw new BuildException("FTP connection failed: %s",
+                    ftp.getReplyString());
             }
 
             task.log("connected", Project.MSG_VERBOSE);
@@ -1836,14 +1840,14 @@
             if (task.isBinary()) {
                 ftp.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
                 if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
-                    throw new BuildException("could not set transfer type: "
-                                             + ftp.getReplyString());
+                    throw new BuildException("could not set transfer type: %s",
+                        ftp.getReplyString());
                 }
             } else {
                 ftp.setFileType(org.apache.commons.net.ftp.FTP.ASCII_FILE_TYPE);
                 if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
-                    throw new BuildException("could not set transfer type: "
-                                             + ftp.getReplyString());
+                    throw new BuildException("could not set transfer type: %s",
+                        ftp.getReplyString());
                 }
             }
 
@@ -1851,8 +1855,9 @@
                 task.log("entering passive mode", Project.MSG_VERBOSE);
                 ftp.enterLocalPassiveMode();
                 if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
-                    throw new BuildException("could not enter into passive "
-                                             + "mode: " + ftp.getReplyString());
+                    throw new BuildException(
+                        "could not enter into passive mode: %s",
+                        ftp.getReplyString());
                 }
             }
 
@@ -1861,55 +1866,46 @@
             // E.G. switching between a UNIX file system mode and
             // a legacy file system.
             if (task.getInitialSiteCommand() != null) {
-                RetryHandler h = new RetryHandler(task.getRetriesAllowed(), task);
                 final FTPClient lftp = ftp;
-                executeRetryable(h, new Retryable() {
-                        public void execute() throws IOException {
-                            doSiteCommand(lftp, task.getInitialSiteCommand());
-                        }
-                    }, "initial site command: " + task.getInitialSiteCommand());
+                executeRetryable(new RetryHandler(task.getRetriesAllowed(), task),
+                    () -> doSiteCommand(lftp, task.getInitialSiteCommand()),
+                    "initial site command: " + task.getInitialSiteCommand());
             }
 
-
             // For a unix ftp server you can set the default mask for all files
             // created.
 
             if (task.getUmask() != null) {
-                RetryHandler h = new RetryHandler(task.getRetriesAllowed(), task);
                 final FTPClient lftp = ftp;
-                executeRetryable(h, new Retryable() {
-                        public void execute() throws IOException {
-                            doSiteCommand(lftp, "umask " + task.getUmask());
-                        }
-                    }, "umask " + task.getUmask());
+                executeRetryable(
+                    new RetryHandler(task.getRetriesAllowed(), task),
+                    () -> doSiteCommand(lftp, "umask " + task.getUmask()),
+                    "umask " + task.getUmask());
             }
 
             // If the action is MK_DIR, then the specified remote
             // directory is the directory to create.
 
             if (task.getAction() == FTPTask.MK_DIR) {
-                RetryHandler h = new RetryHandler(task.getRetriesAllowed(), task);
                 final FTPClient lftp = ftp;
-                executeRetryable(h, new Retryable() {
-                        public void execute() throws IOException {
-                            makeRemoteDir(lftp, task.getRemotedir());
-                        }
-                    }, task.getRemotedir());
+                executeRetryable(
+                    new RetryHandler(task.getRetriesAllowed(), task),
+                    () -> makeRemoteDir(lftp, task.getRemotedir()),
+                    task.getRemotedir());
             } else if (task.getAction() == FTPTask.SITE_CMD) {
-                RetryHandler h = new RetryHandler(task.getRetriesAllowed(), task);
                 final FTPClient lftp = ftp;
-                executeRetryable(h, new Retryable() {
-                        public void execute() throws IOException {
-                            doSiteCommand(lftp, task.getSiteCommand());
-                        }
-                    }, "Site Command: " + task.getSiteCommand());
+                executeRetryable(
+                    new RetryHandler(task.getRetriesAllowed(), task),
+                    () -> doSiteCommand(lftp, task.getSiteCommand()),
+                    "Site Command: " + task.getSiteCommand());
             } else {
                 if (task.getRemotedir() != null) {
                     task.log("changing the remote directory", Project.MSG_VERBOSE);
                     ftp.changeWorkingDirectory(task.getRemotedir());
                     if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
-                        throw new BuildException("could not change remote "
-                                                 + "directory: " + ftp.getReplyString());
+                        throw new BuildException(
+                            "could not change remote directory: %s",
+                            ftp.getReplyString());
                     }
                 }
                 if (task.isNewer() && task.isTimeDiffAuto()) {
@@ -1920,7 +1916,6 @@
                 task.log(FTPTask.ACTION_STRS[task.getAction()] + " " + FTPTask.ACTION_TARGET_STRS[task.getAction()]);
                 transferFiles(ftp);
             }
-
         } catch (IOException ex) {
             throw new BuildException("error during FTP transfer: " + ex, ex);
         } finally {
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/net/MimeMail.java b/src/main/org/apache/tools/ant/taskdefs/optional/net/MimeMail.java
index fca4215..01db77a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/net/MimeMail.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/net/MimeMail.java
@@ -28,12 +28,14 @@
  *
  * @since Ant1.4
  */
+@Deprecated
 public class MimeMail extends EmailTask {
     /**
      * Executes this build task.
      *
      * @exception BuildException On error.
      */
+    @Override
     public void execute()
         throws BuildException {
         log("DEPRECATED - The " + getTaskName() + " task is deprecated. "
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/net/RExecTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/net/RExecTask.java
index d88874f..ff24beb 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/net/RExecTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/net/RExecTask.java
@@ -22,7 +22,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Calendar;
-import java.util.Enumeration;
+import java.util.List;
 import java.util.Vector;
 
 import org.apache.commons.net.bsd.RExecClient;
@@ -68,7 +68,7 @@
     /**
      *  The list of read/write commands for this session
      */
-    private Vector rexecTasks = new Vector();
+    private List<RExecSubTask> rexecTasks = new Vector<>();
 
     /**
      *  If true, adds a CR to beginning of login script
@@ -97,7 +97,7 @@
          */
         public void execute(AntRExecClient rexec)
                 throws BuildException {
-            throw new BuildException("Shouldn't be able instantiate a SubTask directly");
+            throw new BuildException("Shouldn't be able to instantiate a SubTask directly");
         }
 
         /**
@@ -127,6 +127,7 @@
          * @param rexec the task to use
          * @throws BuildException on error
          */
+        @Override
         public void execute(AntRExecClient rexec)
                throws BuildException {
            rexec.sendString(taskString, echoString);
@@ -153,6 +154,7 @@
          * @param rexec the task to use
          * @throws BuildException on error
          */
+        @Override
         public void execute(AntRExecClient rexec)
                throws BuildException {
             rexec.waitForString(taskString, timeout);
@@ -202,7 +204,7 @@
         public void waitForString(String s, Integer timeout) {
             InputStream is = this.getInputStream();
             try {
-                StringBuffer sb = new StringBuffer();
+                StringBuilder sb = new StringBuilder();
                 int windowStart = -s.length();
                 if (timeout == null || timeout.intValue() == 0) {
                     while (windowStart < 0
@@ -253,6 +255,7 @@
                 throw new BuildException(e, getLocation());
             }
         }
+
         /**
          * Read from the rexec session until the EOF is found or
          * the timeout has been reached
@@ -261,15 +264,15 @@
         public void waitForEOF(Integer timeout) {
             InputStream is = this.getInputStream();
             try {
-                StringBuffer sb = new StringBuffer();
+                StringBuilder sb = new StringBuilder();
                 if (timeout == null || timeout.intValue() == 0) {
                 int read;
                     while ((read = is.read()) != -1) {
                         char c = (char) read;
                         sb.append(c);
                         if (c == '\n') {
-                        log(sb.toString(), Project.MSG_INFO);
-                        sb.delete(0, sb.length());
+                            log(sb.toString(), Project.MSG_INFO);
+                            sb.delete(0, sb.length());
                         }
                     }
                 } else {
@@ -281,24 +284,24 @@
                             Thread.sleep(PAUSE_TIME);
                         }
                         if (is.available() == 0) {
-                        log(sb.toString(), Project.MSG_INFO);
-                            throw new BuildException(
-                                                     "Response timed-out waiting for EOF",
-                                                     getLocation());
+                            log(sb.toString(), Project.MSG_INFO);
+                                throw new BuildException(
+                                                         "Response timed-out waiting for EOF",
+                                                         getLocation());
                         }
                         read =  is.read();
                         if (read != -1) {
-                        char c = (char) read;
-                        sb.append(c);
-                        if (c == '\n') {
+                            char c = (char) read;
+                            sb.append(c);
+                            if (c == '\n') {
                                 log(sb.toString(), Project.MSG_INFO);
                                 sb.delete(0, sb.length());
-                        }
+                            }
                         }
                     }
                 }
                 if (sb.length() > 0) {
-                log(sb.toString(), Project.MSG_INFO);
+                    log(sb.toString(), Project.MSG_INFO);
                 }
             } catch (BuildException be) {
                 throw be;
@@ -306,8 +309,8 @@
                 throw new BuildException(e, getLocation());
             }
         }
-
     }
+
     /**
      *  A string to wait for from the server.
      *  A subTask &lt;read&gt; tag was found.  Create the object,
@@ -316,10 +319,11 @@
      */
 
     public RExecSubTask createRead() {
-        RExecSubTask task = (RExecSubTask) new RExecRead();
-        rexecTasks.addElement(task);
+        RExecSubTask task = new RExecRead();
+        rexecTasks.add(task);
         return task;
     }
+
     /**
      *  Add text to send to the server
      *  A subTask &lt;write&gt; tag was found.  Create the object,
@@ -327,16 +331,18 @@
      * @return a write sub task
      */
     public RExecSubTask createWrite() {
-        RExecSubTask task = (RExecSubTask) new RExecWrite();
-        rexecTasks.addElement(task);
+        RExecSubTask task = new RExecWrite();
+        rexecTasks.add(task);
         return task;
     }
+
     /**
      *  Verify that all parameters are included.
      *  Connect and possibly login.
      *  Iterate through the list of Reads and writes.
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
         /**  A server name is required to continue */
         if (server == null) {
@@ -363,7 +369,7 @@
                 throw new BuildException("Can't connect to " + server);
             }
             if (userid != null && password != null && command != null //NOSONAR
-                && rexecTasks.size() == 0) {
+                && rexecTasks.isEmpty()) {
                 // simple one-shot execution
                 rexec.rexec(userid, password, command);
             } else {
@@ -384,13 +390,14 @@
                     String msg = "Error disconnecting from " + server;
                     if (success) {
                         throw new BuildException(msg); //NOSONAR
-                    } else { // don't hide inner exception
-                        log(msg, Project.MSG_ERR);
                     }
+                    // don't hide inner exception
+                    log(msg, Project.MSG_ERR);
                 }
             }
         }
     }
+
     /**
      *  Process a 'typical' login.  If it differs, use the read
      *  and write tasks explicitly
@@ -404,6 +411,7 @@
         rexec.waitForString("assword:");
         rexec.sendString(password, false);
     }
+
     /**
      * Set the the command to execute on the server;
      * @param c a <code>String</code> value
@@ -419,6 +427,7 @@
     public void setInitialCR(boolean b) {
         this.addCarriageReturn = b;
     }
+
     /**
      *  Set the the login password to use
      * required if <tt>userid</tt> is set.
@@ -452,6 +461,7 @@
     public void setTimeout(Integer i) {
         this.defaultTimeout = i;
     }
+
     /**
      * Set the the login id to use on the server;
      * required if <tt>password</tt> is set.
@@ -473,9 +483,7 @@
             login(rexec);
         }
         /**  Process each sub command */
-        Enumeration tasksToRun = rexecTasks.elements();
-        while (tasksToRun != null && tasksToRun.hasMoreElements()) {
-            RExecSubTask task = (RExecSubTask) tasksToRun.nextElement();
+        for (RExecSubTask task : rexecTasks) {
             if (task instanceof RExecRead && defaultTimeout != null) {
                 ((RExecRead) task).setDefaultTimeout(defaultTimeout);
             }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/net/SetProxy.java b/src/main/org/apache/tools/ant/taskdefs/optional/net/SetProxy.java
index 1e1f659..748afcf 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/net/SetProxy.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/net/SetProxy.java
@@ -175,7 +175,6 @@
      * apply to all network connections
      * Relevant docs: buglist #4183340
      */
-
     public void applyWebProxySettings() {
         boolean settingsChanged = false;
         boolean enablingProxy = false;
@@ -261,6 +260,7 @@
      *
      * @exception BuildException thrown in unrecoverable error.
      */
+    @Override
     public void execute() throws BuildException {
         applyWebProxySettings();
     }
@@ -275,6 +275,7 @@
             auth = new PasswordAuthentication(user, pass.toCharArray());
         }
 
+        @Override
         protected PasswordAuthentication getPasswordAuthentication() {
             return auth;
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/net/TelnetTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/net/TelnetTask.java
index a89e7a9..412ef93 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/net/TelnetTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/net/TelnetTask.java
@@ -22,7 +22,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Calendar;
-import java.util.Enumeration;
+import java.util.List;
 import java.util.Vector;
 
 import org.apache.commons.net.telnet.TelnetClient;
@@ -34,7 +34,6 @@
  * Automates the telnet protocol.
  *
  */
-
 public class TelnetTask extends Task {
     private static final int WAIT_INTERVAL = 250;
     private static final int TELNET_PORT = 23;
@@ -62,7 +61,7 @@
     /**
      *  The list of read/write commands for this session
      */
-    private Vector telnetTasks = new Vector();
+    private List<TelnetSubTask> telnetTasks = new Vector<>();
 
     /**
      *  If true, adds a CR to beginning of login script
@@ -81,6 +80,7 @@
      *  Iterate through the list of Reads and writes
      * @throws BuildException on error
      */
+    @Override
     public void execute() throws BuildException {
        /**  A server name is required to continue */
        if (server == null) {
@@ -111,9 +111,7 @@
                login(telnet);
            }
            /**  Process each sub command */
-           Enumeration tasksToRun = telnetTasks.elements();
-           while (tasksToRun != null && tasksToRun.hasMoreElements()) {
-               TelnetSubTask task = (TelnetSubTask) tasksToRun.nextElement();
+           for (TelnetSubTask task : telnetTasks) {
                if (task instanceof TelnetRead && defaultTimeout != null) {
                    ((TelnetRead) task).setDefaultTimeout(defaultTimeout);
                }
@@ -209,8 +207,8 @@
      */
 
     public TelnetSubTask createRead() {
-        TelnetSubTask task = (TelnetSubTask) new TelnetRead();
-        telnetTasks.addElement(task);
+        TelnetSubTask task = new TelnetRead();
+        telnetTasks.add(task);
         return task;
     }
 
@@ -221,8 +219,8 @@
      * @return a write telnet sub task
      */
     public TelnetSubTask createWrite() {
-        TelnetSubTask task = (TelnetSubTask) new TelnetWrite();
-        telnetTasks.addElement(task);
+        TelnetSubTask task = new TelnetWrite();
+        telnetTasks.add(task);
         return task;
     }
 
@@ -271,6 +269,7 @@
          * @param telnet the task to use
          * @throws BuildException on error
          */
+        @Override
         public void execute(AntTelnetClient telnet)
                throws BuildException {
            telnet.sendString(taskString, echoString);
@@ -297,6 +296,7 @@
          * @param telnet the task to use
          * @throws BuildException on error
          */
+        @Override
         public void execute(AntTelnetClient telnet)
                throws BuildException {
             telnet.waitForString(taskString, timeout);
@@ -346,7 +346,7 @@
         public void waitForString(String s, Integer timeout) {
             InputStream is = this.getInputStream();
             try {
-                StringBuffer sb = new StringBuffer();
+                StringBuilder sb = new StringBuilder();
                 int windowStart = -s.length();
                 if (timeout == null || timeout.intValue() == 0) {
                     while (windowStart < 0
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/Pvcs.java b/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/Pvcs.java
index 6956019..9a81ef1 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/Pvcs.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/Pvcs.java
@@ -21,13 +21,13 @@
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
 import java.text.MessageFormat;
 import java.text.ParseException;
-import java.util.Enumeration;
 import java.util.Random;
 import java.util.Vector;
 
@@ -78,10 +78,20 @@
     private static final int POS_2 = 2;
     private static final int POS_3 = 3;
 
+    /**
+     * Constant for the thing to execute
+     */
+    private static final String PCLI_EXE = "pcli";
+
+    /**
+     * Constant for the thing to execute
+     */
+    private static final String GET_EXE = "get";
+
     private String pvcsbin;
     private String repository;
     private String pvcsProject;
-    private Vector pvcsProjects;
+    private Vector<PvcsProject> pvcsProjects;
     private String workspace;
     private String force;
     private String promotiongroup;
@@ -93,21 +103,25 @@
     private String lineStart;
     private String userId;
     private String config;
-    /**
-     * Constant for the thing to execute
-     */
-    private static final String PCLI_EXE = "pcli";
-
-    /*
-     * Constant for the PCLI listversionedfiles recursive i a format "get" understands
-     */
-    // private static final String PCLI_LVF_ARGS = "lvf -z -aw";
 
     /**
-     * Constant for the thing to execute
+     * Creates a Pvcs object
      */
-    private static final String GET_EXE = "get";
-
+    public Pvcs() {
+        super();
+        pvcsProject = null;
+        pvcsProjects = new Vector<>();
+        workspace = null;
+        repository = null;
+        pvcsbin = null;
+        force = null;
+        promotiongroup = null;
+        label = null;
+        ignorerc = false;
+        updateOnly = false;
+        lineStart = "\"P:";
+        filenameFormat = "{0}-arc({1})";
+    }
 
     /**
      * Run the command.
@@ -123,7 +137,7 @@
             exe.setWorkingDirectory(aProj.getBaseDir());
             exe.setCommandline(cmd.getCommandline());
             return exe.execute();
-        } catch (java.io.IOException e) {
+        } catch (IOException e) {
             String msg = "Failed executing: " + cmd.toString()
                 + ". Exception: " + e.getMessage();
             throw new BuildException(msg, getLocation());
@@ -131,7 +145,7 @@
     }
 
     private String getExecutable(String exe) {
-        StringBuffer correctedExe = new StringBuffer();
+        StringBuilder correctedExe = new StringBuilder();
         if (getPvcsbin() != null) {
             if (pvcsbin.endsWith(File.separator)) {
                 correctedExe.append(pvcsbin);
@@ -145,10 +159,11 @@
     /**
      * @exception org.apache.tools.ant.BuildException Something is stopping the build...
      */
-    public void execute() throws org.apache.tools.ant.BuildException {
+    @Override
+    public void execute() throws BuildException {
         int result = 0;
 
-        if (repository == null || repository.trim().equals("")) {
+        if (repository == null || repository.trim().isEmpty()) {
             throw new BuildException("Required argument repository not specified");
         }
 
@@ -182,12 +197,10 @@
             commandLine.createArgument().setValue(getPvcsproject());
         }
         if (!getPvcsprojects().isEmpty()) {
-            Enumeration e = getPvcsprojects().elements();
-            while (e.hasMoreElements()) {
-                String projectName = ((PvcsProject) e.nextElement()).getName();
-                if (projectName == null || (projectName.trim()).equals("")) {
-                    throw new BuildException("name is a required attribute "
-                        + "of pvcsproject");
+            for (PvcsProject pvcsProject : getPvcsprojects()) {
+                String projectName = pvcsProject.getName();
+                if (projectName == null || projectName.trim().isEmpty()) {
+                    throw new BuildException("name is a required attribute of pvcsproject");
                 }
                 commandLine.createArgument().setValue(projectName);
             }
@@ -198,7 +211,7 @@
         try {
             Random rand = new Random(System.currentTimeMillis());
             tmp = new File("pvcs_ant_" + rand.nextLong() + ".log");
-            FileOutputStream fos = new FileOutputStream(tmp);
+            OutputStream fos = Files.newOutputStream(tmp.toPath());
             tmp2 = new File("pvcs_ant_" + rand.nextLong() + ".log");
             log(commandLine.describeCommand(), Project.MSG_VERBOSE);
             try {
@@ -294,9 +307,7 @@
      * Parses the file and creates the folders specified in the output section
      */
     private void createFolders(File file) throws IOException, ParseException {
-        BufferedReader in = null;
-        try {
-            in = new BufferedReader(new FileReader(file));
+        try (BufferedReader in = new BufferedReader(new FileReader(file))) {
             MessageFormat mf = new MessageFormat(getFilenameFormat());
             String line = in.readLine();
             while (line != null) {
@@ -314,7 +325,10 @@
                     int index = f.lastIndexOf(File.separator);
                     if (index > -1) {
                         File dir = new File(f.substring(0, index));
-                        if (!dir.exists()) {
+                        if (dir.exists()) {
+                            log(dir.getAbsolutePath() + " exists. Skipping",
+                                Project.MSG_VERBOSE);
+                        } else {
                             log("Creating " + dir.getAbsolutePath(),
                                 Project.MSG_VERBOSE);
                             if (dir.mkdirs() || dir.isDirectory()) {
@@ -325,9 +339,6 @@
                                     + dir.getAbsolutePath(),
                                     Project.MSG_INFO);
                             }
-                        } else {
-                            log(dir.getAbsolutePath() + " exists. Skipping",
-                                Project.MSG_VERBOSE);
                         }
                     } else {
                         log("File separator problem with " + line,
@@ -338,8 +349,6 @@
                 }
                 line = in.readLine();
             }
-        } finally {
-            FileUtils.close(in);
         }
     }
 
@@ -351,20 +360,13 @@
      */
     private void massagePCLI(File in, File out)
         throws IOException {
-        BufferedReader inReader = null;
-        BufferedWriter outWriter = null;
-        try {
-            inReader = new BufferedReader(new FileReader(in));
-            outWriter = new BufferedWriter(new FileWriter(out));
-            String s = null;
-            while ((s = inReader.readLine()) != null) {
-                String sNormal = s.replace('\\', '/');
-                outWriter.write(sNormal);
+        try (BufferedReader inReader = new BufferedReader(new FileReader(in));
+                BufferedWriter outWriter = new BufferedWriter(new FileWriter(out))) {
+            for (String line : (Iterable<String>) () -> inReader.lines()
+                    .map(s -> s.replace('\\', '/')).iterator()) {
+                outWriter.write(line);
                 outWriter.newLine();
             }
-        } finally {
-            FileUtils.close(inReader);
-            FileUtils.close(outWriter);
         }
     }
 
@@ -454,7 +456,7 @@
      * Get name of the project in the PVCS repository
      * @return Vector
      */
-    public Vector getPvcsprojects() {
+    public Vector<PvcsProject> getPvcsprojects() {
         return pvcsProjects;
     }
 
@@ -519,11 +521,7 @@
      * @param f String (yes/no)
      */
     public void setForce(String f) {
-        if (f != null && f.equalsIgnoreCase("yes")) {
-            force = "yes";
-        } else {
-            force = "no";
-        }
+        force = "yes".equalsIgnoreCase(f) ? "yes" : "no";
     }
 
     /**
@@ -650,23 +648,5 @@
         userId = u;
     }
 
-    /**
-     * Creates a Pvcs object
-     */
-    public Pvcs() {
-        super();
-        pvcsProject = null;
-        pvcsProjects = new Vector();
-        workspace = null;
-        repository = null;
-        pvcsbin = null;
-        force = null;
-        promotiongroup = null;
-        label = null;
-        ignorerc = false;
-        updateOnly = false;
-        lineStart = "\"P:";
-        filenameFormat = "{0}-arc({1})";
-    }
 }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/PvcsProject.java b/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/PvcsProject.java
index a8c6a2a..8f0aed7 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/PvcsProject.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/PvcsProject.java
@@ -26,11 +26,6 @@
 public class PvcsProject {
     private String name;
 
-    /** no arg constructor */
-    public PvcsProject() {
-        super();
-    }
-
     /**
      * Set the name of the project
      * @param name the value to use.
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java b/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
index ac9eb88..4aad07b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
@@ -21,7 +21,6 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -40,7 +39,7 @@
 import org.apache.tools.ant.util.ScriptRunnerHelper;
 
 /**
- * Define a task using a script
+ * Defines a task using a script.
  *
  * @since Ant 1.6
  */
@@ -54,21 +53,22 @@
     private String name;
 
     /** Attributes definitions of this script */
-    private List attributes = new ArrayList();
+    private List<Attribute> attributes = new ArrayList<>();
 
     /** Nested Element definitions of this script */
-    private List nestedElements = new ArrayList();
+    private List<NestedElement> nestedElements = new ArrayList<>();
 
     /** The attribute names as a set */
-    private Set attributeSet;
+    private Set<String> attributeSet;
 
     /** The nested element definitions indexed by their names */
-    private Map nestedElementMap;
+    private Map<String, NestedElement> nestedElementMap;
 
     /**
      * Set the project.
-     * @param project the project that this def belows to.
+     * @param project the project that this definition belongs to.
      */
+    @Override
     public void setProject(Project project) {
         super.setProject(project);
         helper.setProjectComponent(this);
@@ -76,7 +76,7 @@
     }
 
     /**
-     * set the name under which this script will be activated in a build
+     * Sets the name under which this script will be activated in a build
      * file
      *
      * @param name the name of the script
@@ -104,7 +104,7 @@
         private String name;
 
         /**
-         * Set the attribute name
+         * Sets the attribute name
          *
          * @param name the attribute name
          */
@@ -114,7 +114,7 @@
     }
 
     /**
-     * Add an attribute definition to this script.
+     * Adds an attribute definition to this script.
      *
      * @param attribute the attribute definition.
      */
@@ -136,7 +136,7 @@
         private String className;
 
         /**
-         * set the tag name for this nested element
+         * Sets the tag name for this nested element
          *
          * @param name the name of this nested element
          */
@@ -145,7 +145,7 @@
         }
 
         /**
-         * Set the type of this element. This is the name of an
+         * Sets the type of this element. This is the name of an
          * Ant task or type which is to be used when this element is to be
          * created. This is an alternative to specifying the class name directly
          *
@@ -157,7 +157,7 @@
         }
 
         /**
-         * Set the classname of the class to be used for the nested element.
+         * Sets the classname of the class to be used for the nested element.
          * This specifies the class directly and is an alternative to specifying
          * the Ant type name.
          *
@@ -170,7 +170,7 @@
     }
 
     /**
-     * Add a nested element definition.
+     * Adds a nested element definition.
      *
      * @param nestedElement the nested element definition.
      */
@@ -179,17 +179,23 @@
     }
 
     /**
-     * Define the script.
+     * Defines the script.
      */
+    @Override
     public void execute() {
         if (name == null) {
-            throw new BuildException("scriptdef requires a name attribute to "
-                + "name the script");
+            throw new BuildException(
+                "scriptdef requires a name attribute to name the script");
         }
 
         if (helper.getLanguage() == null) {
-            throw new BuildException("<scriptdef> requires a language attribute "
-                + "to specify the script language");
+            throw new BuildException(
+                "scriptdef requires a language attribute to specify the script language");
+        }
+
+        if (helper.getSrc() == null && helper.getEncoding() != null) {
+            throw new BuildException(
+                "scriptdef requires a src attribute if the encoding is set");
         }
 
         // Check if need to set the loader
@@ -197,52 +203,47 @@
             helper.setClassLoader(createLoader());
         }
 
-        attributeSet = new HashSet();
-        for (Iterator i = attributes.iterator(); i.hasNext();) {
-            Attribute attribute = (Attribute) i.next();
+        attributeSet = new HashSet<>();
+        for (Attribute attribute : attributes) {
             if (attribute.name == null) {
-                throw new BuildException("scriptdef <attribute> elements "
-                    + "must specify an attribute name");
+                throw new BuildException(
+                    "scriptdef <attribute> elements must specify an attribute name");
             }
-
             if (attributeSet.contains(attribute.name)) {
-                throw new BuildException("scriptdef <" + name + "> declares "
-                    + "the " + attribute.name + " attribute more than once");
+                throw new BuildException(
+                    "scriptdef <%s> declares the %s attribute more than once",
+                    name, attribute.name);
             }
             attributeSet.add(attribute.name);
         }
 
-        nestedElementMap = new HashMap();
-        for (Iterator i = nestedElements.iterator(); i.hasNext();) {
-            NestedElement nestedElement = (NestedElement) i.next();
+        nestedElementMap = new HashMap<>();
+        for (NestedElement nestedElement : nestedElements) {
             if (nestedElement.name == null) {
-                throw new BuildException("scriptdef <element> elements "
-                    + "must specify an element name");
+                throw new BuildException(
+                    "scriptdef <element> elements must specify an element name");
             }
             if (nestedElementMap.containsKey(nestedElement.name)) {
-                throw new BuildException("scriptdef <" + name + "> declares "
-                    + "the " + nestedElement.name + " nested element more "
-                    + "than once");
+                throw new BuildException(
+                    "scriptdef <%s> declares the %s nested element more than once",
+                    name, nestedElement.name);
             }
 
             if (nestedElement.className == null
                 && nestedElement.type == null) {
-                throw new BuildException("scriptdef <element> elements "
-                    + "must specify either a classname or type attribute");
+                throw new BuildException(
+                    "scriptdef <element> elements must specify either a classname or type attribute");
             }
             if (nestedElement.className != null
                 && nestedElement.type != null) {
-                throw new BuildException("scriptdef <element> elements "
-                    + "must specify only one of the classname and type "
-                    + "attributes");
+                throw new BuildException(
+                    "scriptdef <element> elements must specify only one of the classname and type attributes");
             }
-
-
             nestedElementMap.put(nestedElement.name, nestedElement);
         }
 
         // find the script repository - it is stored in the project
-        Map scriptRepository = lookupScriptRepository();
+        Map<String, ScriptDef> scriptRepository = lookupScriptRepository();
         name = ProjectHelper.genComponentName(getURI(), name);
         scriptRepository.put(name, this);
         AntTypeDefinition def = new AntTypeDefinition();
@@ -253,18 +254,18 @@
     }
 
     /**
-     * Find or create the script repository - it is stored in the project.
+     * Finds or creates the script repository - it is stored in the project.
      * This method is synchronized on the project under {@link MagicNames#SCRIPT_REPOSITORY}
      * @return the current script repository registered as a reference.
      */
-    private Map lookupScriptRepository() {
-        Map scriptRepository = null;
+    private Map<String, ScriptDef> lookupScriptRepository() {
+        Map<String, ScriptDef> scriptRepository;
         Project p = getProject();
         synchronized (p) {
             scriptRepository =
-                    (Map) p.getReference(MagicNames.SCRIPT_REPOSITORY);
+                    p.getReference(MagicNames.SCRIPT_REPOSITORY);
             if (scriptRepository == null) {
-                scriptRepository = new HashMap();
+                scriptRepository = new HashMap<>();
                 p.addReference(MagicNames.SCRIPT_REPOSITORY,
                         scriptRepository);
             }
@@ -273,20 +274,20 @@
     }
 
     /**
-     * Create a nested element to be configured.
+     * Creates a nested element to be configured.
      *
      * @param elementName the name of the nested element.
      * @return object representing the element name.
      */
     public Object createNestedElement(String elementName) {
-        NestedElement definition
-            = (NestedElement) nestedElementMap.get(elementName);
+        NestedElement definition = nestedElementMap.get(elementName);
         if (definition == null) {
-            throw new BuildException("<" + name + "> does not support "
-                + "the <" + elementName + "> nested element");
+            throw new BuildException(
+                "<%s> does not support the <%s> nested element", name,
+                elementName);
         }
 
-        Object instance = null;
+        Object instance;
         String classname = definition.className;
         if (classname == null) {
             instance = getProject().createTask(definition.type);
@@ -294,11 +295,6 @@
                 instance = getProject().createDataType(definition.type);
             }
         } else {
-            /*
-            // try the context classloader
-            ClassLoader loader
-                = Thread.currentThread().getContextClassLoader();
-            */
             ClassLoader loader = createLoader();
 
             try {
@@ -306,31 +302,33 @@
             } catch (BuildException e) {
                 instance = ClasspathUtils.newInstance(classname, ScriptDef.class.getClassLoader());
             }
-
             getProject().setProjectReference(instance);
         }
 
         if (instance == null) {
-            throw new BuildException("<" + name + "> is unable to create "
-                + "the <" + elementName + "> nested element");
+            throw new BuildException(
+                "<%s> is unable to create the <%s> nested element", name,
+                elementName);
         }
         return instance;
     }
 
     /**
-     * Execute the script.
+     * Executes the script.
      *
      * @param attributes collection of attributes
      * @param elements a list of nested element values.
      * @deprecated since 1.7.
      *             Use executeScript(attribute, elements, instance) instead.
      */
-    public void executeScript(Map attributes, Map elements) {
+    @Deprecated
+    public void executeScript(Map<String, String> attributes,
+        Map<String, List<Object>> elements) {
         executeScript(attributes, elements, null);
     }
 
     /**
-     * Execute the script.
+     * Executes the script.
      * This is called by the script instance to execute the script for this
      * definition.
      *
@@ -338,7 +336,8 @@
      * @param elements   a list of nested element values.
      * @param instance   the script instance; can be null
      */
-    public void executeScript(Map attributes, Map elements, ScriptDefBase instance) {
+    public void executeScript(Map<String, String> attributes,
+        Map<String, List<Object>> elements, ScriptDefBase instance) {
         ScriptRunnerBase runner = helper.getScriptRunner();
         runner.addBean("attributes", attributes);
         runner.addBean("elements", elements);
@@ -368,7 +367,17 @@
     }
 
     /**
-     * Load the script from an external file ; optional.
+     * Defines the compilation feature; optional.
+     *
+     * @param compiled enables the script compilation if available.
+     * @since Ant 1.10.2
+     */
+    public void setCompiled(boolean compiled) {
+        helper.setCompiled(compiled);
+    }
+
+    /**
+     * Loads the script from an external file; optional.
      *
      * @param file the file containing the script source.
      */
@@ -377,7 +386,17 @@
     }
 
     /**
-     * Set the script text.
+     * Sets the encoding of the script from an external file; optional.
+     *
+     * @param encoding the encoding of the file containing the script source.
+     * @since Ant 1.10.2
+     */
+    public void setEncoding(String encoding) {
+        helper.setEncoding(encoding);
+    }
+
+    /**
+     * Sets the script text.
      *
      * @param text a component of the script text to be added.
      */
@@ -386,12 +405,11 @@
     }
 
     /**
-     * Add any source resource.
-     * @since Ant1.7.1
+     * Adds any source resource.
+     * @since Ant 1.7.1
      * @param resource source of script
      */
     public void add(ResourceCollection resource) {
         helper.add(resource);
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDefBase.java b/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDefBase.java
index 95d15aa..a4a0bd6 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDefBase.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDefBase.java
@@ -36,10 +36,10 @@
 public class ScriptDefBase extends Task implements DynamicConfigurator {
 
     /** Nested elements */
-    private Map nestedElementMap = new HashMap();
+    private Map<String, List<Object>> nestedElementMap = new HashMap<>();
 
     /** Attributes */
-    private Map attributes = new HashMap();
+    private Map<String, String> attributes = new HashMap<>();
 
     private String text;
 
@@ -47,19 +47,20 @@
      * Locate the script defining task and execute the script by passing
      * control to it
      */
+    @Override
     public void execute() {
         getScript().executeScript(attributes, nestedElementMap, this);
     }
 
     private ScriptDef getScript() {
         String name = getTaskType();
-        Map scriptRepository
-            = (Map) getProject().getReference(MagicNames.SCRIPT_REPOSITORY);
+        Map<String, ScriptDef> scriptRepository =
+            getProject().getReference(MagicNames.SCRIPT_REPOSITORY);
         if (scriptRepository == null) {
             throw new BuildException("Script repository not found for " + name);
         }
 
-        ScriptDef definition = (ScriptDef) scriptRepository.get(getTaskType());
+        ScriptDef definition = scriptRepository.get(getTaskType());
         if (definition == null) {
             throw new BuildException("Script definition not found for " + name);
         }
@@ -72,12 +73,10 @@
      * @param name the nested element name
      * @return the element to be configured
      */
+    @Override
     public Object createDynamicElement(String name)  {
-        List nestedElementList = (List) nestedElementMap.get(name);
-        if (nestedElementList == null) {
-            nestedElementList = new ArrayList();
-            nestedElementMap.put(name, nestedElementList);
-        }
+        List<Object> nestedElementList =
+            nestedElementMap.computeIfAbsent(name, k -> new ArrayList<>());
         Object element = getScript().createNestedElement(name);
         nestedElementList.add(element);
         return element;
@@ -89,13 +88,14 @@
      * @param name the attribute name.
      * @param value the attribute's string value
      */
+    @Override
     public void setDynamicAttribute(String name, String value) {
         ScriptDef definition = getScript();
         if (!definition.isAttributeSupported(name)) {
-                throw new BuildException("<" + getTaskType()
-                    + "> does not support the \"" + name + "\" attribute");
+            throw new BuildException(
+                "<%s> does not support the \"%s\" attribute", getTaskType(),
+                name);
         }
-
         attributes.put(name, value);
     }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOS.java b/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOS.java
index be2e336..c9b462d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOS.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOS.java
@@ -388,6 +388,7 @@
      *
      * @throws BuildException on error.
      */
+    @Override
     public void execute()
         throws BuildException {
         int result = 0;
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckin.java b/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckin.java
index 7a8a246..fe8bd0e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckin.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckin.java
@@ -70,6 +70,7 @@
      *
      * @return    Commandline the generated command to be executed
      */
+    @Override
     protected Commandline buildCmdLine() {
         commandLine = new Commandline();
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckout.java b/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckout.java
index 6994dfa..447be0e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckout.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckout.java
@@ -59,6 +59,7 @@
      *
      * @return    Commandline the generated command to be executed
      */
+    @Override
     protected Commandline buildCmdLine() {
         commandLine = new Commandline();
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSGet.java b/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSGet.java
index bd13959..c55165e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSGet.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSGet.java
@@ -79,6 +79,7 @@
      *
      * @return    Commandline the generated command to be executed
      */
+    @Override
     protected Commandline buildCmdLine() {
         commandLine = new Commandline();
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSLabel.java b/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSLabel.java
index 21e8815..79cb11d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSLabel.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSLabel.java
@@ -65,6 +65,7 @@
      *
      * @return    Commandline the generated command to be executed
      */
+    @Override
     protected Commandline buildCmdLine() {
         commandLine = new Commandline();
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sos/package.html b/src/main/org/apache/tools/ant/taskdefs/optional/sos/package.html
index 401c7d7..4a34412 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/sos/package.html
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/sos/package.html
@@ -19,11 +19,11 @@
   <p>
     Ant tasks for working with a SourceOffSite source control system.
   </p>
-  <p>
-    The &lt;SOSGet&gt; Retrieves file(s) from a SOS database<br/>
-    The &lt;SOSCheckin&gt; Commits and unlocks file(s) in a SOS database<br/>
-    The &lt;SOSCheckout&gt; Retrieves and lock file(s) in a SOS database<br/>
-    The &lt;SOSLabel&gt; Label a SOS database
-  </p>
+  <dl>
+    <dt>&lt;SOSGet&gt;</dt><dd>Retrieves file(s) from a SOS database</dd>
+    <dt>&lt;SOSCheckin&gt;</dt><dd>Commits and unlocks file(s) in a SOS database</dd>
+    <dt>&lt;SOSCheckout&gt;</dt><dd>Retrieves and lock file(s) in a SOS database</dd>
+    <dt>&lt;SOSLabel&gt;</dt><dd>Label a SOS database</dd>
+  </dl>
 </body>
 </html>
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sound/AntSoundPlayer.java b/src/main/org/apache/tools/ant/taskdefs/optional/sound/AntSoundPlayer.java
index d1675a8..84b4317 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/sound/AntSoundPlayer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/sound/AntSoundPlayer.java
@@ -36,7 +36,7 @@
 import org.apache.tools.ant.BuildEvent;
 import org.apache.tools.ant.BuildListener;
 import org.apache.tools.ant.Project;
-
+import org.apache.tools.ant.util.FileUtils;
 
 
 /**
@@ -60,10 +60,6 @@
     private int loopsFail = 0;
     private Long durationFail = null;
 
-    /** Constructor for AntSoundPlayer. */
-    public AntSoundPlayer() {
-    }
-
     /**
      * @param file the location of the audio file to be played when the
      *        build is successful
@@ -102,7 +98,6 @@
 
         AudioInputStream audioInputStream = null;
 
-
         try {
             audioInputStream = AudioSystem.getAudioInputStream(file);
         } catch (UnsupportedAudioFileException uafe) {
@@ -137,9 +132,7 @@
                     audioClip.drain();
                 }
             } finally {
-                if (audioClip != null) {
-                    audioClip.close();
-                }
+                FileUtils.close(audioClip);
             }
         } else {
             project.log("Can't get data from file " + file.getName());
@@ -182,6 +175,7 @@
      * clip if required.
      * @param event the line event to follow
      */
+    @Override
     public void update(LineEvent event) {
         if (event.getType().equals(LineEvent.Type.STOP)) {
             Line line = event.getLine();
@@ -194,6 +188,7 @@
      *  Fired before any targets are started.
      * @param event ignored
      */
+    @Override
     public void buildStarted(BuildEvent event) {
     }
 
@@ -203,6 +198,7 @@
      * @param event the build finished event.
      *  @see BuildEvent#getException()
      */
+    @Override
     public void buildFinished(BuildEvent event) {
         if (event.getException() == null && fileSuccess != null) {
             // build successful!
@@ -217,6 +213,7 @@
      * @param event ignored.
      *  @see BuildEvent#getTarget()
      */
+    @Override
     public void targetStarted(BuildEvent event) {
     }
 
@@ -226,6 +223,7 @@
      * @param event ignored.
      *  @see BuildEvent#getException()
      */
+    @Override
     public void targetFinished(BuildEvent event) {
     }
 
@@ -234,6 +232,7 @@
      * @param event ignored.
      *  @see BuildEvent#getTask()
      */
+    @Override
     public void taskStarted(BuildEvent event) {
     }
 
@@ -243,6 +242,7 @@
      * @param event ignored.
      *  @see BuildEvent#getException()
      */
+    @Override
     public void taskFinished(BuildEvent event) {
     }
 
@@ -252,6 +252,7 @@
      *  @see BuildEvent#getMessage()
      *  @see BuildEvent#getPriority()
      */
+    @Override
     public void messageLogged(BuildEvent event) {
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashScreen.java b/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashScreen.java
index 5de84cc..e7d1c31 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashScreen.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashScreen.java
@@ -37,8 +37,10 @@
 
 import org.apache.tools.ant.BuildEvent;
 import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.Project;
 
 class SplashScreen extends JWindow implements ActionListener, BuildListener {
+    private static final long serialVersionUID = 1L;
     private static final int FONT_SIZE = 12;
     private JLabel text;
     private JProgressBar pb;
@@ -118,6 +120,7 @@
         text.setText(txt);
     }
 
+    @Override
     public void actionPerformed(ActionEvent a) {
         if (!hasProgressPattern()) {
             if (total < MAX) {
@@ -129,31 +132,38 @@
         }
     }
 
+    @Override
     public void buildStarted(BuildEvent event) {
         actionPerformed(null);
     }
 
+    @Override
     public void buildFinished(BuildEvent event) {
         pb.setValue(MAX);
         setVisible(false);
         dispose();
     }
+    @Override
     public void targetStarted(BuildEvent event) {
         actionPerformed(null);
     }
 
+    @Override
     public void targetFinished(BuildEvent event) {
         actionPerformed(null);
     }
 
+    @Override
     public void taskStarted(BuildEvent event) {
         actionPerformed(null);
     }
 
+    @Override
     public void taskFinished(BuildEvent event) {
         actionPerformed(null);
     }
 
+    @Override
     public void messageLogged(BuildEvent event) {
         actionPerformed(null);
         if (hasProgressPattern()) {
@@ -162,12 +172,11 @@
             if (matcher != null && matcher.matches()) {
                 String gr = matcher.group(1);
                 try {
-                    int i = Math.min(new Integer(gr).intValue() * 2, MAX);
-                    pb.setValue(i);
+                    pb.setValue(Math.min(Integer.parseInt(gr) * 2, MAX));
                 } catch (NumberFormatException e) {
-                    //TODO: how to reach logger?!?
-                    //log("Number parsing error in progressRegExp", Project.MSG_VERBOSE);
-
+                    event.getProject().log(
+                        "Number parsing error in progressRegExp",
+                        Project.MSG_VERBOSE);
                 }
             }
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashTask.java
index 9d995bc..a3235f9 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashTask.java
@@ -20,7 +20,6 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
-import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.net.URLConnection;
@@ -237,9 +236,9 @@
 
         boolean success = false;
         if (in != null) {
-            DataInputStream din = new DataInputStream(in);
-            try {
-                ByteArrayOutputStream bout = new ByteArrayOutputStream();
+            try (
+                DataInputStream din = new DataInputStream(in);
+                ByteArrayOutputStream bout = new ByteArrayOutputStream()){
                 int data;
                 while ((data = din.read()) != -1) {
                     bout.write((byte) data);
@@ -257,15 +256,6 @@
             } catch (Exception e) {
                 throw new BuildException(e);
             } finally {
-                try {
-                    din.close();
-                } catch (IOException ioe) {
-                    // swallow if there was an error before so that
-                    // original error will be passed up
-                    if (success) {
-                        throw new BuildException(ioe); //NOSONAR
-                    }
-                }
             }
         } else {
             try {
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java
index 4ce07ff..d564eb4 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java
@@ -41,10 +41,8 @@
     private final Session session;
     private final boolean verbose;
     private final boolean compressed;
-    private LogListener listener = new LogListener() {
-        public void log(final String message) {
-            // do nothing;
-        }
+    private LogListener listener = message -> {
+        // do nothing;
     };
 
     /**
@@ -97,9 +95,7 @@
      * @throws JSchException on error
      */
     protected ChannelSftp openSftpChannel() throws JSchException {
-        final ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
-
-        return channel;
+        return (ChannelSftp) session.openChannel("sftp");
     }
 
     /**
@@ -132,8 +128,9 @@
         if (b == -1) {
             // didn't receive any response
             throw new BuildException("No response from server");
-        } else if (b != 0) {
-            final StringBuffer sb = new StringBuffer();
+        }
+        if (b != 0) {
+            final StringBuilder sb = new StringBuilder();
 
             int c = in.read();
             while (c > 0 && c != '\n') {
@@ -270,12 +267,12 @@
         private long totalLength = 0;
         private int percentTransmitted = 0;
 
+        @Override
         public void init(final int op, final String src, final String dest, final long max) {
             initFileSize = max;
-            totalLength = 0;
-            percentTransmitted = 0;
         }
 
+        @Override
         public boolean count(final long len) {
             totalLength += len;
             percentTransmitted = trackProgress(initFileSize,
@@ -284,6 +281,7 @@
             return true;
         }
 
+        @Override
         public void end() {
         }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Directory.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Directory.java
index db857fc..e428693 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Directory.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Directory.java
@@ -22,6 +22,7 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Set;
 import java.util.StringTokenizer;
 
@@ -31,8 +32,8 @@
 public class Directory {
 
     private File directory;
-    private Set childDirectories;
-    private ArrayList files;
+    private Set<Directory> childDirectories;
+    private List<File> files;
     private Directory parent;
 
     /**
@@ -50,8 +51,8 @@
      */
     public Directory(File directory, Directory parent) {
         this.parent = parent;
-        this.childDirectories = new LinkedHashSet();
-        this.files = new ArrayList();
+        this.childDirectories = new LinkedHashSet<>();
+        this.files = new ArrayList<>();
         this.directory = directory;
     }
 
@@ -77,7 +78,7 @@
      * Get an iterator over the child Directories.
      * @return an iterator
      */
-    public Iterator directoryIterator() {
+    public Iterator<Directory> directoryIterator() {
         return childDirectories.iterator();
     }
 
@@ -85,7 +86,7 @@
      * Get an iterator over the files.
      * @return an iterator
      */
-    public Iterator filesIterator() {
+    public Iterator<File> filesIterator() {
         return files.iterator();
     }
 
@@ -119,8 +120,7 @@
      * @return the child directory, or null if not found
      */
     public Directory getChild(File dir) {
-        for (Iterator i = childDirectories.iterator(); i.hasNext();) {
-            Directory current = (Directory) i.next();
+        for (Directory current : childDirectories) {
             if (current.getDirectory().equals(dir)) {
                 return current;
             }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java
index 591d610..1dcf3b9 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java
@@ -228,6 +228,7 @@
      * This initializes the known hosts and sets the default port.
      * @throws BuildException on error
      */
+    @Override
     public void init() throws BuildException {
         super.init();
         this.knownHosts = System.getProperty("user.home") + "/.ssh/known_hosts";
@@ -243,14 +244,17 @@
         final JSch jsch = new JSch();
         final SSHBase base = this;
         if (verbose) {
-            JSch.setLogger(new com.jcraft.jsch.Logger(){
-                    public boolean isEnabled(final int level){
-                        return true;
-                    }
-                    public void log(final int level, final String message){
-                        base.log(message, Project.MSG_INFO);
-                    }
-                });
+            JSch.setLogger(new com.jcraft.jsch.Logger() {
+                @Override
+                public boolean isEnabled(final int level) {
+                    return true;
+                }
+
+                @Override
+                public void log(final int level, final String message) {
+                    base.log(message, Project.MSG_INFO);
+                }
+            });
         }
         if (null != userInfo.getKeyfile()) {
             jsch.addIdentity(userInfo.getKeyfile());
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java
index 80e0dda..c3e4821 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java
@@ -22,13 +22,13 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.StringReader;
+import java.nio.file.Files;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -298,18 +298,16 @@
             + (inputProperty != null ? 1 : 0)
             + (inputString != null ? 1 : 0);
         if (numberOfInputs > 1) {
-            throw new BuildException("You can't specify more than one of"
-                                     + " inputFile, inputProperty and"
-                                     + " inputString.");
+            throw new BuildException(
+                "You can't specify more than one of inputFile, inputProperty and inputString.");
         }
         if (inputFile != null && !inputFile.exists()) {
-            throw new BuildException("The input file "
-                                     + inputFile.getAbsolutePath()
-                                     + " does not exist.");
+            throw new BuildException("The input file %s does not exist.",
+                inputFile.getAbsolutePath());
         }
 
         Session session = null;
-        final StringBuffer output = new StringBuffer();
+        final StringBuilder output = new StringBuilder();
         try {
             session = openSession();
             /* called once */
@@ -317,32 +315,27 @@
                 log("cmd : " + command, Project.MSG_INFO);
                 executeCommand(session, command, output);
             } else { // read command resource and execute for each command
-                try {
-                    final BufferedReader br = new BufferedReader(
-                            new InputStreamReader(commandResource.getInputStream()));
-                    String cmd;
-                    while ((cmd = br.readLine()) != null) {
+                try (final BufferedReader br = new BufferedReader(
+                    new InputStreamReader(commandResource.getInputStream()))) {
+                    final Session s = session;
+                    br.lines().forEach(cmd -> {
                         log("cmd : " + cmd, Project.MSG_INFO);
                         output.append(cmd).append(" : ");
-                        executeCommand(session, cmd, output);
+                        executeCommand(s, cmd, output);
                         output.append("\n");
-                    }
-                    FileUtils.close(br);
+                    });
                 } catch (final IOException e) {
                     if (getFailonerror()) {
                         throw new BuildException(e);
-                    } else {
-                        log("Caught exception: " + e.getMessage(),
-                            Project.MSG_ERR);
                     }
+                    log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
                 }
             }
         } catch (final JSchException e) {
             if (getFailonerror()) {
                 throw new BuildException(e);
-            } else {
-                log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
             }
+            log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
         } finally {
             if (outputProperty != null) {
                 getProject().setNewProperty(outputProperty, output.toString());
@@ -353,7 +346,7 @@
         }
     }
 
-    private void executeCommand(final Session session, final String cmd, final StringBuffer sb)
+    private void executeCommand(final Session session, final String cmd, final StringBuilder sb)
         throws BuildException {
         final ByteArrayOutputStream out = new ByteArrayOutputStream();
         final ByteArrayOutputStream errout = new ByteArrayOutputStream();
@@ -363,7 +356,7 @@
         InputStream istream = null;
         if (inputFile != null) {
             try {
-                istream = new FileInputStream(inputFile);
+                istream = Files.newInputStream(inputFile.toPath());
             } catch (final IOException e) {
                 // because we checked the existence before, this one
                 // shouldn't happen What if the file exists, but there
@@ -426,9 +419,8 @@
                 thread = null;
                 if (getFailonerror()) {
                     throw new BuildException(TIMEOUT_MESSAGE);
-                } else {
-                    log(TIMEOUT_MESSAGE, Project.MSG_ERR);
                 }
+                log(TIMEOUT_MESSAGE, Project.MSG_ERR);
             } else {
                 // stdout to outputFile
                 if (outputFile != null) {
@@ -453,9 +445,8 @@
                     final String msg = "Remote command failed with exit status " + ec;
                     if (getFailonerror()) {
                         throw new BuildException(msg);
-                    } else {
-                        log(msg, Project.MSG_ERR);
                     }
+                    log(msg, Project.MSG_ERR);
                 }
             }
         } catch (final BuildException e) {
@@ -464,23 +455,19 @@
             if (e.getMessage().indexOf("session is down") >= 0) {
                 if (getFailonerror()) {
                     throw new BuildException(TIMEOUT_MESSAGE, e);
-                } else {
-                    log(TIMEOUT_MESSAGE, Project.MSG_ERR);
                 }
+                log(TIMEOUT_MESSAGE, Project.MSG_ERR);
             } else {
                 if (getFailonerror()) {
                     throw new BuildException(e);
-                } else {
-                    log("Caught exception: " + e.getMessage(),
-                        Project.MSG_ERR);
                 }
+                log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
             }
         } catch (final Exception e) {
             if (getFailonerror()) {
                 throw new BuildException(e);
-            } else {
-                log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
             }
+            log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
         } finally {
             sb.append(out.toString());
             FileUtils.close(istream);
@@ -497,24 +484,17 @@
      */
     private void writeToFile(final String from, final boolean append, final File to)
         throws IOException {
-        FileWriter out = null;
-        try {
-            out = new FileWriter(to.getAbsolutePath(), append);
+        try (FileWriter out = new FileWriter(to.getAbsolutePath(), append)) {
             final StringReader in = new StringReader(from);
             final char[] buffer = new char[BUFFER_SIZE];
-            int bytesRead;
             while (true) {
-                bytesRead = in.read(buffer);
+                int bytesRead = in.read(buffer);
                 if (bytesRead == -1) {
                     break;
                 }
                 out.write(buffer, 0, bytesRead);
             }
             out.flush();
-        } finally {
-            if (out != null) {
-                out.close();
-            }
         }
     }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java
index fb80c8c..016b90e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java
@@ -19,7 +19,6 @@
 package org.apache.tools.ant.taskdefs.optional.ssh;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
@@ -29,7 +28,6 @@
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
 import org.apache.tools.ant.TaskContainer;
-
 import com.jcraft.jsch.JSchException;
 import com.jcraft.jsch.Session;
 
@@ -45,10 +43,10 @@
     /** units are milliseconds, default is 0=infinite */
     private long maxwait = 0;
 
-    private final Vector localTunnels = new Vector();
-    private final Set localPortsUsed = new TreeSet();
-    private final Vector remoteTunnels = new Vector();
-    private final Set remotePortsUsed = new TreeSet();
+    private final List<LocalTunnel> localTunnels = new Vector<>();
+    private final Set<Integer> localPortsUsed = new TreeSet<>();
+    private final List<RemoteTunnel> remoteTunnels = new Vector<>();
+    private final Set<Integer> remotePortsUsed = new TreeSet<>();
     private NestedSequential nestedSequential = null;
 
     private static final String TIMEOUT_MESSAGE =
@@ -56,7 +54,7 @@
 
 
     /** Optional Vector holding the nested tasks */
-    private final Vector nestedTasks = new Vector();
+    private final List<Task> nestedTasks = new Vector<>();
 
     /**
      * Add a nested task to Sequential.
@@ -64,7 +62,7 @@
      * @param nestedTask Nested task to execute sequentially
      */
     public void addTask(final Task nestedTask) {
-        nestedTasks.addElement(nestedTask);
+        nestedTasks.add(nestedTask);
     }
 
     /**
@@ -147,48 +145,38 @@
             throw new BuildException("Missing sequential element.");
         }
 
-
         Session session = null;
         try {
             // establish the session
             session = openSession();
             session.setTimeout((int) maxwait);
 
-            for (final Iterator i = localTunnels.iterator(); i.hasNext();) {
-                final LocalTunnel tunnel = (LocalTunnel) i.next();
+            for (LocalTunnel tunnel : localTunnels) {
                 session.setPortForwardingL(tunnel.getLPort(),
                                            tunnel.getRHost(),
                                            tunnel.getRPort());
             }
 
-            for (final Iterator i = remoteTunnels.iterator(); i.hasNext();) {
-                final RemoteTunnel tunnel = (RemoteTunnel) i.next();
+            for (RemoteTunnel tunnel : remoteTunnels) {
                 session.setPortForwardingR(tunnel.getRPort(),
                                            tunnel.getLHost(),
                                            tunnel.getLPort());
             }
 
-            for (final Iterator i = nestedSequential.getNested().iterator();
-                 i.hasNext();) {
-                final Task nestedTask = (Task) i.next();
-                nestedTask.perform();
-            }
+            nestedSequential.getNested().forEach(Task::perform);
             // completed successfully
 
         } catch (final JSchException e) {
             if (e.getMessage().indexOf("session is down") >= 0) {
                 if (getFailonerror()) {
                     throw new BuildException(TIMEOUT_MESSAGE, e);
-                } else {
-                    log(TIMEOUT_MESSAGE, Project.MSG_ERR);
                 }
+                log(TIMEOUT_MESSAGE, Project.MSG_ERR);
             } else {
                 if (getFailonerror()) {
                     throw new BuildException(e);
-                } else {
-                    log("Caught exception: " + e.getMessage(),
-                        Project.MSG_ERR);
                 }
+                log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
             }
         } catch (final BuildException e) {
             // avoid wrapping it into yet another BuildException further down
@@ -196,9 +184,8 @@
         } catch (final Exception e) {
             if (getFailonerror()) {
                 throw new BuildException(e);
-            } else {
-                log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
             }
+            log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
         } finally {
             if (session != null && session.isConnected()) {
                 session.disconnect();
@@ -219,34 +206,44 @@
     }
 
     public class LocalTunnel {
-        public LocalTunnel() {}
 
         int lport = 0;
         String rhost = null;
         int rport = 0;
+
         public void setLPort(final int lport) {
-            final Integer portKey = new Integer(lport);
+            final Integer portKey = Integer.valueOf(lport);
             if (localPortsUsed.contains(portKey)) {
-                throw new BuildException("Multiple local tunnels defined to"
-                                         + " use same local port " + lport);
+                throw new BuildException(
+                    "Multiple local tunnels defined to use same local port %d",
+                    lport);
             }
             localPortsUsed.add(portKey);
             this.lport = lport;
         }
-        public void setRHost(final String rhost) { this.rhost = rhost; }
-        public void setRPort(final int rport) { this.rport = rport; }
+
+        public void setRHost(final String rhost) {
+            this.rhost = rhost;
+        }
+
+        public void setRPort(final int rport) {
+            this.rport = rport;
+        }
+
         public int getLPort() {
             if (lport == 0) {
                 throw new BuildException("lport is required for LocalTunnel.");
             }
             return lport;
         }
+
         public String getRHost() {
             if (rhost == null) {
                 throw new BuildException("rhost is required for LocalTunnel.");
             }
             return rhost;
         }
+
         public int getRPort() {
             if (rport == 0) {
                 throw new BuildException("rport is required for LocalTunnel.");
@@ -256,34 +253,44 @@
     }
 
     public class RemoteTunnel {
-        public RemoteTunnel() {}
 
         int lport = 0;
         String lhost = null;
         int rport = 0;
-        public void setLPort(final int lport) { this.lport = lport; }
-        public void setLHost(final String lhost) { this.lhost = lhost; }
+
+        public void setLPort(final int lport) {
+            this.lport = lport;
+        }
+
+        public void setLHost(final String lhost) {
+            this.lhost = lhost;
+        }
+
         public void setRPort(final int rport) {
-            final Integer portKey = new Integer(rport);
+            final Integer portKey = Integer.valueOf(rport);
             if (remotePortsUsed.contains(portKey)) {
-                throw new BuildException("Multiple remote tunnels defined to"
-                                         + " use same remote port " + rport);
+                throw new BuildException(
+                    "Multiple remote tunnels defined to use same remote port %d",
+                    rport);
             }
             remotePortsUsed.add(portKey);
             this.rport = rport;
         }
+
         public int getLPort() {
             if (lport == 0) {
                 throw new BuildException("lport is required for RemoteTunnel.");
             }
             return lport;
         }
+
         public String getLHost() {
             if (lhost == null) {
                 throw new BuildException("lhost is required for RemoteTunnel.");
             }
             return lhost;
         }
+
         public int getRPort() {
             if (rport == 0) {
                 throw new BuildException("rport is required for RemoteTunnel.");
@@ -310,13 +317,14 @@
      * This is a simple task container.
      */
     public static class NestedSequential implements TaskContainer {
-        private final List<Task> nested = new ArrayList<Task>();
+        private final List<Task> nested = new ArrayList<>();
 
         /**
          * Add a task or type to the container.
          *
          * @param task an unknown element.
          */
+        @Override
         public void addTask(final Task task) {
             nested.add(task);
         }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHUserInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHUserInfo.java
index 54e7029..455d12b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHUserInfo.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHUserInfo.java
@@ -35,8 +35,7 @@
 
     /** Constructor for SSHUserInfo. */
     public SSHUserInfo() {
-        super();
-        this.trustAllCertificates = false;
+        this(null, false);
     }
 
     /**
@@ -71,6 +70,7 @@
      * Gets the user's password.
      * @return the user's password
      */
+    @Override
     public String getPassword() {
         return password;
     }
@@ -135,6 +135,7 @@
      * Returns the passphrase.
      * @return String
      */
+    @Override
     public String getPassphrase() {
         return passphrase;
     }
@@ -160,6 +161,7 @@
      * @param message ignored
      * @return true always
      */
+    @Override
     public boolean promptPassphrase(String message) {
         return true;
     }
@@ -169,6 +171,7 @@
      * @param passwordPrompt ignored
      * @return true the first time this is called, false otherwise
      */
+    @Override
     public boolean promptPassword(String passwordPrompt) {
         return true;
     }
@@ -178,6 +181,7 @@
      * @param message ignored
      * @return the value of trustAllCertificates
      */
+    @Override
     public boolean promptYesNo(String message) {
         return trustAllCertificates;
     }
@@ -187,6 +191,7 @@
      * Implement the UserInfo interface (noop).
      * @param message ignored
      */
+    @Override
     public void showMessage(String message) {
         //log(message, Project.MSG_DEBUG);
     }
@@ -201,6 +206,7 @@
      * @return the password in an size one array if there is a password
      *         and if the prompt and echo checks pass.
      */
+    @Override
     public String[] promptKeyboardInteractive(String destination,
                                               String name,
                                               String instruction,
@@ -209,9 +215,7 @@
         if (prompt.length != 1 || echo[0] || this.password == null) {
             return null;
         }
-        String[] response = new String[1];
-        response[0] = this.password;
-        return response;
+        return new String[] { this.password };
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
index 4e04a46..24217f4 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
@@ -21,9 +21,10 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.DirectoryScanner;
@@ -165,11 +166,9 @@
 
     private static void validateRemoteUri(final String type, final String aToUri) {
         if (!isRemoteUri(aToUri)) {
-            throw new BuildException(type + " '" + aToUri + "' is invalid. "
-                                     + "The 'remoteToDir' attribute must "
-                                     + "have syntax like the "
-                                     + "following: user:password@host:/path"
-                                     + " - the :password part is optional");
+            throw new BuildException(
+                "%s '%s' is invalid. The 'remoteToDir' attribute must have syntax like the following: user:password@host:/path - the :password part is optional",
+                type, aToUri);
         }
     }
 
@@ -240,7 +239,7 @@
      */
     public void add(ResourceCollection res) {
         if (rcs == null) {
-            rcs = new LinkedList<ResourceCollection>();
+            rcs = new LinkedList<>();
         }
         rcs.add(res);
     }
@@ -282,24 +281,21 @@
                 throw new BuildException(
                     "Copying from a remote server to a remote server is not supported.");
             } else {
-                throw new BuildException("'todir' and 'file' attributes "
-                    + "must have syntax like the following: "
-                    + "user:password@host:/path");
+                throw new BuildException(
+                    "'todir' and 'file' attributes must have syntax like the following: user:password@host:/path");
             }
         } catch (final Exception e) {
             if (getFailonerror()) {
-                if(e instanceof BuildException) {
+                if (e instanceof BuildException) {
                     final BuildException be = (BuildException) e;
-                    if(be.getLocation() == null) {
+                    if (be.getLocation() == null) {
                         be.setLocation(getLocation());
                     }
                     throw be;
-                } else {
-                    throw new BuildException(e);
                 }
-            } else {
-                log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
+                throw new BuildException(e);
             }
+            log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
         }
     }
 
@@ -341,9 +337,8 @@
 
         Session session = null;
         try {
-            final List<Directory> list = new ArrayList<Directory>(rcs.size());
-            for (final Iterator<ResourceCollection> i = rcs.iterator(); i.hasNext();) {
-                final ResourceCollection rc = (ResourceCollection) i.next();
+            final List<Directory> list = new ArrayList<>(rcs.size());
+            for (ResourceCollection rc : rcs) {
                 if (rc instanceof FileSet && rc.isFilesystemOnly()) {
                     FileSet fs = (FileSet) rc;
                     final Directory d = createDirectory(fs);
@@ -351,15 +346,15 @@
                         list.add(d);
                     }
                 } else {
-                       List<Directory> ds = createDirectoryCollection(rc);
-                       if (ds !=null) {
-                               list.addAll(ds);
-                       }
+                    List<Directory> ds = createDirectoryCollection(rc);
+                    if (ds != null) {
+                        list.addAll(ds);
+                    }
                 }
             }
             if (!list.isEmpty()) {
                 session = openSession();
-                ScpToMessage message = null;
+                ScpToMessage message;
                 if (!isSftp) {
                     message = new ScpToMessage(getVerbose(), compressed, session,
                                                list, file, preserveLastModified);
@@ -443,19 +438,19 @@
 
         if (getUserInfo().getPassword() == null
             && getUserInfo().getKeyfile() == null) {
-            throw new BuildException("neither password nor keyfile for user "
-                                     + getUserInfo().getName() + " has been "
-                                     + "given.  Can't authenticate.");
+            throw new BuildException(
+                "neither password nor keyfile for user %s has been given.  Can't authenticate.",
+                getUserInfo().getName());
         }
 
         final int indexOfPath = uri.indexOf(':', indexOfAt + 1);
         if (indexOfPath == -1) {
-            throw new BuildException("no remote path in " + uri);
+            throw new BuildException("no remote path in %s", uri);
         }
 
         setHost(uri.substring(indexOfAt + 1, indexOfPath));
         String remotePath = uri.substring(indexOfPath + 1);
-        if (remotePath.equals("")) {
+        if (remotePath.isEmpty()) {
             remotePath = ".";
         }
         return remotePath;
@@ -472,28 +467,26 @@
 
     private Directory createDirectory(final FileSet set) {
         final DirectoryScanner scanner = set.getDirectoryScanner(getProject());
-        Directory root = new Directory(scanner.getBasedir());
         final String[] files = scanner.getIncludedFiles();
-        if (files.length != 0) {
-            for (int j = 0; j < files.length; j++) {
-                final String[] path = Directory.getPath(files[j]);
-                Directory current = root;
-                File currentParent = scanner.getBasedir();
-                for (int i = 0; i < path.length; i++) {
-                    final File file = new File(currentParent, path[i]);
-                    if (file.isDirectory()) {
-                        current.addDirectory(new Directory(file));
-                        current = current.getChild(file);
-                        currentParent = current.getDirectory();
-                    } else if (file.isFile()) {
-                        current.addFile(file);
-                    }
+        if (files.length == 0) {
+            // skip
+            return null;
+        }
+        Directory root = new Directory(scanner.getBasedir());
+        Stream.of(files).map(Directory::getPath).forEach(path -> {
+            Directory current = root;
+            File currentParent = scanner.getBasedir();
+            for (String element : path) {
+                final File file = new File(currentParent, element);
+                if (file.isDirectory()) {
+                    current.addDirectory(new Directory(file));
+                    current = current.getChild(file);
+                    currentParent = current.getDirectory();
+                } else if (file.isFile()) {
+                    current.addFile(file);
                 }
             }
-        } else {
-            // skip
-            root = null;
-        }
+        });
         return root;
     }
 
@@ -503,21 +496,24 @@
             throw new BuildException("Only FileSystem resources are supported.");
         }
 
-        List<Directory> ds = new ArrayList<Directory>();
+        List<Directory> ds = new ArrayList<>();
         for (Resource r : rc) {
                if (!r.isExists()) {
-                throw new BuildException("Could not find resource " + r.toLongString() + " to scp.");
+                throw new BuildException("Could not find resource %s to scp.",
+                    r.toLongString());
             }
 
             FileProvider fp = r.as(FileProvider.class);
             if (fp == null) {
-                throw new BuildException("Resource " + r.toLongString() + " is not a file.");
+                throw new BuildException("Resource %s is not a file.",
+                    r.toLongString());
             }
 
             FileResource fr = ResourceUtils.asFileResource(fp);
             File baseDir = fr.getBaseDir();
             if (baseDir == null) {
-                throw new BuildException("basedir for resource " + r.toLongString() + " is undefined.");
+                throw new BuildException(
+                    "basedir for resource %s is undefined.", r.toLongString());
             }
 
             // if the basedir is set, the name will be relative to that
@@ -525,9 +521,8 @@
             Directory root = new Directory(baseDir);
             Directory current = root;
             File currentParent = baseDir;
-            final String[] path = Directory.getPath(name);
-            for (int i = 0; i < path.length; i++) {
-                final File file = new File(currentParent, path[i]);
+            for (String element : Directory.getPath(name)) {
+                final File file = new File(currentParent, element);
                 if (file.isDirectory()) {
                     current.addDirectory(new Directory(file));
                     current = current.getChild(file);
@@ -537,7 +532,7 @@
                 }
             }
             ds.add(root);
-       }
+        }
         return ds;
     }
 
@@ -560,15 +555,8 @@
     }
 
     private BuildException exactlyOne(final String[] attrs, final String alt) {
-        final StringBuffer buf = new StringBuffer("Exactly one of ").append(
-                '[').append(attrs[0]);
-        for (int i = 1; i < attrs.length; i++) {
-            buf.append('|').append(attrs[i]);
-        }
-        buf.append(']');
-        if (alt != null) {
-            buf.append(" or ").append(alt);
-        }
-        return new BuildException(buf.append(" is required.").toString());
+        return new BuildException("Exactly one of [%s]%s is required",
+            Stream.of(attrs).collect(Collectors.joining("|")),
+            alt == null ? "" : " or " + alt);
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java
index bce3f78..9a385e6 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java
@@ -21,10 +21,10 @@
 import java.io.ByteArrayOutputStream;
 import java.io.EOFException;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.file.Files;
 
 import org.apache.tools.ant.util.FileUtils;
 
@@ -149,6 +149,7 @@
      * @throws IOException on i/o errors
      * @throws JSchException on errors detected by scp
      */
+    @Override
     public void execute() throws IOException, JSchException {
         String command = "scp -f ";
         if (isRecursive) {
@@ -220,9 +221,9 @@
 
     private File parseAndCreateDirectory(final String serverResponse,
                                          final File localFile) {
-        int start = serverResponse.indexOf(" ");
+        int start = serverResponse.indexOf(' ');
         // appears that the next token is not used and it's zero.
-        start = serverResponse.indexOf(" ", start + 1);
+        start = serverResponse.indexOf(' ', start + 1);
         final String directoryName = serverResponse.substring(start + 1);
         if (localFile.isDirectory()) {
             final File dir = new File(localFile, directoryName);
@@ -239,13 +240,13 @@
                                    final InputStream in)
         throws IOException, JSchException  {
         int start = 0;
-        int end = serverResponse.indexOf(" ", start + 1);
+        int end = serverResponse.indexOf(' ', start + 1);
         start = end + 1;
-        end = serverResponse.indexOf(" ", start + 1);
+        end = serverResponse.indexOf(' ', start + 1);
         final long filesize = Long.parseLong(serverResponse.substring(start, end));
         final String filename = serverResponse.substring(end + 1);
         log("Receiving: " + filename + " : " + filesize);
-        final File transferFile = (localFile.isDirectory())
+        final File transferFile = localFile.isDirectory()
                 ? new File(localFile, filename)
                 : localFile;
         fetchFile(transferFile, filesize, out, in);
@@ -262,7 +263,7 @@
         sendAck(out);
 
         // read a content of lfile
-        final FileOutputStream fos = new FileOutputStream(localFile);
+        final OutputStream fos = Files.newOutputStream(localFile.toPath());
         int length;
         long totalLength = 0;
         final long startTime = System.currentTimeMillis();
@@ -277,7 +278,7 @@
         try {
             while (true) {
                 length = in.read(buf, 0,
-                                 (BUFFER_SIZE < filesize) ? BUFFER_SIZE
+                                 BUFFER_SIZE < filesize ? BUFFER_SIZE
                                                           : (int) filesize);
                 if (length < 0) {
                     throw new EOFException("Unexpected end of stream.");
@@ -327,10 +328,10 @@
      * returns the directory part of the remote file, if any.
      */
     private static String remoteDir(final String remoteFile) {
-        int index = remoteFile.lastIndexOf("/");
+        int index = remoteFile.lastIndexOf('/');
         if (index < 0) {
-            index = remoteFile.lastIndexOf("\\");
+            index = remoteFile.lastIndexOf('\\');
         }
-        return index > -1 ? remoteFile.substring(0, index + 1) : "";
+        return index < 0 ? "" : remoteFile.substring(0, index + 1);
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java
index 04f72d2..886d06d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java
@@ -20,7 +20,7 @@
 
 import java.io.File;
 import java.io.IOException;
-
+import java.util.List;
 import org.apache.tools.ant.util.FileUtils;
 
 import com.jcraft.jsch.ChannelSftp;
@@ -103,6 +103,7 @@
      * @throws IOException on i/o errors
      * @throws JSchException on errors detected by scp
      */
+    @Override
     public void execute() throws IOException, JSchException {
         final ChannelSftp channel = openSftpChannel();
         try {
@@ -117,9 +118,9 @@
             }
             getDir(channel, remoteFile, localFile);
         } catch (final SftpException e) {
-            final JSchException schException = new JSchException("Could not get '"+ remoteFile
-                    +"' to '"+localFile+"' - "
-                    +e.toString());
+            final JSchException schException =
+                new JSchException("Could not get '" + remoteFile + "' to '"
+                    + localFile + "' - " + e.toString());
             schException.initCause(e);
             throw schException;
         } finally {
@@ -143,13 +144,12 @@
         if (!localFile.exists()) {
             localFile.mkdirs();
         }
-        final java.util.Vector files = channel.ls(remoteFile);
-        final int size = files.size();
-        for (int i = 0; i < size; i++) {
-            final ChannelSftp.LsEntry le = (ChannelSftp.LsEntry) files.elementAt(i);
+        @SuppressWarnings("unchecked")
+        final List<ChannelSftp.LsEntry> files = channel.ls(remoteFile);
+        for (ChannelSftp.LsEntry le : files) {
             final String name = le.getFilename();
             if (le.getAttrs().isDir()) {
-                if (name.equals(".") || name.equals("..")) {
+                if (".".equals(name) || "..".equals(name)) {
                     continue;
                 }
                 getDir(channel,
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java
index 650804f..2fc30a5 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java
@@ -19,10 +19,10 @@
 package org.apache.tools.ant.taskdefs.optional.ssh;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.file.Files;
 import java.util.Iterator;
 import java.util.List;
 
@@ -42,7 +42,7 @@
 
     private File localFile;
     private String remotePath;
-    private List directoryList;
+    private List<Directory> directoryList;
     private Integer fileMode, dirMode;
     private boolean preserveLastModified;
 
@@ -124,7 +124,7 @@
      */
     public ScpToMessage(final boolean verbose,
                         final Session session,
-                        final List aDirectoryList,
+                        final List<Directory> aDirectoryList,
                         final String aRemotePath,
                         final boolean preserveLastModified) {
         this(verbose, false, session, aDirectoryList, aRemotePath, preserveLastModified);
@@ -143,7 +143,7 @@
     public ScpToMessage(final boolean verbose,
                         final boolean compressed,
                         final Session session,
-                        final List aDirectoryList,
+                        final List<Directory> aDirectoryList,
                         final String aRemotePath,
                         final boolean preserveLastModified) {
         this(verbose, compressed, session, aRemotePath);
@@ -176,7 +176,7 @@
      */
     public ScpToMessage(final boolean verbose,
                         final Session session,
-                        final List aDirectoryList,
+                        final List<Directory> aDirectoryList,
                         final String aRemotePath) {
         this(verbose, session, aDirectoryList, aRemotePath, false);
     }
@@ -184,19 +184,6 @@
     /**
      * Constructor for ScpToMessage.
      * @param verbose if true do verbose logging
-     * @param session the scp session to use
-     * @param aRemotePath the remote path
-     * @since Ant 1.6.2
-     */
-    private ScpToMessage(final boolean verbose,
-                         final Session session,
-                         final String aRemotePath) {
-        this(verbose, false, session, aRemotePath);
-    }
-
-    /**
-     * Constructor for ScpToMessage.
-     * @param verbose if true do verbose logging
      * @param compressed if true use compression
      * @param session the scp session to use
      * @param aRemotePath the remote path
@@ -229,7 +216,7 @@
      * @param aRemotePath the remote path
      */
     public ScpToMessage(final Session session,
-                         final List aDirectoryList,
+                         final List<Directory> aDirectoryList,
                          final String aRemotePath) {
         this(false, session, aDirectoryList, aRemotePath);
     }
@@ -262,7 +249,6 @@
         final String cmd = sb.toString();
         final Channel channel = openExecChannel(cmd);
         try {
-
             final OutputStream out = channel.getOutputStream();
             final InputStream in = channel.getInputStream();
 
@@ -294,8 +280,7 @@
             channel.connect();
 
             waitForAck(in);
-            for (final Iterator i = directoryList.iterator(); i.hasNext();) {
-                final Directory current = (Directory) i.next();
+            for (Directory current : directoryList) {
                 sendDirectory(current, in, out);
             }
         } finally {
@@ -308,12 +293,11 @@
     private void sendDirectory(final Directory current,
                                final InputStream in,
                                final OutputStream out) throws IOException {
-        for (final Iterator fileIt = current.filesIterator(); fileIt.hasNext();) {
-            sendFileToRemote((File) fileIt.next(), in, out);
+        for (final Iterator<File> fileIt = current.filesIterator(); fileIt.hasNext();) {
+            sendFileToRemote(fileIt.next(), in, out);
         }
-        for (final Iterator dirIt = current.directoryIterator(); dirIt.hasNext();) {
-            final Directory dir = (Directory) dirIt.next();
-            sendDirectoryToRemote(dir, in, out);
+        for (final Iterator<Directory> dirIt = current.directoryIterator(); dirIt.hasNext();) {
+            sendDirectoryToRemote(dirIt.next(), in, out);
         }
     }
 
@@ -363,7 +347,7 @@
         waitForAck(in);
 
         // send a content of lfile
-        final FileInputStream fis = new FileInputStream(localFile);
+        final InputStream fis = Files.newInputStream(localFile.toPath());
         final byte[] buf = new byte[BUFFER_SIZE];
         final long startTime = System.currentTimeMillis();
         long totalLength = 0;
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java
index 093ce2a..ef3e2ce 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java
@@ -38,7 +38,7 @@
 
     private File localFile;
     private final String remotePath;
-    private List directoryList;
+    private List<Directory> directoryList;
     private final boolean preserveLastModified;
 
     /**
@@ -88,7 +88,7 @@
      */
     public ScpToMessageBySftp(final boolean verbose,
                               final Session session,
-                              final List aDirectoryList,
+                              final List<Directory> aDirectoryList,
                               final String aRemotePath) {
         this(verbose, session, aDirectoryList, aRemotePath, false);
     }
@@ -105,7 +105,7 @@
      */
     public ScpToMessageBySftp(final boolean verbose,
                               final Session session,
-                              final List aDirectoryList,
+                              final List<Directory> aDirectoryList,
                               final String aRemotePath,
                               final boolean preserveLastModified) {
         this(verbose, session, aRemotePath, preserveLastModified);
@@ -150,7 +150,7 @@
      * @param aRemotePath the remote path
      */
     public ScpToMessageBySftp(final Session session,
-                              final List aDirectoryList,
+                              final List<Directory> aDirectoryList,
                               final String aRemotePath) {
         this(false, session, aDirectoryList, aRemotePath);
     }
@@ -212,21 +212,19 @@
                 throw new JSchException("Could not CD to '" + remotePath
                                         + "' - " + e.toString(), e);
             }
-            Directory current = null;
-            try {
-                for (final Iterator i = directoryList.iterator(); i.hasNext();) {
-                    current = (Directory) i.next();
+            for (Directory current : directoryList) {
+                try {
                     if (getVerbose()) {
                         log("Sending directory " + current);
                     }
                     sendDirectory(channel, current);
+                } catch (final SftpException e) {
+                    String msg = "Error sending directory";
+                    if (current != null && current.getDirectory() != null) {
+                        msg += " '" + current.getDirectory().getName() + "'";
+                    }
+                    throw new JSchException(msg, e);
                 }
-            } catch (final SftpException e) {
-                String msg = "Error sending directory";
-                if (current != null && current.getDirectory() != null) {
-                    msg += " '" + current.getDirectory().getName() + "'";
-                }
-                throw new JSchException(msg, e);
             }
         } finally {
             if (channel != null) {
@@ -238,12 +236,11 @@
     private void sendDirectory(final ChannelSftp channel,
                                final Directory current)
         throws IOException, SftpException {
-        for (final Iterator fileIt = current.filesIterator(); fileIt.hasNext();) {
-            sendFileToRemote(channel, (File) fileIt.next(), null);
+        for (final Iterator<File> fileIt = current.filesIterator(); fileIt.hasNext();) {
+            sendFileToRemote(channel, fileIt.next(), null);
         }
-        for (final Iterator dirIt = current.directoryIterator(); dirIt.hasNext();) {
-            final Directory dir = (Directory) dirIt.next();
-            sendDirectoryToRemote(channel, dir);
+        for (final Iterator<Directory> dirIt = current.directoryIterator(); dirIt.hasNext();) {
+            sendDirectoryToRemote(channel, dirIt.next());
         }
     }
 
@@ -329,6 +326,7 @@
      * Get the local file.
      * @return the local file.
      */
+    @Override
     public File getLocalFile() {
         return localFile;
     }
@@ -337,6 +335,7 @@
      * Get the remote path.
      * @return the remote path.
      */
+    @Override
     public String getRemotePath() {
         return remotePath;
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/testing/BlockFor.java b/src/main/org/apache/tools/ant/taskdefs/optional/testing/BlockFor.java
index 4b2978a..9d8338e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/testing/BlockFor.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/testing/BlockFor.java
@@ -54,6 +54,7 @@
      * @throws BuildTimeoutException on timeout, using the text in {@link #text}
      *
      */
+    @Override
     protected void processTimeout() throws BuildTimeoutException {
         super.processTimeout();
         throw new BuildTimeoutException(text, getLocation());
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/testing/Funtest.java b/src/main/org/apache/tools/ant/taskdefs/optional/testing/Funtest.java
index 303a9d6..4f376cf 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/testing/Funtest.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/testing/Funtest.java
@@ -58,6 +58,19 @@
  */
 
 public class Funtest extends Task {
+    /** {@value} */
+    public static final String WARN_OVERRIDING = "Overriding previous definition of ";
+    /** {@value} */
+    public static final String APPLICATION_FORCIBLY_SHUT_DOWN = "Application forcibly shut down";
+    /** {@value} */
+    public static final String SHUTDOWN_INTERRUPTED = "Shutdown interrupted";
+    /** {@value} */
+    public static final String SKIPPING_TESTS
+        = "Condition failed -skipping tests";
+    /** Application exception : {@value} */
+    public static final String APPLICATION_EXCEPTION = "Application Exception";
+    /** Teardown exception : {@value} */
+    public static final String TEARDOWN_EXCEPTION = "Teardown Exception";
 
     /**
      * A condition that must be true before the tests are run. This makes it
@@ -158,20 +171,6 @@
      */
     private BuildException taskException;
 
-    /** {@value} */
-    public static final String WARN_OVERRIDING = "Overriding previous definition of ";
-    /** {@value} */
-    public static final String APPLICATION_FORCIBLY_SHUT_DOWN = "Application forcibly shut down";
-    /** {@value} */
-    public static final String SHUTDOWN_INTERRUPTED = "Shutdown interrupted";
-    /** {@value} */
-    public static final String SKIPPING_TESTS
-        = "Condition failed -skipping tests";
-    /** Application exception : {@value} */
-    public static final String APPLICATION_EXCEPTION = "Application Exception";
-    /** Teardown exception : {@value} */
-    public static final String TEARDOWN_EXCEPTION = "Teardown Exception";
-
     /**
      * Log if the definition is overriding something
      *
@@ -378,8 +377,9 @@
      * @param role role of the task
      */
     private void validateTask(Task task, String role) {
-        if (task!=null && task.getProject() == null) {
-            throw new BuildException(role + " task is not bound to the project" + task);
+        if (task != null && task.getProject() == null) {
+            throw new BuildException("%s task is not bound to the project %s",
+                role, task);
         }
     }
 
@@ -392,6 +392,7 @@
      * test failing that is more important.
      * @throws BuildException if something was caught during the run or teardown.
      */
+    @Override
     public void execute() throws BuildException {
 
         //validation
@@ -561,12 +562,13 @@
     }
 
     private static class NestedCondition extends ConditionBase implements Condition {
+        @Override
         public boolean eval() {
             if (countConditions() != 1) {
                 throw new BuildException(
                     "A single nested condition is required.");
             }
-            return ((Condition) (getConditions().nextElement())).eval();
+            return getConditions().nextElement().eval();
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/unix/AbstractAccessTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/unix/AbstractAccessTask.java
index 2e1331f..83847ed 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/unix/AbstractAccessTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/unix/AbstractAccessTask.java
@@ -69,6 +69,7 @@
      * @ant.attribute ignore="true"
      * @param cmdl A user supplied command line that we won't accept.
      */
+    @Override
     public void setCommand(Commandline cmdl) {
         throw new BuildException(getTaskType()
                                  + " doesn\'t support the command attribute",
@@ -81,6 +82,7 @@
      * @ant.attribute ignore="true"
      * @param skip A user supplied boolean we won't accept.
      */
+    @Override
     public void setSkipEmptyFilesets(boolean skip) {
         throw new BuildException(getTaskType() + " doesn\'t support the "
                                  + "skipemptyfileset attribute",
@@ -93,6 +95,7 @@
      * @ant.attribute ignore="true"
      * @param b A user supplied boolean we won't accept.
      */
+    @Override
     public void setAddsourcefile(boolean b) {
         throw new BuildException(getTaskType()
             + " doesn\'t support the addsourcefile attribute", getLocation());
@@ -103,6 +106,7 @@
      * @return true if a valid OS, for unix this is always true, otherwise
      *              use the superclasses' test (user set).
      */
+    @Override
     protected boolean isValidOs() {
         return getOs() == null && getOsFamily() == null
             ? Os.isFamily(Os.FAMILY_UNIX) : super.isValidOs();
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chgrp.java b/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chgrp.java
index cd2cc49..529c146 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chgrp.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chgrp.java
@@ -63,6 +63,7 @@
      * Ensure that all the required arguments and other conditions have
      * been set.
      */
+    @Override
     protected void checkConfiguration() {
         if (!haveGroup) {
             throw new BuildException("Required attribute group not set in "
@@ -76,6 +77,7 @@
      *
      * @param e User supplied executable that we won't accept.
      */
+    @Override
     public void setExecutable(String e) {
         throw new BuildException(getTaskType()
                                  + " doesn\'t support the executable"
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chown.java b/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chown.java
index 02a1c17..c3d50a7 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chown.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chown.java
@@ -63,6 +63,7 @@
      * Ensure that all the required arguments and other conditions have
      * been set.
      */
+    @Override
     protected void checkConfiguration() {
         if (!haveOwner) {
             throw new BuildException("Required attribute owner not set in"
@@ -76,6 +77,7 @@
      *
      * @param e User supplied executable that we won't accept.
      */
+    @Override
     public void setExecutable(String e) {
         throw new BuildException(getTaskType()
                                  + " doesn\'t support the executable"
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java b/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java
index 86f199d..3f8ec43 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java
@@ -32,28 +32,30 @@
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintStream;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 import java.util.Properties;
-import java.util.Vector;
+import java.util.Set;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.DirectoryScanner;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.dispatch.DispatchTask;
 import org.apache.tools.ant.dispatch.DispatchUtils;
-import org.apache.tools.ant.taskdefs.Execute;
 import org.apache.tools.ant.taskdefs.LogOutputStream;
 import org.apache.tools.ant.types.FileSet;
-import org.apache.tools.ant.util.FileUtils;
-import org.apache.tools.ant.util.SymbolicLinkUtils;
 
 /**
  * Creates, Deletes, Records and Restores Symlinks.
@@ -98,28 +100,14 @@
  * &lt;symlink action=&quot;delete&quot; link=&quot;${dir.top}/foo&quot;/&gt;
  * </pre>
  *
- * <p><strong>LIMITATIONS:</strong> Because Java has no direct support for
- * handling symlinks this task divines them by comparing canonical and
- * absolute paths. On non-unix systems this may cause false positives.
- * Furthermore, any operating system on which the command
- * <code>ln -s link resource</code> is not a valid command on the command line
- * will not be able to use action=&quot;delete&quot;, action=&quot;single&quot;
- * or action=&quot;recreate&quot;, but action=&quot;record&quot; should still
- * work. Finally, the lack of support for symlinks in Java means that all links
- * are recorded as links to the <strong>canonical</strong> resource name.
- * Therefore the link: <code>link --&gt; subdir/dir/../foo.bar</code> will be
- * recorded as <code>link=subdir/foo.bar</code> and restored as
- * <code>link --&gt; subdir/foo.bar</code>.</p>
- *
+ * <p><strong>Note:</strong> Starting Ant version 1.10.2, this task relies on the symbolic link support
+ * introduced in Java 7 through the {@link Files} APIs.
  */
 public class Symlink extends DispatchTask {
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-    private static final SymbolicLinkUtils SYMLINK_UTILS =
-        SymbolicLinkUtils.getSymbolicLinkUtils();
 
     private String resource;
     private String link;
-    private Vector fileSets = new Vector();
+    private List<FileSet> fileSets = new ArrayList<>();
     private String linkFileName;
     private boolean overwrite;
     private boolean failonerror;
@@ -185,14 +173,18 @@
                 handleError("Must define the link name for symlink!");
                 return;
             }
+            final Path linkPath = Paths.get(link);
+            if (!Files.isSymbolicLink(linkPath)) {
+                log("Skipping deletion of " + linkPath + " since it's not a symlink", Project.MSG_VERBOSE);
+                // just ignore and silently return (this is consistent
+                // with the current, 1.9.x versions, of Ant)
+                return;
+
+            }
             log("Removing symlink: " + link);
-            SYMLINK_UTILS.deleteSymbolicLink(FILE_UTILS
-                                             .resolveFile(new File("."), link),
-                                             this);
-        } catch (FileNotFoundException fnfe) {
-            handleError(fnfe.toString());
+            deleteSymLink(linkPath);
         } catch (IOException ioe) {
-            handleError(ioe.toString());
+            handleError(ioe.getMessage());
         } finally {
             setDefaults();
         }
@@ -206,28 +198,34 @@
     public void recreate() throws BuildException {
         try {
             if (fileSets.isEmpty()) {
-                handleError("File set identifying link file(s) "
-                            + "required for action recreate");
+                handleError(
+                        "File set identifying link file(s) required for action recreate");
                 return;
             }
-            Properties links = loadLinks(fileSets);
-
-            for (Iterator kitr = links.keySet().iterator(); kitr.hasNext();) {
-                String lnk = (String) kitr.next();
-                String res = links.getProperty(lnk);
-                // handle the case where lnk points to a directory (bug 25181)
+            final Properties links = loadLinks(fileSets);
+            for (final String lnk : links.stringPropertyNames()) {
+                final String res = links.getProperty(lnk);
                 try {
-                    File test = new File(lnk);
-                    if (!SYMLINK_UTILS.isSymbolicLink(lnk)) {
-                        doLink(res, lnk);
-                    } else if (!test.getCanonicalPath().equals(
-                        new File(res).getCanonicalPath())) {
-                        SYMLINK_UTILS.deleteSymbolicLink(test, this);
-                        doLink(res, lnk);
-                    } // else lnk exists, do nothing
-                } catch (IOException ioe) {
-                    handleError("IO exception while creating link");
+                    if (Files.isSymbolicLink(Paths.get(lnk)) &&
+                            new File(lnk).getCanonicalPath().equals(new File(res).getCanonicalPath())) {
+                        // it's already a symlink and the symlink target is the same
+                        // as the target noted in the properties file. So there's no
+                        // need to recreate it
+                        log("not recreating " + lnk + " as it points to the correct target already" ,
+                            Project.MSG_DEBUG);
+                        continue;
+                    }
+                } catch (IOException e) {
+                    final String errMessage = "Failed to check if path " + lnk + " is a symbolic link, linking to " + res;
+                    if (failonerror) {
+                        throw new BuildException(errMessage, e);
+                    }
+                    // log and continue
+                    log(errMessage, Project.MSG_INFO);
+                    continue;
                 }
+                // create the link
+                this.doLink(res, lnk);
             }
         } finally {
             setDefaults();
@@ -249,30 +247,20 @@
                 handleError("Name of file to record links in required");
                 return;
             }
-            // create a hashtable to group them by parent directory:
-            Hashtable byDir = new Hashtable();
+            // create a map to group them by parent directory:
+            Map<File, List<File>> byDir = new HashMap<>();
 
             // get an Iterator of file objects representing links (canonical):
-            for (Iterator litr = findLinks(fileSets).iterator();
-                litr.hasNext();) {
-                File thisLink = (File) litr.next();
-                File parent = thisLink.getParentFile();
-                Vector v = (Vector) byDir.get(parent);
-                if (v == null) {
-                    v = new Vector();
-                    byDir.put(parent, v);
-                }
-                v.addElement(thisLink);
-            }
+            findLinks(fileSets).forEach(lnk -> byDir
+                .computeIfAbsent(lnk.getParentFile(), k -> new ArrayList<>())
+                .add(lnk));
+
             // write a Properties file in each directory:
-            for (Iterator dirs = byDir.keySet().iterator(); dirs.hasNext();) {
-                File dir = (File) dirs.next();
-                Vector linksInDir = (Vector) byDir.get(dir);
+            byDir.forEach((dir, linksInDir) -> {
                 Properties linksToStore = new Properties();
 
                 // fill up a Properties object with link and resource names:
-                for (Iterator dlnk = linksInDir.iterator(); dlnk.hasNext();) {
-                    File lnk = (File) dlnk.next();
+                for (File lnk : linksInDir) {
                     try {
                         linksToStore.put(lnk.getName(), lnk.getCanonicalPath());
                     } catch (IOException ioe) {
@@ -280,7 +268,7 @@
                     }
                 }
                 writePropertyFile(linksToStore, dir);
-            }
+            });
         } finally {
             setDefaults();
         }
@@ -367,61 +355,49 @@
      * @param set      The fileset to add.
      */
     public void addFileset(FileSet set) {
-        fileSets.addElement(set);
+        fileSets.add(set);
     }
 
     /**
      * Delete a symlink (without deleting the associated resource).
      *
-     * <p>This is a convenience method that simply invokes
-     * <code>deleteSymlink(java.io.File)</code>.
+     * <p>This is a convenience method that simply invokes {@link #deleteSymlink(File)}</p>
      *
-     * @param path    A string containing the path of the symlink to delete.
+     * @param path A string containing the path of the symlink to delete.
+     * @throws IOException If the deletion attempt fails
      *
-     * @throws IOException             If calls to <code>File.rename</code>
-     *                                   or <code>File.delete</code> fail.
-     * @deprecated use
-     * org.apache.tools.ant.util.SymbolicLinkUtils#deleteSymbolicLink
-     * instead
+     * @deprecated use {@link Files#delete(Path)} instead
      */
     @Deprecated
-    public static void deleteSymlink(String path)
-        throws IOException {
-        SYMLINK_UTILS.deleteSymbolicLink(new File(path), null);
+    public static void deleteSymlink(final String path)
+            throws IOException {
+        deleteSymlink(Paths.get(path).toFile());
     }
 
     /**
      * Delete a symlink (without deleting the associated resource).
      *
-     * <p>This is a utility method that removes a unix symlink without removing
+     * <p>This is a utility method that removes a symlink without removing
      * the resource that the symlink points to. If it is accidentally invoked
-     * on a real file, the real file will not be harmed.</p>
+     * on a real file, the real file will not be harmed and instead this method
+     * returns silently.</p>
      *
-     * <p>This method works by
-     * getting the canonical path of the link, using the canonical path to
-     * rename the resource (breaking the link) and then deleting the link.
-     * The resource is then returned to its original name inside a finally
-     * block to ensure that the resource is unharmed even in the event of
-     * an exception.</p>
+     * <p>Since Ant 1.10.2 this method relies on the {@link Files#isSymbolicLink(Path)}
+     * and {@link Files#delete(Path)} to check and delete the symlink
+     * </p>
      *
-     * <p>Since Ant 1.8.0 this method will try to delete the File object if
-     * it reports it wouldn't exist (as symlinks pointing nowhere usually do).
-     * Prior version would throw a FileNotFoundException in that case.</p>
+     * @param linkfil A <code>File</code> object of the symlink to delete. Cannot be null.
+     * @throws IOException If the attempt to delete runs into exception
      *
-     * @param linkfil    A <code>File</code> object of the symlink to delete.
-     *
-     * @throws IOException             If calls to <code>File.rename</code>,
-     *                                   <code>File.delete</code> or
-     *                                   <code>File.getCanonicalPath</code>
-     *                                   fail.
-     * @deprecated use
-     * org.apache.tools.ant.util.SymbolicLinkUtils#deleteSymbolicLink
-     * instead
+     * @deprecated use {@link Files#delete(Path)} instead
      */
     @Deprecated
-    public static void deleteSymlink(File linkfil)
-        throws IOException {
-        SYMLINK_UTILS.deleteSymbolicLink(linkfil, null);
+    public static void deleteSymlink(final File linkfil)
+            throws IOException {
+        if (!Files.isSymbolicLink(linkfil.toPath())) {
+            return;
+        }
+        deleteSymLink(linkfil.toPath());
     }
 
     /**
@@ -434,15 +410,11 @@
      */
     private void writePropertyFile(Properties properties, File dir)
         throws BuildException {
-        BufferedOutputStream bos = null;
-        try {
-            bos = new BufferedOutputStream(
-                new FileOutputStream(new File(dir, linkFileName)));
+        try (BufferedOutputStream bos = new BufferedOutputStream(
+            Files.newOutputStream(new File(dir, linkFileName).toPath()))) {
             properties.store(bos, "Symlinks from " + dir);
         } catch (IOException ioe) {
             throw new BuildException(ioe, getLocation());
-        } finally {
-            FileUtils.close(bos);
         }
     }
 
@@ -463,38 +435,50 @@
     /**
      * Conduct the actual construction of a link.
      *
-     * <p>The link is constructed by calling <code>Execute.runCommand</code>.</p>
-     *
-     * @param res   The path of the resource we are linking to.
-     * @param lnk       The name of the link we wish to make.
+     * @param res The path of the resource we are linking to.
+     * @param lnk The name of the link we wish to make.
      * @throws BuildException when things go wrong
      */
     private void doLink(String res, String lnk) throws BuildException {
-        File linkfil = new File(lnk);
-        String options = "-s";
-        if (overwrite) {
-            options += "f";
-            if (linkfil.exists()) {
-                try {
-                    SYMLINK_UTILS.deleteSymbolicLink(linkfil, this);
-                } catch (FileNotFoundException fnfe) {
-                    log("Symlink disappeared before it was deleted: " + lnk);
-                } catch (IOException ioe) {
-                    log("Unable to overwrite preexisting link or file: " + lnk,
-                        ioe, Project.MSG_INFO);
+        final Path link = Paths.get(lnk);
+        final Path target = Paths.get(res);
+        final boolean alreadyExists = Files.exists(link, LinkOption.NOFOLLOW_LINKS);
+        if (!alreadyExists) {
+            // if the path (at which the link is expected to be created) isn't already present
+            // then we just go ahead and attempt to symlink
+            try {
+                log("creating symlink " + link + " -> " + target, Project.MSG_DEBUG);
+                Files.createSymbolicLink(link, target);
+            } catch (IOException e) {
+                if (failonerror) {
+                    throw new BuildException("Failed to create symlink " + lnk + " to target " + res, e);
                 }
+                log("Unable to create symlink " + lnk + " to target " + res, e, Project.MSG_INFO);
             }
+            return;
         }
-        String[] cmd = new String[] {"ln", options, res, lnk};
+        // file already exists, see if we are allowed to overwrite
+        if (!overwrite) {
+            log("Skipping symlink creation, since file at " + lnk + " already exists and overwrite is set to false", Project.MSG_INFO);
+            return;
+        }
+        // we have been asked to overwrite, so we now do the necessary steps
+
+        // initiate a deletion of the existing file
+        final boolean existingFileDeleted = link.toFile().delete();
+        if (!existingFileDeleted) {
+            handleError("Deletion of file at " + lnk + " failed, while trying to overwrite it with a symlink");
+            return;
+        }
         try {
-            Execute.runCommand(this, cmd);
-        } catch (BuildException failedToExecute) {
+            log("creating symlink " + link + " -> " + target + " after removing original",
+                Project.MSG_DEBUG);
+            Files.createSymbolicLink(link, target);
+        } catch (IOException e) {
             if (failonerror) {
-                throw failedToExecute;
-            } else {
-                //log at the info level, and keep going.
-                log(failedToExecute.getMessage(), failedToExecute, Project.MSG_INFO);
+                throw new BuildException("Failed to create symlink " + lnk + " to target " + res, e);
             }
+            log("Unable to create symlink " + lnk + " to target " + res, e, Project.MSG_INFO);
         }
     }
 
@@ -505,33 +489,33 @@
      * &quot;record&quot;. This means that filesets are interpreted
      * as the directories in which links may be found.</p>
      *
-     * @param v   The filesets specified by the user.
-     * @return A HashSet of <code>File</code> objects containing the
-     *         links (with canonical parent directories).
+     * @param fileSets The filesets specified by the user.
+     * @return A Set of <code>File</code> objects containing the
+     * links (with canonical parent directories).
      */
-    private HashSet findLinks(Vector v) {
-        HashSet result = new HashSet();
-        final int size = v.size();
-        for (int i = 0; i < size; i++) {
-            FileSet fs = (FileSet) v.get(i);
+    private Set<File> findLinks(List<FileSet> fileSets) {
+        final Set<File> result = new HashSet<>();
+        for (FileSet fs : fileSets) {
             DirectoryScanner ds = fs.getDirectoryScanner(getProject());
-            String[][] fnd = new String[][]
-                {ds.getIncludedFiles(), ds.getIncludedDirectories()};
+
             File dir = fs.getDir(getProject());
-            for (int j = 0; j < fnd.length; j++) {
-                for (int k = 0; k < fnd[j].length; k++) {
-                    try {
-                        File f = new File(dir, fnd[j][k]);
-                        File pf = f.getParentFile();
-                        String name = f.getName();
-                        if (SYMLINK_UTILS.isSymbolicLink(pf, name)) {
-                            result.add(new File(pf.getCanonicalFile(), name));
+
+            Stream.of(ds.getIncludedFiles(), ds.getIncludedDirectories())
+                    .flatMap(Stream::of).forEach(path -> {
+                        try {
+                            final File f = new File(dir, path);
+                            final File pf = f.getParentFile();
+                            final String name = f.getName();
+                            // we use the canonical path of the parent dir in which the (potential)
+                            // link resides
+                            final File parentDirCanonicalizedFile = new File(pf.getCanonicalPath(), name);
+                            if (Files.isSymbolicLink(parentDirCanonicalizedFile.toPath())) {
+                                result.add(parentDirCanonicalizedFile);
+                            }
+                        } catch (IOException e) {
+                            handleError("IOException: " + path + " omitted");
                         }
-                    } catch (IOException e) {
-                        handleError("IOException: " + fnd[j][k] + " omitted");
-                    }
-                }
-            }
+            });
         }
         return result;
     }
@@ -544,50 +528,50 @@
      * names of the property files with the link information and the
      * subdirectories in which to look for them.</p>
      *
-     * @param v    The <code>FileSet</code>s for this task.
+     * @param fileSets    The <code>FileSet</code>s for this task.
      * @return            The links to be made.
      */
-    private Properties loadLinks(Vector v) {
+    private Properties loadLinks(List<FileSet> fileSets) {
         Properties finalList = new Properties();
         // loop through the supplied file sets:
-        final int size = v.size();
-        for (int i = 0; i < size; i++) {
-            FileSet fs = (FileSet) v.elementAt(i);
+        for (FileSet fs : fileSets) {
             DirectoryScanner ds = new DirectoryScanner();
             fs.setupDirectoryScanner(ds, getProject());
             ds.setFollowSymlinks(false);
             ds.scan();
-            String[] incs = ds.getIncludedFiles();
             File dir = fs.getDir(getProject());
 
             // load included files as properties files:
-            for (int j = 0; j < incs.length; j++) {
-                File inc = new File(dir, incs[j]);
+            for (String name : ds.getIncludedFiles()) {
+                File inc = new File(dir, name);
                 File pf = inc.getParentFile();
                 Properties lnks = new Properties();
-                InputStream is = null;
-                try {
-                    is = new BufferedInputStream(new FileInputStream(inc));
+                try (InputStream is = new BufferedInputStream(
+                    Files.newInputStream(inc.toPath()))) {
                     lnks.load(is);
                     pf = pf.getCanonicalFile();
                 } catch (FileNotFoundException fnfe) {
-                    handleError("Unable to find " + incs[j] + "; skipping it.");
+                    handleError("Unable to find " + name + "; skipping it.");
                     continue;
                 } catch (IOException ioe) {
-                    handleError("Unable to open " + incs[j]
-                                + " or its parent dir; skipping it.");
+                    handleError("Unable to open " + name
+                        + " or its parent dir; skipping it.");
                     continue;
-                } finally {
-                    FileUtils.close(is);
                 }
-                lnks.list(new PrintStream(
-                    new LogOutputStream(this, Project.MSG_INFO)));
+                try {
+                    lnks.store(new PrintStream(
+                        new LogOutputStream(this, Project.MSG_INFO)),
+                        "listing properties");
+                } catch (IOException ex) {
+                    log("failed to log unshortened properties");
+                    lnks.list(new PrintStream(
+                        new LogOutputStream(this, Project.MSG_INFO)));
+                }
                 // Write the contents to our master list of links
                 // This method assumes that all links are defined in
                 // terms of absolute paths, or paths relative to the
                 // working directory:
-                for (Iterator kitr = lnks.keySet().iterator(); kitr.hasNext();) {
-                    String key = (String) kitr.next();
+                for (String key : lnks.stringPropertyNames()) {
                     finalList.put(new File(pf, key).getAbsolutePath(),
                         lnks.getProperty(key));
                 }
@@ -595,4 +579,21 @@
         }
         return finalList;
     }
+
+    private static void deleteSymLink(final Path path) throws IOException {
+        // Implementation note: We intentionally use java.io.File#delete() instead of
+        // java.nio.file.Files#delete(Path) since it turns out that the latter doesn't
+        // update/clear the "canonical file paths cache" maintained by the JRE FileSystemProvider.
+        // Not clearing/updating that cache results in this deleted (and later recreated) symlink
+        // to point to a wrong/outdated target for a few seconds (30 seconds is the time the JRE
+        // maintains the cache entries for). All this is implementation detail of the JRE and
+        // is a JRE bug http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-December/050540.html,
+        // but given that it affects our tests (SymlinkTest#testRecreate consistently fails
+        // on MacOS/Unix) as well as the Symlink task, it makes sense to use this API instead of
+        // the Files#delete(Path) API
+        final boolean deleted = path.toFile().delete();
+        if (!deleted) {
+            throw new IOException("Could not delete symlink at " + path);
+        }
+    }
 }
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/windows/Attrib.java b/src/main/org/apache/tools/ant/taskdefs/optional/windows/Attrib.java
index 5c0b96a..8bdfe1f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/windows/Attrib.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/windows/Attrib.java
@@ -93,6 +93,7 @@
     /**
      * Check the attributes.
      */
+    @Override
     protected void checkConfiguration() {
         if (!haveAttr()) {
             throw new BuildException("Missing attribute parameter",
@@ -107,6 +108,7 @@
      * @param e ignored
      * @ant.attribute ignore="true"
      */
+    @Override
     public void setExecutable(String e) {
         throw new BuildException(getTaskType()
             + " doesn\'t support the executable attribute", getLocation());
@@ -129,6 +131,7 @@
      * @param b ignored
      * @ant.attribute ignore="true"
      */
+    @Override
     public void setAddsourcefile(boolean b) {
         throw new BuildException(getTaskType()
             + " doesn\'t support the addsourcefile attribute", getLocation());
@@ -140,6 +143,7 @@
      * @param skip ignored
      * @ant.attribute ignore="true"
      */
+    @Override
     public void setSkipEmptyFilesets(boolean skip) {
         throw new BuildException(getTaskType() + " doesn\'t support the "
                                  + "skipemptyfileset attribute",
@@ -152,6 +156,7 @@
      * @param parallel ignored
      * @ant.attribute ignore="true"
      */
+    @Override
     public void setParallel(boolean parallel) {
         throw new BuildException(getTaskType()
                                  + " doesn\'t support the parallel attribute",
@@ -164,6 +169,7 @@
      * @param max ignored
      * @ant.attribute ignore="true"
      */
+    @Override
     public void setMaxParallel(int max) {
         throw new BuildException(getTaskType()
                                  + " doesn\'t support the maxparallel attribute",
@@ -175,13 +181,14 @@
      * Default is to allow windows
      * @return true if the os is valid.
      */
+    @Override
     protected boolean isValidOs() {
         return getOs() == null && getOsFamily() == null
             ? Os.isFamily(Os.FAMILY_WINDOWS) : super.isValidOs();
     }
 
     private static String getSignString(boolean attr) {
-        return (attr ? SET : UNSET);
+        return attr ? SET : UNSET;
     }
 
     private void addArg(boolean sign, String attribute) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/xz/Unxz.java b/src/main/org/apache/tools/ant/taskdefs/optional/xz/Unxz.java
new file mode 100644
index 0000000..4502d07
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/xz/Unxz.java
@@ -0,0 +1,87 @@
+/*
+ *  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.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.xz;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Unpack;
+import org.tukaani.xz.XZInputStream;
+
+/**
+ * Expands a file that has been compressed with the XZ
+ * algorithm. Normally used to compress non-compressed archives such
+ * as TAR files.
+ *
+ * @since Ant 1.10.1
+ *
+ * @ant.task category="packaging"
+ */
+
+public class Unxz extends Unpack {
+    private static final int BUFFER_SIZE = 8 * 1024;
+    private static final String DEFAULT_EXTENSION = ".xz";
+
+    /**
+     * Get the default extension.
+     * @return the value ".xz"
+     */
+    @Override
+    protected String getDefaultExtension() {
+        return DEFAULT_EXTENSION;
+    }
+
+    /**
+     * Implement the gunzipping.
+     */
+    @Override
+    protected void extract() {
+        if (srcResource.getLastModified() > dest.lastModified()) {
+            log("Expanding " + srcResource.getName() + " to "
+                        + dest.getAbsolutePath());
+
+            try (XZInputStream zIn =
+                new XZInputStream(srcResource.getInputStream());
+                    OutputStream out = Files.newOutputStream(dest.toPath())) {
+                byte[] buffer = new byte[BUFFER_SIZE];
+                int count = 0;
+                do {
+                    out.write(buffer, 0, count);
+                    count = zIn.read(buffer, 0, buffer.length);
+                } while (count != -1);
+            } catch (IOException ioe) {
+                String msg = "Problem expanding xz " + ioe.getMessage();
+                throw new BuildException(msg, ioe, getLocation());
+            }
+        }
+    }
+
+    /**
+     * Whether this task can deal with non-file resources.
+     *
+     * <p>This implementation returns true only.</p>
+     * @return true
+     */
+    @Override
+    protected boolean supportsNonFileResources() {
+        return true;
+    }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/xz/Xz.java b/src/main/org/apache/tools/ant/taskdefs/optional/xz/Xz.java
new file mode 100644
index 0000000..58cff61
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/xz/Xz.java
@@ -0,0 +1,63 @@
+/*
+ *  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.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.xz;
+
+import java.io.IOException;
+import java.nio.file.Files;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Pack;
+import org.tukaani.xz.LZMA2Options;
+import org.tukaani.xz.XZOutputStream;
+
+/**
+ * Compresses a file with the XZ algorithm. Normally used to compress
+ * non-compressed archives such as TAR files.
+ *
+ * @since Ant 1.10.1
+ *
+ * @ant.task category="packaging"
+ */
+
+public class Xz extends Pack {
+    /**
+     * Compress the zipFile.
+     */
+    @Override
+    protected void pack() {
+        try (XZOutputStream zOut = new XZOutputStream(
+            Files.newOutputStream(zipFile.toPath()), new LZMA2Options())) {
+            zipResource(getSrcResource(), zOut);
+        } catch (IOException ioe) {
+            String msg = "Problem creating xz " + ioe.getMessage();
+            throw new BuildException(msg, ioe, getLocation());
+        }
+    }
+
+    /**
+     * Whether this task can deal with non-file resources.
+     *
+     * <p>This implementation always returns true only.</p>
+     * @return true
+     */
+    @Override
+    protected boolean supportsNonFileResources() {
+        return true;
+    }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java b/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java
index d4483d9..914598f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java
+++ b/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java
@@ -23,6 +23,7 @@
 import java.util.List;
 import java.util.Random;
 import java.util.Vector;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -42,8 +43,6 @@
  */
 public abstract class DefaultRmicAdapter implements RmicAdapter {
 
-    private Rmic attributes;
-    private FileNameMapper mapper;
     private static final Random RAND = new Random();
     /** suffix denoting a stub file: {@value} */
     public static final String RMI_STUB_SUFFIX = "_Stub";
@@ -71,16 +70,14 @@
      */
     public static final String STUB_OPTION_COMPAT = "compat";
 
-    /**
-     * Default constructor
-     */
-    public DefaultRmicAdapter() {
-    }
+    private Rmic attributes;
+    private FileNameMapper mapper;
 
     /**
      * Sets Rmic attributes
      * @param attributes the rmic attributes
      */
+    @Override
     public void setRmic(final Rmic attributes) {
         this.attributes = attributes;
         mapper = new RmicFileNameMapper();
@@ -135,6 +132,7 @@
      * </ul>
      * @return a <code>FileNameMapper</code>
      */
+    @Override
     public FileNameMapper getMapper() {
         return mapper;
     }
@@ -143,6 +141,7 @@
      * Gets the CLASSPATH this rmic process will use.
      * @return the classpath
      */
+    @Override
     public Path getClasspath() {
         return getCompileClasspath();
     }
@@ -311,17 +310,16 @@
      */
     protected String[] filterJvmCompilerArgs(String[] compilerArgs) {
         int len = compilerArgs.length;
-        List args = new ArrayList(len);
+        List<String> args = new ArrayList<>(len);
         for (int i = 0; i < len; i++) {
             String arg = compilerArgs[i];
-            if (!arg.startsWith("-J")) {
-                args.add(arg);
-            } else {
+            if (arg.startsWith("-J")) {
                 attributes.log("Dropping " + arg + " from compiler arguments");
+            } else {
+                args.add(arg);
             }
         }
-        int count = args.size();
-        return (String[]) args.toArray(new String[count]);
+        return args.toArray(new String[args.size()]);
     }
 
 
@@ -331,24 +329,18 @@
      * @param cmd the commandline args
      */
     protected void logAndAddFilesToCompile(Commandline cmd) {
-        Vector compileList = attributes.getCompileList();
+        Vector<String> compileList = attributes.getCompileList();
 
         attributes.log("Compilation " + cmd.describeArguments(),
                        Project.MSG_VERBOSE);
 
-        StringBuffer niceSourceList = new StringBuffer("File");
-        int cListSize = compileList.size();
-        if (cListSize != 1) {
-            niceSourceList.append("s");
-        }
-        niceSourceList.append(" to be compiled:");
+        StringBuilder niceSourceList =
+            new StringBuilder(compileList.size() == 1 ? "File" : "Files")
+                .append(" to be compiled:");
 
-        for (int i = 0; i < cListSize; i++) {
-            String arg = (String) compileList.elementAt(i);
-            cmd.createArgument().setValue(arg);
-            niceSourceList.append("    ");
-            niceSourceList.append(arg);
-        }
+        niceSourceList.append(
+            compileList.stream().peek(arg -> cmd.createArgument().setValue(arg))
+                .collect(Collectors.joining("    ")));
 
         attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE);
     }
@@ -380,20 +372,20 @@
      */
     private class RmicFileNameMapper implements FileNameMapper {
 
-        RmicFileNameMapper() {
-        }
-
         /**
          * Empty implementation.
          */
+        @Override
         public void setFrom(String s) {
         }
         /**
          * Empty implementation.
          */
+        @Override
         public void setTo(String s) {
         }
 
+        @Override
         public String[] mapFileName(String name) {
             if (name == null
                 || !name.endsWith(".class")
@@ -438,7 +430,7 @@
             } else if (!attributes.getIdl()) {
                 int lastSlash = base.lastIndexOf(File.separatorChar);
 
-                String dirname = "";
+                String dirname;
                 /*
                  * I know, this is not necessary, but I prefer it explicit (SB)
                  */
@@ -446,6 +438,7 @@
                 if (lastSlash == -1) {
                     // no package
                     index = 0;
+                    dirname = "";
                 } else {
                     index = lastSlash + 1;
                     dirname = base.substring(0, index);
@@ -454,7 +447,7 @@
                 String filename = base.substring(index);
 
                 try {
-                    Class c = attributes.getLoader().loadClass(classname);
+                    Class<?> c = attributes.getLoader().loadClass(classname);
 
                     if (c.isInterface()) {
                         // only stub, no tie
@@ -467,14 +460,15 @@
                          * stub is derived from implementation,
                          * tie from interface name.
                          */
-                        Class interf = attributes.getRemoteInterface(c);
+                        Class<?> interf = attributes.getRemoteInterface(c);
                         String iName = interf.getName();
-                        String iDir = "";
-                        int iIndex = -1;
-                        int lastDot = iName.lastIndexOf(".");
+                        String iDir;
+                        int iIndex;
+                        int lastDot = iName.lastIndexOf('.');
                         if (lastDot == -1) {
                             // no package
                             iIndex = 0;
+                            iDir = "";
                         } else {
                             iIndex = lastDot + 1;
                             iDir = iName.substring(0, iIndex);
diff --git a/src/main/org/apache/tools/ant/taskdefs/rmic/ForkingSunRmic.java b/src/main/org/apache/tools/ant/taskdefs/rmic/ForkingSunRmic.java
index 81bd797..7f67009 100644
--- a/src/main/org/apache/tools/ant/taskdefs/rmic/ForkingSunRmic.java
+++ b/src/main/org/apache/tools/ant/taskdefs/rmic/ForkingSunRmic.java
@@ -50,6 +50,7 @@
      * @return true if the command ran successfully
      * @throws BuildException on error
      */
+    @Override
     public boolean execute() throws BuildException {
         Rmic owner = getRmic();
         Commandline cmd = setupRmicCommand();
diff --git a/src/main/org/apache/tools/ant/taskdefs/rmic/KaffeRmic.java b/src/main/org/apache/tools/ant/taskdefs/rmic/KaffeRmic.java
index ff72ad4..018ba95 100644
--- a/src/main/org/apache/tools/ant/taskdefs/rmic/KaffeRmic.java
+++ b/src/main/org/apache/tools/ant/taskdefs/rmic/KaffeRmic.java
@@ -44,15 +44,15 @@
     public static final String COMPILER_NAME = "kaffe";
 
     /** {@inheritDoc} */
+    @Override
     public boolean execute() throws BuildException {
         getRmic().log("Using Kaffe rmic", Project.MSG_VERBOSE);
         Commandline cmd = setupRmicCommand();
 
-        Class c = getRmicClass();
+        Class<?> c = getRmicClass();
         if (c == null) {
-            StringBuffer buf = new StringBuffer("Cannot use Kaffe rmic, as it"
-                                                + " is not available.  None"
-                                                + " of ");
+            StringBuilder buf = new StringBuilder(
+                "Cannot use Kaffe rmic, as it is not available.  None of ");
             for (int i = 0; i < RMIC_CLASSNAMES.length; i++) {
                 if (i != 0) {
                     buf.append(", ");
@@ -60,8 +60,8 @@
 
                 buf.append(RMIC_CLASSNAMES[i]);
             }
-            buf.append(" have been found. A common solution is to set the"
-                       + " environment variable JAVA_HOME or CLASSPATH.");
+            buf.append(
+                " have been found. A common solution is to set the environment variable JAVA_HOME or CLASSPATH.");
             throw new BuildException(buf.toString(),
                                      getRmic().getLocation());
         }
@@ -91,7 +91,7 @@
      *
      * @return null if neither class can get loaded.
      */
-    private static Class getRmicClass() {
+    private static Class<?> getRmicClass() {
         for (int i = 0; i < RMIC_CLASSNAMES.length; i++) {
             try {
                 return Class.forName(RMIC_CLASSNAMES[i]);
diff --git a/src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapterFactory.java b/src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapterFactory.java
index a604144..d7c4a4a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapterFactory.java
+++ b/src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapterFactory.java
@@ -106,13 +106,17 @@
         }
         if (SunRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
             return new SunRmic();
-        } else if (KaffeRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
+        }
+        if (KaffeRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
             return new KaffeRmic();
-        } else if (WLRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
+        }
+        if (WLRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
             return new WLRmic();
-        } else if (ForkingSunRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
+        }
+        if (ForkingSunRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
             return new ForkingSunRmic();
-        } else if (XNewRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
+        }
+        if (XNewRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
             return new XNewRmic();
         }
         //no match?
@@ -133,7 +137,7 @@
     private static RmicAdapter resolveClassName(String className,
                                                 ClassLoader loader)
             throws BuildException {
-        return (RmicAdapter) ClasspathUtils.newInstance(className,
+        return ClasspathUtils.newInstance(className,
                 loader != null ? loader :
                 RmicAdapterFactory.class.getClassLoader(), RmicAdapter.class);
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/rmic/SunRmic.java b/src/main/org/apache/tools/ant/taskdefs/rmic/SunRmic.java
index 7281252..4af9c72 100644
--- a/src/main/org/apache/tools/ant/taskdefs/rmic/SunRmic.java
+++ b/src/main/org/apache/tools/ant/taskdefs/rmic/SunRmic.java
@@ -51,13 +51,10 @@
      */
     public static final String RMIC_EXECUTABLE = "rmic";
     /** Error message to use with the sun rmic is not the classpath. */
-    public static final String ERROR_NO_RMIC_ON_CLASSPATH = "Cannot use SUN rmic, as it is not "
-                                         + "available.  A common solution is to "
-                                         + "set the environment variable "
-                                         + "JAVA_HOME";
-    public static final String ERROR_NO_RMIC_ON_CLASSPATH_JAVA_9 = "Cannot use SUN rmic, as it is not "
-                                         + "available.  The class we try to use is part of the jdk.rmic module which may not be. "
-                                         + "Please use the 'forking' compiler for JDK 9+";
+    public static final String ERROR_NO_RMIC_ON_CLASSPATH =
+        "Cannot use SUN rmic, as it is not available.  A common solution is to set the environment variable JAVA_HOME";
+    public static final String ERROR_NO_RMIC_ON_CLASSPATH_JAVA_9 =
+        "Cannot use SUN rmic, as it is not available.  The class we try to use is part of the jdk.rmic module which may not be. Please use the 'forking' compiler for JDK 9+";
     /** Error message to use when there is an error starting the sun rmic compiler */
     public static final String ERROR_RMIC_FAILED = "Error starting SUN rmic: ";
 
@@ -66,29 +63,28 @@
      * @return true if the compilation succeeded
      * @throws BuildException on error
      */
+    @Override
     public boolean execute() throws BuildException {
         getRmic().log("Using SUN rmic compiler", Project.MSG_VERBOSE);
         Commandline cmd = setupRmicCommand();
 
         // Create an instance of the rmic, redirecting output to
         // the project log
-        LogOutputStream logstr = new LogOutputStream(getRmic(),
-                                                     Project.MSG_WARN);
+        LogOutputStream logstr =
+            new LogOutputStream(getRmic(), Project.MSG_WARN);
 
         boolean success = false;
         try {
-            Class c = Class.forName(RMIC_CLASSNAME);
-            Constructor cons
-                = c.getConstructor(new Class[]  {OutputStream.class, String.class});
-            Object rmic = cons.newInstance(new Object[] {logstr, "rmic"});
+            Class<?> c = Class.forName(RMIC_CLASSNAME);
+            Constructor<?> cons =
+                c.getConstructor(OutputStream.class, String.class);
+            Object rmic = cons.newInstance(logstr, "rmic");
 
-            Method doRmic = c.getMethod("compile",
-                                        new Class [] {String[].class});
-            Boolean ok =
-                (Boolean) doRmic.invoke(rmic,
-                                       (new Object[] {cmd.getArguments()}));
+            Method doRmic = c.getMethod("compile", String[].class);
+            boolean ok = Boolean.TRUE
+                .equals(doRmic.invoke(rmic, (Object) cmd.getArguments()));
             success = true;
-            return ok.booleanValue();
+            return ok;
         } catch (ClassNotFoundException ex) {
             if (JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_9)) {
                 throw new BuildException(ERROR_NO_RMIC_ON_CLASSPATH_JAVA_9,
@@ -99,10 +95,9 @@
         } catch (Exception ex) {
             if (ex instanceof BuildException) {
                 throw (BuildException) ex;
-            } else {
-                throw new BuildException(ERROR_RMIC_FAILED,
-                                         ex, getRmic().getLocation());
             }
+            throw new BuildException(ERROR_RMIC_FAILED,
+                                     ex, getRmic().getLocation());
         } finally {
             try {
                 logstr.close();
@@ -122,6 +117,7 @@
      * @param compilerArgs the original compiler arguments
      * @return the filtered set.
      */
+    @Override
     protected String[] preprocessCompilerArgs(String[] compilerArgs) {
         return filterJvmCompilerArgs(compilerArgs);
     }
diff --git a/src/main/org/apache/tools/ant/taskdefs/rmic/WLRmic.java b/src/main/org/apache/tools/ant/taskdefs/rmic/WLRmic.java
index 3b1f2a1..17a7650 100644
--- a/src/main/org/apache/tools/ant/taskdefs/rmic/WLRmic.java
+++ b/src/main/org/apache/tools/ant/taskdefs/rmic/WLRmic.java
@@ -40,8 +40,7 @@
 
     /** The error string to use if not able to find the weblogic rmic */
     public static final String ERROR_NO_WLRMIC_ON_CLASSPATH =
-        "Cannot use WebLogic rmic, as it is not "
-        + "available. Add it to Ant's classpath with the -lib option";
+        "Cannot use WebLogic rmic, as it is not available. Add it to Ant's classpath with the -lib option";
 
     /** The error string to use if not able to start the weblogic rmic */
     public static final String ERROR_WLRMIC_FAILED = "Error starting WebLogic rmic: ";
@@ -57,6 +56,7 @@
      * @return true if the compilation succeeded
      * @throws  BuildException on error
      */
+    @Override
     public boolean execute() throws BuildException {
         getRmic().log("Using WebLogic rmic", Project.MSG_VERBOSE);
         Commandline cmd = setupRmicCommand(new String[] {"-noexit"});
@@ -64,7 +64,7 @@
         AntClassLoader loader = null;
         try {
             // Create an instance of the rmic
-            Class c = null;
+            Class<?> c;
             if (getRmic().getClasspath() == null) {
                 c = Class.forName(WLRMIC_CLASSNAME);
             } else {
@@ -72,9 +72,8 @@
                     = getRmic().getProject().createClassLoader(getRmic().getClasspath());
                 c = Class.forName(WLRMIC_CLASSNAME, true, loader);
             }
-            Method doRmic = c.getMethod("main",
-                                        new Class [] {String[].class});
-            doRmic.invoke(null, new Object[] {cmd.getArguments()});
+            Method doRmic = c.getMethod("main", String[].class);
+            doRmic.invoke(null, (Object) cmd.getArguments());
             return true;
         } catch (ClassNotFoundException ex) {
             throw new BuildException(ERROR_NO_WLRMIC_ON_CLASSPATH, getRmic().getLocation());
@@ -96,6 +95,7 @@
      * Get the suffix for the rmic stub classes
      * @return the stub suffix
      */
+    @Override
     public String getStubClassSuffix() {
         return WL_RMI_STUB_SUFFIX;
     }
@@ -104,6 +104,7 @@
      * Get the suffix for the rmic skeleton classes
      * @return the skeleton suffix
      */
+    @Override
     public String getSkelClassSuffix() {
         return WL_RMI_SKEL_SUFFIX;
     }
@@ -114,6 +115,7 @@
      * @param compilerArgs the original compiler arguments
      * @return the filtered set.
      */
+    @Override
     protected String[] preprocessCompilerArgs(String[] compilerArgs) {
         return filterJvmCompilerArgs(compilerArgs);
     }
@@ -123,6 +125,7 @@
      * stub option is set, a warning is printed.
      * @return null, for no stub version
      */
+    @Override
     protected String addStubVersionOptions() {
         //handle the many different stub options.
         String stubVersion = getRmic().getStubVersion();
diff --git a/src/main/org/apache/tools/ant/taskdefs/rmic/XNewRmic.java b/src/main/org/apache/tools/ant/taskdefs/rmic/XNewRmic.java
index 81e043e..271daae 100644
--- a/src/main/org/apache/tools/ant/taskdefs/rmic/XNewRmic.java
+++ b/src/main/org/apache/tools/ant/taskdefs/rmic/XNewRmic.java
@@ -33,14 +33,11 @@
      */
     public static final String COMPILER_NAME = "xnew";
 
-    /** No-arg constructor. */
-    public XNewRmic() {
-    }
-
     /**
      * Create a normal command line, then with -Xnew at the front
      * @return a command line that hands off to thw
      */
+    @Override
     protected Commandline setupRmicCommand() {
         String[] options = new String[] {
                 "-Xnew"
diff --git a/src/main/org/apache/tools/ant/types/AbstractFileSet.java b/src/main/org/apache/tools/ant/types/AbstractFileSet.java
index 0c1d57d..7e1a3e4 100644
--- a/src/main/org/apache/tools/ant/types/AbstractFileSet.java
+++ b/src/main/org/apache/tools/ant/types/AbstractFileSet.java
@@ -23,6 +23,8 @@
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Stack;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.DirectoryScanner;
@@ -36,18 +38,21 @@
 import org.apache.tools.ant.types.selectors.DepthSelector;
 import org.apache.tools.ant.types.selectors.DifferentSelector;
 import org.apache.tools.ant.types.selectors.ExtendSelector;
+import org.apache.tools.ant.types.selectors.ExecutableSelector;
 import org.apache.tools.ant.types.selectors.FileSelector;
 import org.apache.tools.ant.types.selectors.FilenameSelector;
 import org.apache.tools.ant.types.selectors.MajoritySelector;
 import org.apache.tools.ant.types.selectors.NoneSelector;
 import org.apache.tools.ant.types.selectors.NotSelector;
 import org.apache.tools.ant.types.selectors.OrSelector;
+import org.apache.tools.ant.types.selectors.OwnedBySelector;
 import org.apache.tools.ant.types.selectors.PresentSelector;
 import org.apache.tools.ant.types.selectors.ReadableSelector;
 import org.apache.tools.ant.types.selectors.SelectSelector;
 import org.apache.tools.ant.types.selectors.SelectorContainer;
 import org.apache.tools.ant.types.selectors.SelectorScanner;
 import org.apache.tools.ant.types.selectors.SizeSelector;
+import org.apache.tools.ant.types.selectors.SymlinkSelector;
 import org.apache.tools.ant.types.selectors.TypeSelector;
 import org.apache.tools.ant.types.selectors.WritableSelector;
 import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
@@ -63,8 +68,8 @@
     implements Cloneable, SelectorContainer {
 
     private PatternSet defaultPatterns = new PatternSet();
-    private List<PatternSet> additionalPatterns = new ArrayList<PatternSet>();
-    private List<FileSelector> selectors = new ArrayList<FileSelector>();
+    private List<PatternSet> additionalPatterns = new ArrayList<>();
+    private List<FileSelector> selectors = new ArrayList<>();
 
     private File dir;
     private boolean fileAttributeUsed;
@@ -110,6 +115,7 @@
      * @param r the <code>Reference</code> to use.
      * @throws BuildException on error
      */
+    @Override
     public void setRefid(Reference r) throws BuildException {
         if (dir != null || defaultPatterns.hasPatterns(getProject())) {
             throw tooManyAttributes();
@@ -492,14 +498,14 @@
             return getRef(p).getDirectoryScanner(p);
         }
         dieOnCircularReference();
-        DirectoryScanner ds = null;
+        final DirectoryScanner ds;
         synchronized (this) {
             if (directoryScanner != null && p == getProject()) {
                 ds = directoryScanner;
             } else {
                 if (dir == null) {
-                    throw new BuildException("No directory specified for "
-                                             + getDataTypeName() + ".");
+                    throw new BuildException("No directory specified for %s.",
+                        getDataTypeName());
                 }
                 if (!dir.exists() && errorOnMissingDir) {
                     throw new BuildException(dir.getAbsolutePath()
@@ -507,8 +513,8 @@
                                              .DOES_NOT_EXIST_POSTFIX);
                 }
                 if (!dir.isDirectory() && dir.exists()) {
-                    throw new BuildException(dir.getAbsolutePath()
-                                             + " is not a directory.");
+                    throw new BuildException("%s is not a directory.",
+                        dir.getAbsolutePath());
                 }
                 ds = new DirectoryScanner();
                 setupDirectoryScanner(ds, p);
@@ -580,6 +586,7 @@
      *
      * @return whether any selectors are in this container.
      */
+    @Override
     public synchronized boolean hasSelectors() {
         if (isReference()) {
             return getRef(getProject()).hasSelectors();
@@ -601,12 +608,7 @@
         if (defaultPatterns.hasPatterns(getProject())) {
             return true;
         }
-        for (PatternSet ps : additionalPatterns) {
-            if (ps.hasPatterns(getProject())) {
-                return true;
-            }
-        }
-        return false;
+        return additionalPatterns.stream().anyMatch(ps -> ps.hasPatterns(getProject()));
     }
 
     /**
@@ -614,6 +616,7 @@
      *
      * @return the number of selectors in this container as an <code>int</code>.
      */
+    @Override
     public synchronized int selectorCount() {
         if (isReference()) {
             return getRef(getProject()).selectorCount();
@@ -627,13 +630,13 @@
      * @param p the current project
      * @return a <code>FileSelector[]</code> of the selectors in this container.
      */
+    @Override
     public synchronized FileSelector[] getSelectors(Project p) {
         if (isReference()) {
             return getRef(getProject()).getSelectors(p);
         }
         dieOnCircularReference(p);
-        return (FileSelector[]) (selectors.toArray(
-            new FileSelector[selectors.size()]));
+        return selectors.toArray(new FileSelector[selectors.size()]);
     }
 
     /**
@@ -641,6 +644,7 @@
      *
      * @return an <code>Enumeration</code> of selectors.
      */
+    @Override
     public synchronized Enumeration<FileSelector> selectorElements() {
         if (isReference()) {
             return getRef(getProject()).selectorElements();
@@ -654,6 +658,7 @@
      *
      * @param selector the new <code>FileSelector</code> to add.
      */
+    @Override
     public synchronized void appendSelector(FileSelector selector) {
         if (isReference()) {
             throw noChildrenAllowed();
@@ -669,6 +674,7 @@
      * Add a "Select" selector entry on the selector list.
      * @param selector the <code>SelectSelector</code> to add.
      */
+    @Override
     public void addSelector(SelectSelector selector) {
         appendSelector(selector);
     }
@@ -677,6 +683,7 @@
      * Add an "And" selector entry on the selector list.
      * @param selector the <code>AndSelector</code> to add.
      */
+    @Override
     public void addAnd(AndSelector selector) {
         appendSelector(selector);
     }
@@ -685,6 +692,7 @@
      * Add an "Or" selector entry on the selector list.
      * @param selector the <code>OrSelector</code> to add.
      */
+    @Override
     public void addOr(OrSelector selector) {
         appendSelector(selector);
     }
@@ -693,6 +701,7 @@
      * Add a "Not" selector entry on the selector list.
      * @param selector the <code>NotSelector</code> to add.
      */
+    @Override
     public void addNot(NotSelector selector) {
         appendSelector(selector);
     }
@@ -701,6 +710,7 @@
      * Add a "None" selector entry on the selector list.
      * @param selector the <code>NoneSelector</code> to add.
      */
+    @Override
     public void addNone(NoneSelector selector) {
         appendSelector(selector);
     }
@@ -709,6 +719,7 @@
      * Add a majority selector entry on the selector list.
      * @param selector the <code>MajoritySelector</code> to add.
      */
+    @Override
     public void addMajority(MajoritySelector selector) {
         appendSelector(selector);
     }
@@ -717,6 +728,7 @@
      * Add a selector date entry on the selector list.
      * @param selector the <code>DateSelector</code> to add.
      */
+    @Override
     public void addDate(DateSelector selector) {
         appendSelector(selector);
     }
@@ -725,6 +737,7 @@
      * Add a selector size entry on the selector list.
      * @param selector the <code>SizeSelector</code> to add.
      */
+    @Override
     public void addSize(SizeSelector selector) {
         appendSelector(selector);
     }
@@ -733,6 +746,7 @@
      * Add a DifferentSelector entry on the selector list.
      * @param selector the <code>DifferentSelector</code> to add.
      */
+    @Override
     public void addDifferent(DifferentSelector selector) {
         appendSelector(selector);
     }
@@ -741,6 +755,7 @@
      * Add a selector filename entry on the selector list.
      * @param selector the <code>FilenameSelector</code> to add.
      */
+    @Override
     public void addFilename(FilenameSelector selector) {
         appendSelector(selector);
     }
@@ -749,6 +764,7 @@
      * Add a selector type entry on the selector list.
      * @param selector the <code>TypeSelector</code> to add.
      */
+    @Override
     public void addType(TypeSelector selector) {
         appendSelector(selector);
     }
@@ -757,6 +773,7 @@
      * Add an extended selector entry on the selector list.
      * @param selector the <code>ExtendSelector</code> to add.
      */
+    @Override
     public void addCustom(ExtendSelector selector) {
         appendSelector(selector);
     }
@@ -765,6 +782,7 @@
      * Add a contains selector entry on the selector list.
      * @param selector the <code>ContainsSelector</code> to add.
      */
+    @Override
     public void addContains(ContainsSelector selector) {
         appendSelector(selector);
     }
@@ -773,6 +791,7 @@
      * Add a present selector entry on the selector list.
      * @param selector the <code>PresentSelector</code> to add.
      */
+    @Override
     public void addPresent(PresentSelector selector) {
         appendSelector(selector);
     }
@@ -781,6 +800,7 @@
      * Add a depth selector entry on the selector list.
      * @param selector the <code>DepthSelector</code> to add.
      */
+    @Override
     public void addDepth(DepthSelector selector) {
         appendSelector(selector);
     }
@@ -789,6 +809,7 @@
      * Add a depends selector entry on the selector list.
      * @param selector the <code>DependSelector</code> to add.
      */
+    @Override
     public void addDepend(DependSelector selector) {
         appendSelector(selector);
     }
@@ -797,6 +818,7 @@
      * Add a regular expression selector entry on the selector list.
      * @param selector the <code>ContainsRegexpSelector</code> to add.
      */
+    @Override
     public void addContainsRegexp(ContainsRegexpSelector selector) {
         appendSelector(selector);
     }
@@ -806,6 +828,7 @@
      * @param selector the <code>ModifiedSelector</code> to add.
      * @since ant 1.6
      */
+    @Override
     public void addModified(ModifiedSelector selector) {
         appendSelector(selector);
     }
@@ -819,10 +842,35 @@
     }
 
     /**
+     * @param e ExecutableSelector
+     * @since 1.10.0
+     */
+    public void addExecutable(ExecutableSelector e) {
+        appendSelector(e);
+    }
+
+    /**
+     * @param e SymlinkSelector
+     * @since 1.10.0
+     */
+    public void addSymlink(SymlinkSelector e) {
+        appendSelector(e);
+    }
+
+    /**
+     * @param o OwnedBySelector
+     * @since 1.10.0
+     */
+    public void addOwnedBy(OwnedBySelector o) {
+        appendSelector(o);
+    }
+
+    /**
      * Add an arbitrary selector.
      * @param selector the <code>FileSelector</code> to add.
      * @since Ant 1.6
      */
+    @Override
     public void add(FileSelector selector) {
         appendSelector(selector);
     }
@@ -832,22 +880,14 @@
      *
      * @return a <code>String</code> of included filenames.
      */
+    @Override
     public String toString() {
         if (isReference()) {
             return getRef(getProject()).toString();
         }
         dieOnCircularReference();
         DirectoryScanner ds = getDirectoryScanner(getProject());
-        String[] files = ds.getIncludedFiles();
-        StringBuffer sb = new StringBuffer();
-
-        for (int i = 0; i < files.length; i++) {
-            if (i > 0) {
-                sb.append(';');
-            }
-            sb.append(files[i]);
-        }
-        return sb.toString();
+        return Stream.of(ds.getIncludedFiles()).collect(Collectors.joining(File.pathSeparator));
     }
 
     /**
@@ -857,22 +897,20 @@
      * @return the cloned object
      * @since Ant 1.6
      */
-    public synchronized Object clone() {
+    @Override
+    public synchronized AbstractFileSet clone() {
         if (isReference()) {
             return (getRef(getProject())).clone();
-        } else {
-            try {
-                AbstractFileSet fs = (AbstractFileSet) super.clone();
-                fs.defaultPatterns = (PatternSet) defaultPatterns.clone();
-                fs.additionalPatterns = new ArrayList<PatternSet>(additionalPatterns.size());
-                for (PatternSet ps : additionalPatterns) {
-                    fs.additionalPatterns.add((PatternSet) ps.clone());
-                }
-                fs.selectors = new ArrayList<FileSelector>(selectors);
-                return fs;
-            } catch (CloneNotSupportedException e) {
-                throw new BuildException(e);
-            }
+        }
+        try {
+            AbstractFileSet fs = (AbstractFileSet) super.clone();
+            fs.defaultPatterns = defaultPatterns.clone();
+            fs.additionalPatterns = additionalPatterns.stream().map(
+                    PatternSet::clone).map(PatternSet.class::cast).collect(Collectors.toList());
+            fs.selectors = new ArrayList<>(selectors);
+            return fs;
+        } catch (CloneNotSupportedException e) {
+            throw new BuildException(e);
         }
     }
 
@@ -913,14 +951,12 @@
             return getRef(p).mergePatterns(p);
         }
         dieOnCircularReference();
-        PatternSet ps = (PatternSet) defaultPatterns.clone();
-        final int count = additionalPatterns.size();
-        for (int i = 0; i < count; i++) {
-            ps.append(additionalPatterns.get(i), p);
-        }
+        PatternSet ps = defaultPatterns.clone();
+        additionalPatterns.forEach(pat -> ps.append(pat, p));
         return ps;
     }
 
+    @Override
     protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
@@ -929,11 +965,9 @@
         if (isReference()) {
             super.dieOnCircularReference(stk, p);
         } else {
-            for (FileSelector fileSelector : selectors) {
-                if (fileSelector instanceof DataType) {
-                    pushAndInvokeCircularReferenceCheck((DataType) fileSelector, stk, p);
-                }
-            }
+            selectors.stream().filter(DataType.class::isInstance).forEach(fileSelector ->
+                pushAndInvokeCircularReferenceCheck((DataType) fileSelector, stk, p)
+            );
             for (PatternSet ps : additionalPatterns) {
                 pushAndInvokeCircularReferenceCheck(ps, stk, p);
             }
diff --git a/src/main/org/apache/tools/ant/types/AntFilterReader.java b/src/main/org/apache/tools/ant/types/AntFilterReader.java
index bdc1c31..154b860 100644
--- a/src/main/org/apache/tools/ant/types/AntFilterReader.java
+++ b/src/main/org/apache/tools/ant/types/AntFilterReader.java
@@ -17,8 +17,9 @@
  */
 package org.apache.tools.ant.types;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Stack;
-import java.util.Vector;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -31,7 +32,7 @@
 
     private String className;
 
-    private final Vector<Parameter> parameters = new Vector<Parameter>();
+    private final List<Parameter> parameters = new ArrayList<>();
 
     private Path classpath;
 
@@ -69,7 +70,7 @@
         if (isReference()) {
             throw noChildrenAllowed();
         }
-        parameters.addElement(param);
+        parameters.add(param);
     }
 
     /**
@@ -137,9 +138,7 @@
             ((AntFilterReader) getCheckedRef()).getParams();
         }
         dieOnCircularReference();
-        Parameter[] params = new Parameter[parameters.size()];
-        parameters.copyInto(params);
-        return params;
+        return parameters.toArray(new Parameter[parameters.size()]);
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/types/ArchiveFileSet.java b/src/main/org/apache/tools/ant/types/ArchiveFileSet.java
index e9a0730..c34f213 100644
--- a/src/main/org/apache/tools/ant/types/ArchiveFileSet.java
+++ b/src/main/org/apache/tools/ant/types/ArchiveFileSet.java
@@ -110,6 +110,7 @@
      * @param dir the directory for the fileset
      * @throws BuildException on error
      */
+    @Override
     public void setDir(File dir) throws BuildException {
         checkAttributesAllowed();
         if (src != null) {
@@ -191,13 +192,10 @@
             return ((ArchiveFileSet) getCheckedRef()).getSrc();
         }
         dieOnCircularReference();
-        if (src != null) {
-            FileProvider fp = src.as(FileProvider.class);
-            if (fp != null) {
-                return fp.getFile();
-            }
+        if (src == null) {
+            return null;
         }
-        return null;
+        return src.asOptional(FileProvider.class).map(FileProvider::getFile).orElse(null);
     }
 
     /**
@@ -212,6 +210,7 @@
      * @since Ant 1.8
      */
     // TODO is the above true? AFAICT the calls look circular :/
+    @Override
     protected Object getCheckedRef(Project p) {
         return getRef(p);
     }
@@ -288,11 +287,7 @@
     public String getEncoding() {
         if (isReference()) {
             AbstractFileSet ref = getRef(getProject());
-            if (ref instanceof ArchiveFileSet) {
-                return ((ArchiveFileSet) ref).getEncoding();
-            } else {
-                return null;
-            }
+            return ref instanceof ArchiveFileSet ? ((ArchiveFileSet) ref).getEncoding() : null;
         }
         return encoding;
     }
@@ -310,6 +305,7 @@
      * @param p the project to use
      * @return a directory scanner
      */
+    @Override
     public DirectoryScanner getDirectoryScanner(Project p) {
         if (isReference()) {
             return getRef(p).getDirectoryScanner(p);
@@ -340,6 +336,7 @@
      * @return Iterator of Resources.
      * @since Ant 1.7
      */
+    @Override
     public Iterator<Resource> iterator() {
         if (isReference()) {
             return ((ResourceCollection) (getRef(getProject()))).iterator();
@@ -356,6 +353,7 @@
      * @return size of the collection as int.
      * @since Ant 1.7
      */
+    @Override
     public int size() {
         if (isReference()) {
             return ((ResourceCollection) (getRef(getProject()))).size();
@@ -375,6 +373,7 @@
      * @return whether this is a filesystem-only resource collection.
      * @since Ant 1.7
      */
+    @Override
     public boolean isFilesystemOnly() {
         if (isReference()) {
             return ((ArchiveFileSet) getCheckedRef()).isFilesystemOnly();
@@ -505,11 +504,13 @@
      * @return the cloned archiveFileSet
      * @since Ant 1.6
      */
-    public Object clone() {
+    @Override
+    public ArchiveFileSet clone() {
         if (isReference()) {
-            return getCheckedRef(ArchiveFileSet.class, getDataTypeName(), getProject()).clone();
+            return getCheckedRef(ArchiveFileSet.class, getDataTypeName(),
+                getProject()).clone();
         }
-        return super.clone();
+        return (ArchiveFileSet) super.clone();
     }
 
     /**
@@ -518,6 +519,7 @@
      * @return for file based archivefilesets, included files as a list
      * of semicolon-separated filenames. else just the name of the zip.
      */
+    @Override
     public String toString() {
         if (hasDir && getProject() != null) {
             return super.toString();
@@ -530,6 +532,7 @@
      * @return the prefix.
      * @deprecated since 1.7.
      */
+    @Deprecated
     public String getPrefix() {
         return prefix;
     }
@@ -539,6 +542,7 @@
      * @return the full pathname.
      * @deprecated since 1.7.
      */
+    @Deprecated
     public String getFullpath() {
         return fullpath;
     }
@@ -547,6 +551,7 @@
      * @return the file mode.
      * @deprecated since 1.7.
      */
+    @Deprecated
     public int getFileMode() {
         return fileMode;
     }
@@ -555,6 +560,7 @@
      * @return the dir mode.
      * @deprecated since 1.7.
      */
+    @Deprecated
     public int getDirMode() {
         return dirMode;
     }
@@ -577,6 +583,7 @@
         }
     }
 
+    @Override
     protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
diff --git a/src/main/org/apache/tools/ant/types/ArchiveScanner.java b/src/main/org/apache/tools/ant/types/ArchiveScanner.java
index db5a8d4..90e91e8 100644
--- a/src/main/org/apache/tools/ant/types/ArchiveScanner.java
+++ b/src/main/org/apache/tools/ant/types/ArchiveScanner.java
@@ -272,11 +272,12 @@
      * @return the resource
      * @since Ant 1.5.2
      */
+    @Override
     public Resource getResource(String name) {
         if (src == null) {
             return super.getResource(name);
         }
-        if (name.equals("")) {
+        if ("".equals(name)) {
             // special case in ZIPs, we do not want this thing included
             return new Resource("", true, Long.MAX_VALUE, true);
         }
diff --git a/src/main/org/apache/tools/ant/types/Assertions.java b/src/main/org/apache/tools/ant/types/Assertions.java
index ce7091a..0bb2f30 100644
--- a/src/main/org/apache/tools/ant/types/Assertions.java
+++ b/src/main/org/apache/tools/ant/types/Assertions.java
@@ -117,7 +117,7 @@
      * @param ref the reference to use
      */
     public void setRefid(Reference ref) {
-        if (assertionList.size() > 0 || enableSystemAssertions != null) {
+        if (!assertionList.isEmpty() || enableSystemAssertions != null) {
             throw tooManyAttributes();
         }
         super.setRefid(ref);
@@ -130,13 +130,12 @@
     private Assertions getFinalReference() {
         if (getRefid() == null) {
             return this;
-        } else {
-            Object o = getRefid().getReferencedObject(getProject());
-            if (!(o instanceof Assertions)) {
-                throw new BuildException("reference is of wrong type");
-            }
-            return (Assertions) o;
         }
+        Object o = getRefid().getReferencedObject(getProject());
+        if (!(o instanceof Assertions)) {
+            throw new BuildException("reference is of wrong type");
+        }
+        return (Assertions) o;
     }
 
     /**
@@ -245,16 +244,16 @@
      * @return a cli
      * @throws CloneNotSupportedException if the super class does not support cloning
      */
+    @Override
     public Object clone() throws CloneNotSupportedException {
         Assertions that = (Assertions) super.clone();
-        that.assertionList = new ArrayList<BaseAssertion>(assertionList);
+        that.assertionList = new ArrayList<>(assertionList);
         return that;
     }
 
     /**
      * base class for our assertion elements.
      */
-
     public abstract static class BaseAssertion {
         private String packageName;
         private String className;
@@ -309,7 +308,7 @@
             if (getPackageName() != null && getClassName() != null) {
                 throw new BuildException("Both package and class have been set");
             }
-            StringBuffer command = new StringBuffer(getCommandPrefix());
+            StringBuilder command = new StringBuilder(getCommandPrefix());
             //see if it is a package or a class
             if (getPackageName() != null) {
                 //packages get a ... prefix
@@ -337,6 +336,7 @@
          * get the prefix used to begin the command; -ea or -da.
          * @return prefix
          */
+        @Override
         public String getCommandPrefix() {
             return "-ea";
         }
@@ -351,6 +351,7 @@
          * get the prefix used to begin the command; -ea or -da.
          * @return prefix
          */
+        @Override
         public String getCommandPrefix() {
             return "-da";
         }
diff --git a/src/main/org/apache/tools/ant/types/Commandline.java b/src/main/org/apache/tools/ant/types/Commandline.java
index c8f4eaf..96bc335 100644
--- a/src/main/org/apache/tools/ant/types/Commandline.java
+++ b/src/main/org/apache/tools/ant/types/Commandline.java
@@ -25,6 +25,7 @@
 import java.util.List;
 import java.util.ListIterator;
 import java.util.StringTokenizer;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.ProjectComponent;
@@ -229,11 +230,9 @@
          */
         public int getPosition() {
             if (realPos == -1) {
-                realPos = (executable == null ? 0 : 1);
-                for (int i = 0; i < position; i++) {
-                    Argument arg = (Argument) arguments.get(i);
-                    realPos += arg.getParts().length;
-                }
+                realPos = (executable == null ? 0 : 1) + (int)
+                arguments.stream().limit(position).map(Argument::getParts)
+                        .flatMap(Stream::of).count();
             }
             return realPos;
         }
@@ -387,7 +386,7 @@
      * @return the arguments as an array of strings.
      */
     public String[] getArguments() {
-        List<String> result = new ArrayList<String>(arguments.size() * 2);
+        List<String> result = new ArrayList<>(arguments.size() * 2);
         addArgumentsToList(result.listIterator());
         return result.toArray(new String[result.size()]);
     }
@@ -414,6 +413,7 @@
      * Return the command line as a string.
      * @return the command line.
      */
+    @Override
     public String toString() {
         return toString(getCommandline());
     }
@@ -434,17 +434,16 @@
             if (argument.indexOf("\'") > -1) {
                 throw new BuildException("Can\'t handle single and double"
                         + " quotes in same argument");
-            } else {
-                return '\'' + argument + '\'';
             }
-        } else if (argument.indexOf("\'") > -1
-                   || argument.indexOf(" ") > -1
-                   // WIN9x uses a bat file for executing commands
-                   || (IS_WIN_9X && argument.indexOf(';') != -1)) {
-            return '\"' + argument + '\"';
-        } else {
-            return argument;
+            return '\'' + argument + '\'';
         }
+        if (argument.indexOf("\'") > -1
+               || argument.indexOf(" ") > -1
+               // WIN9x uses a bat file for executing commands
+               || (IS_WIN_9X && argument.indexOf(';') != -1)) {
+            return '\"' + argument + '\"';
+        }
+        return argument;
     }
 
     /**
@@ -488,7 +487,7 @@
         final int inDoubleQuote = 2;
         int state = normal;
         final StringTokenizer tok = new StringTokenizer(toProcess, "\"\' ", true);
-        final ArrayList<String> result = new ArrayList<String>();
+        final ArrayList<String> result = new ArrayList<>();
         final StringBuilder current = new StringBuilder();
         boolean lastTokenHasBeenQuoted = false;
 
@@ -550,10 +549,11 @@
      * Generate a deep clone of the contained object.
      * @return a clone of the contained object
      */
-    public Object clone() {
+    @Override
+    public Commandline clone() {
         try {
             Commandline c = (Commandline) super.clone();
-            c.arguments = new ArrayList<Argument>(arguments);
+            c.arguments = new ArrayList<>(arguments);
             return c;
         } catch (CloneNotSupportedException e) {
             throw new BuildException(e);
@@ -644,9 +644,7 @@
         if (args == null || args.length == 0) {
             return "";
         }
-        StringBuffer buf = new StringBuffer("Executing \'");
-        buf.append(args[0]);
-        buf.append("\'");
+        StringBuilder buf = new StringBuilder("Executing \'").append(args[0]).append("\'");
         if (args.length > 1) {
             buf.append(" with ");
             buf.append(describeArguments(args, 1));
@@ -681,7 +679,7 @@
         if (args == null || args.length <= offset) {
             return "";
         }
-        StringBuffer buf = new StringBuffer("argument");
+        StringBuilder buf = new StringBuilder("argument");
         if (args.length > offset) {
             buf.append("s");
         }
diff --git a/src/main/org/apache/tools/ant/types/CommandlineJava.java b/src/main/org/apache/tools/ant/types/CommandlineJava.java
index e6f82cf..92b11c4 100644
--- a/src/main/org/apache/tools/ant/types/CommandlineJava.java
+++ b/src/main/org/apache/tools/ant/types/CommandlineJava.java
@@ -82,7 +82,7 @@
         /** the system properties. */
         Properties sys = null;
         // CheckStyle:VisibilityModifier ON
-        private Vector<PropertySet> propertySets = new Vector<PropertySet>();
+        private Vector<PropertySet> propertySets = new Vector<>();
 
         /**
          * Get the properties as an array; this is an override of the
@@ -90,15 +90,15 @@
          * @return the array of definitions; may be null.
          * @throws BuildException on error.
          */
+        @Override
         public String[] getVariables() throws BuildException {
 
-            List<String> definitions = new LinkedList<String>();
+            List<String> definitions = new LinkedList<>();
             addDefinitionsToList(definitions.listIterator());
-            if (definitions.size() == 0) {
+            if (definitions.isEmpty()) {
                 return null;
-            } else {
-                return definitions.toArray(new String[definitions.size()]);
             }
+            return definitions.toArray(new String[definitions.size()]);
         }
 
         /**
@@ -182,6 +182,7 @@
          * @exception CloneNotSupportedException for signature.
          */
         @SuppressWarnings("unchecked")
+        @Override
         public Object clone() throws CloneNotSupportedException {
             try {
                 SysProperties c = (SysProperties) super.clone();
@@ -366,6 +367,7 @@
                     return javaCommand.getExecutable();
                 case MODULE:
                     return parseClassFromModuleClassPair(javaCommand.getExecutable());
+                default:
             }
         }
         return null;
@@ -392,6 +394,7 @@
                     javaCommand.setExecutable(createModuleClassPair(module,
                             parseClassFromModuleClassPair(javaCommand.getExecutable())), false);
                     break;
+                default:
             }
         }
         executableType = ExecutableType.MODULE;
@@ -476,7 +479,7 @@
      */
     public String[] getCommandline() {
         //create the list
-        List<String> commands = new LinkedList<String>();
+        List<String> commands = new LinkedList<>();
         //fill it
         addCommandsToList(commands.listIterator());
         //convert to an array
@@ -555,6 +558,7 @@
      * Get a string description.
      * @return the command line as a string.
      */
+    @Override
     public String toString() {
         return Commandline.toString(getCommandline());
     }
@@ -606,6 +610,7 @@
      *             Please dont use this, it effectively creates the
      *             entire command.
      */
+    @Deprecated
     public int size() {
         int size = getActualVMCommand().size() + javaCommand.size()
             + sysProperties.size();
@@ -714,7 +719,8 @@
      * @throws BuildException if anything went wrong.
      * @throws CloneNotSupportedException never.
      */
-    public Object clone() throws CloneNotSupportedException {
+    @Override
+    public CommandlineJava clone() throws CloneNotSupportedException {
         try {
             CommandlineJava c = (CommandlineJava) super.clone();
             c.vmCommand = (Commandline) vmCommand.clone();
@@ -782,7 +788,7 @@
         Path fullClasspath = modulepath != null
                 ? modulepath.concatSystemClasspath("ignore") : null;
         return fullClasspath != null
-            && fullClasspath.toString().trim().length() > 0;
+            && !fullClasspath.toString().trim().isEmpty();
     }
 
     /**
@@ -792,8 +798,8 @@
      */
     public boolean haveUpgrademodulepath() {
         Path fullClasspath = upgrademodulepath != null
-            ? upgrademodulepath.concatSystemClasspath("ignore") : null;
-        return fullClasspath != null && fullClasspath.toString().trim().length() > 0;
+                ? upgrademodulepath.concatSystemClasspath("ignore") : null;
+        return fullClasspath != null && !fullClasspath.toString().trim().isEmpty();
     }
 
     /**
@@ -828,7 +834,7 @@
      * @since 1.7
      */
     private boolean isCloneVm() {
-        return cloneVm || "true".equals(System.getProperty("ant.build.clonevm"));
+        return cloneVm || Boolean.parseBoolean(System.getProperty("ant.build.clonevm"));
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/types/DataType.java b/src/main/org/apache/tools/ant/types/DataType.java
index 7b2ec7a..decfaa8 100644
--- a/src/main/org/apache/tools/ant/types/DataType.java
+++ b/src/main/org/apache/tools/ant/types/DataType.java
@@ -342,6 +342,7 @@
      * Basic DataType toString().
      * @return this DataType formatted as a String.
      */
+    @Override
     public String toString() {
         String d = getDescription();
         return d == null ? getDataTypeName() : getDataTypeName() + " " + d;
@@ -352,6 +353,7 @@
      * @return a shallow copy of this DataType.
      * @throws CloneNotSupportedException if there is a problem.
      */
+    @Override
     public Object clone() throws CloneNotSupportedException {
         DataType dt = (DataType) super.clone();
         dt.setDescription(getDescription());
diff --git a/src/main/org/apache/tools/ant/types/Description.java b/src/main/org/apache/tools/ant/types/Description.java
index d23f1d8..822697b 100644
--- a/src/main/org/apache/tools/ant/types/Description.java
+++ b/src/main/org/apache/tools/ant/types/Description.java
@@ -17,8 +17,9 @@
  */
 package org.apache.tools.ant.types;
 
-import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.ProjectHelper;
@@ -90,7 +91,7 @@
         if (t == null) {
             return;
         }
-        for (Task task : findElementInTarget(project, t, "description")) {
+        for (Task task : findElementInTarget(t, "description")) {
             if (!(task instanceof UnknownElement)) {
                 continue;
             }
@@ -102,15 +103,10 @@
         }
     }
 
-    private static List<Task> findElementInTarget(Project project,
-                                              Target t, String name) {
-        final List<Task> elems = new ArrayList<Task>();
-        for (Task task : t.getTasks()) {
-            if (name.equals(task.getTaskName())) {
-                elems.add(task);
-            }
-        }
-        return elems;
+    private static List<Task> findElementInTarget(Target t, String name) {
+        return Stream.of(t.getTasks())
+            .filter(task -> name.equals(task.getTaskName()))
+            .collect(Collectors.toList());
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/DirSet.java b/src/main/org/apache/tools/ant/types/DirSet.java
index 35c0231..12d9414 100644
--- a/src/main/org/apache/tools/ant/types/DirSet.java
+++ b/src/main/org/apache/tools/ant/types/DirSet.java
@@ -19,6 +19,8 @@
 package org.apache.tools.ant.types;
 
 import java.util.Iterator;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.DirectoryScanner;
 import org.apache.tools.ant.types.resources.FileResourceIterator;
@@ -51,12 +53,12 @@
      * as this one.
      * @return the cloned dirset.
      */
-    public Object clone() {
+    @Override
+    public DirSet clone() {
         if (isReference()) {
             return ((DirSet) getRef(getProject())).clone();
-        } else {
-            return super.clone();
         }
+        return (DirSet) super.clone();
     }
 
     /**
@@ -64,6 +66,7 @@
      * @return an Iterator of Resources.
      * @since Ant 1.7
      */
+    @Override
     public Iterator<Resource> iterator() {
         if (isReference()) {
             return ((DirSet) getRef(getProject())).iterator();
@@ -77,6 +80,7 @@
      * @return number of elements as int.
      * @since Ant 1.7
      */
+    @Override
     public int size() {
         if (isReference()) {
             return ((DirSet) getRef(getProject())).size();
@@ -89,6 +93,7 @@
      * @return true indicating that all elements will be FileResources.
      * @since Ant 1.7
      */
+    @Override
     public boolean isFilesystemOnly() {
         return true;
     }
@@ -98,18 +103,10 @@
      *
      * @return a <code>String</code> of included directories.
      */
+    @Override
     public String toString() {
         DirectoryScanner ds = getDirectoryScanner(getProject());
-        String[] dirs = ds.getIncludedDirectories();
-        StringBuffer sb = new StringBuffer();
-
-        for (int i = 0; i < dirs.length; i++) {
-            if (i > 0) {
-                sb.append(';');
-            }
-            sb.append(dirs[i]);
-        }
-        return sb.toString();
+        return Stream.of(ds.getIncludedDirectories()).collect(Collectors.joining(";"));
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/EnumeratedAttribute.java b/src/main/org/apache/tools/ant/types/EnumeratedAttribute.java
index 18603b2..dac3966 100644
--- a/src/main/org/apache/tools/ant/types/EnumeratedAttribute.java
+++ b/src/main/org/apache/tools/ant/types/EnumeratedAttribute.java
@@ -73,7 +73,7 @@
             throw new BuildException(
                 "You have to provide a subclass from EnumeratedAttribute as clazz-parameter.");
         }
-        EnumeratedAttribute ea = null;
+        EnumeratedAttribute ea;
         try {
             ea = clazz.newInstance();
         } catch (Exception e) {
@@ -146,6 +146,7 @@
      *
      * @return the string form of the value.
      */
+    @Override
     public String toString() {
         return getValue();
     }
diff --git a/src/main/org/apache/tools/ant/types/Environment.java b/src/main/org/apache/tools/ant/types/Environment.java
index 5bc6d79..3f33c74 100644
--- a/src/main/org/apache/tools/ant/types/Environment.java
+++ b/src/main/org/apache/tools/ant/types/Environment.java
@@ -115,9 +115,8 @@
          */
         public String getContent() throws BuildException {
             validate();
-            StringBuffer sb = new StringBuffer(key.trim());
-            sb.append("=").append(value.trim());
-            return sb.toString();
+            return new StringBuilder(key.trim()).append("=")
+                .append(value.trim()).toString();
         }
 
         /**
@@ -126,8 +125,8 @@
          */
         public void validate() {
             if (key == null || value == null) {
-                throw new BuildException("key and value must be specified "
-                    + "for environment variables.");
+                throw new BuildException(
+                    "key and value must be specified for environment variables.");
             }
         }
     }
@@ -136,7 +135,7 @@
      * constructor
      */
     public Environment() {
-        variables = new Vector<Variable>();
+        variables = new Vector<>();
     }
 
     /**
@@ -155,14 +154,10 @@
      * @throws BuildException if any variable is misconfigured
      */
     public String[] getVariables() throws BuildException {
-        if (variables.size() == 0) {
+        if (variables.isEmpty()) {
             return null;
         }
-        String[] result = new String[variables.size()];
-        for (int i = 0; i < result.length; i++) {
-            result[i] = ((Variable) variables.elementAt(i)).getContent();
-        }
-        return result;
+        return variables.stream().map(Variable::getContent).toArray(String[]::new);
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/types/FileList.java b/src/main/org/apache/tools/ant/types/FileList.java
index c36ba6c..32485e7 100644
--- a/src/main/org/apache/tools/ant/types/FileList.java
+++ b/src/main/org/apache/tools/ant/types/FileList.java
@@ -37,7 +37,7 @@
  */
 public class FileList extends DataType implements ResourceCollection {
 
-    private List<String> filenames = new ArrayList<String>();
+    private List<String> filenames = new ArrayList<>();
     private File dir;
 
     /**
@@ -68,8 +68,9 @@
      * @param r the reference to another filelist.
      * @exception BuildException if an error occurs.
      */
+    @Override
     public void setRefid(Reference r) throws BuildException {
-        if ((dir != null) || (filenames.size() != 0)) {
+        if ((dir != null) || (!filenames.isEmpty())) {
             throw tooManyAttributes();
         }
         super.setRefid(r);
@@ -105,7 +106,7 @@
      */
     public void setFiles(String filenames) {
         checkAttributesAllowed();
-        if (filenames != null && filenames.length() > 0) {
+        if (!(filenames == null || filenames.isEmpty())) {
             StringTokenizer tok = new StringTokenizer(
                 filenames, ", \t\n\r\f", false);
             while (tok.hasMoreTokens()) {
@@ -128,7 +129,7 @@
             throw new BuildException("No directory specified for filelist.");
         }
 
-        if (filenames.size() == 0) {
+        if (filenames.isEmpty()) {
             throw new BuildException("No files specified for filelist.");
         }
 
@@ -187,6 +188,7 @@
      * @return an Iterator of Resources.
      * @since Ant 1.7
      */
+    @Override
     public Iterator<Resource> iterator() {
         if (isReference()) {
             return getRef(getProject()).iterator();
@@ -200,9 +202,10 @@
      * @return number of elements as int.
      * @since Ant 1.7
      */
+    @Override
     public int size() {
         if (isReference()) {
-            return ((FileList) getRef(getProject())).size();
+            return getRef(getProject()).size();
         }
         return filenames.size();
     }
@@ -212,6 +215,7 @@
      * @return true indicating that all elements will be FileResources.
      * @since Ant 1.7
      */
+    @Override
     public boolean isFilesystemOnly() {
         return true;
     }
diff --git a/src/main/org/apache/tools/ant/types/FileSet.java b/src/main/org/apache/tools/ant/types/FileSet.java
index c6d2127..244e204 100644
--- a/src/main/org/apache/tools/ant/types/FileSet.java
+++ b/src/main/org/apache/tools/ant/types/FileSet.java
@@ -49,12 +49,12 @@
      * as this one.
      * @return the cloned fileset
      */
-    public Object clone() {
+    @Override
+    public FileSet clone() {
         if (isReference()) {
             return ((FileSet) getRef(getProject())).clone();
-        } else {
-            return super.clone();
         }
+        return (FileSet) super.clone();
     }
 
     /**
@@ -62,6 +62,7 @@
      * @return an Iterator of Resources.
      * @since Ant 1.7
      */
+    @Override
     public Iterator<Resource> iterator() {
         if (isReference()) {
             return ((FileSet) getRef(getProject())).iterator();
@@ -75,6 +76,7 @@
      * @return number of elements as int.
      * @since Ant 1.7
      */
+    @Override
     public int size() {
         if (isReference()) {
             return ((FileSet) getRef(getProject())).size();
@@ -87,6 +89,7 @@
      * @return true indicating that all elements will be FileResources.
      * @since Ant 1.7
      */
+    @Override
     public boolean isFilesystemOnly() {
         return true;
     }
diff --git a/src/main/org/apache/tools/ant/types/FilterSet.java b/src/main/org/apache/tools/ant/types/FilterSet.java
index 2c1f2e7..3917833 100644
--- a/src/main/org/apache/tools/ant/types/FilterSet.java
+++ b/src/main/org/apache/tools/ant/types/FilterSet.java
@@ -18,7 +18,8 @@
 package org.apache.tools.ant.types;
 
 import java.io.File;
-import java.io.FileInputStream;
+import java.io.InputStream;
+import java.nio.file.Files;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.Map;
@@ -28,7 +29,6 @@
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
-import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.VectorSet;
 
 /**
@@ -113,12 +113,6 @@
     public class FiltersFile {
 
         /**
-         * Constructor for the FiltersFile object.
-         */
-        public FiltersFile() {
-        }
-
-        /**
          * Sets the file from which filters will be read.
          *
          * @param file the file from which filters will be read.
@@ -186,7 +180,7 @@
 
     private boolean recurse = true;
     private Hashtable<String, String> filterHash = null;
-    private Vector<File> filtersFiles = new Vector<File>();
+    private Vector<File> filtersFiles = new Vector<>();
     private OnMissing onMissingFiltersFile = OnMissing.FAIL;
     private boolean readingFiles = false;
 
@@ -195,7 +189,7 @@
     /**
      * List of ordered filters and filter files.
      */
-    private Vector<Filter> filters = new Vector<Filter>();
+    private Vector<Filter> filters = new Vector<>();
 
     /**
      * Default constructor.
@@ -258,7 +252,7 @@
         }
         dieOnCircularReference();
         if (filterHash == null) {
-            filterHash = new Hashtable<String, String>(getFilters().size());
+            filterHash = new Hashtable<>(getFilters().size());
             for (Enumeration<Filter> e = getFilters().elements(); e.hasMoreElements();) {
                Filter filter = e.nextElement();
                filterHash.put(filter.getToken(), filter.getValue());
@@ -357,39 +351,28 @@
      * @param filtersFile        the file from which filters are read.
      * @exception BuildException when the file cannot be read.
      */
-    public synchronized void readFiltersFromFile(File filtersFile) throws BuildException {
+    public synchronized void readFiltersFromFile(File filtersFile)
+        throws BuildException {
         if (isReference()) {
             throw tooManyAttributes();
         }
         if (!filtersFile.exists()) {
-           handleMissingFile("Could not read filters from file "
-                                     + filtersFile + " as it doesn't exist.");
+            handleMissingFile("Could not read filters from file " + filtersFile
+                + " as it doesn't exist.");
         }
         if (filtersFile.isFile()) {
-           log("Reading filters from " + filtersFile, Project.MSG_VERBOSE);
-           FileInputStream in = null;
-           try {
-              Properties props = new Properties();
-              in = new FileInputStream(filtersFile);
-              props.load(in);
-
-              Enumeration<?> e = props.propertyNames();
-              Vector<Filter> filts = getFilters();
-              while (e.hasMoreElements()) {
-                 String strPropName = (String) e.nextElement();
-                 String strValue = props.getProperty(strPropName);
-                 filts.addElement(new Filter(strPropName, strValue));
-              }
-           } catch (Exception ex) {
-              throw new BuildException("Could not read filters from file: "
-                  + filtersFile, ex);
-           } finally {
-              FileUtils.close(in);
-           }
+            log("Reading filters from " + filtersFile, Project.MSG_VERBOSE);
+            try (InputStream in = Files.newInputStream(filtersFile.toPath())) {
+                Properties props = new Properties();
+                props.load(in);
+                props.forEach((k, v) -> addFilter(new Filter((String) k, (String) v)));
+            } catch (Exception ex) {
+                throw new BuildException(
+                    "Could not read filters from file: " + filtersFile, ex);
+            }
         } else {
-           handleMissingFile(
-               "Must specify a file rather than a directory in "
-               + "the filtersfile attribute:" + filtersFile);
+            handleMissingFile("Must specify a file rather than a directory in "
+                + "the filtersfile attribute:" + filtersFile);
         }
         filterHash = null;
     }
@@ -470,7 +453,7 @@
             throw noChildrenAllowed();
         }
         Properties p = propertySet.getProperties();
-        Set<Map.Entry<Object,Object>> entries = p.entrySet();
+        Set<Map.Entry<Object, Object>> entries = p.entrySet();
         for (Map.Entry<Object, Object> entry : entries) {
             addFilter(new Filter(String.valueOf(entry.getKey()),
                                  String.valueOf(entry.getValue())));
@@ -483,7 +466,7 @@
      * @return Return true if there are filters in this set.
      */
     public synchronized boolean hasFilters() {
-        return getFilters().size() > 0;
+        return !getFilters().isEmpty();
     }
 
     /**
@@ -544,8 +527,6 @@
             try {
                 StringBuilder b = new StringBuilder();
                 int i = 0;
-                String token = null;
-                String value = null;
 
                 while (index > -1) {
                     //can't have zero-length token
@@ -554,11 +535,11 @@
                     if (endIndex == -1) {
                         break;
                     }
-                    token
-                        = line.substring(index + beginToken.length(), endIndex);
+                    String token =
+                        line.substring(index + beginToken.length(), endIndex);
                     b.append(line.substring(i, index));
                     if (tokens.containsKey(token)) {
-                        value = tokens.get(token);
+                        String value = tokens.get(token);
                         if (recurse && !value.equals(token)) {
                             // we have another token, let's parse it.
                             value = replaceTokens(value, token);
@@ -602,7 +583,7 @@
         String beginToken = getBeginToken();
         String endToken = getEndToken();
         if (recurseDepth == 0) {
-            passedTokens = new VectorSet<String>();
+            passedTokens = new VectorSet<>();
         }
         recurseDepth++;
         if (passedTokens.contains(parent) && !duplicateToken) {
@@ -622,14 +603,14 @@
             passedTokens = null;
         } else if (duplicateToken) {
             // should always be the case...
-            if (passedTokens.size() > 0) {
+            if (!passedTokens.isEmpty()) {
                 value = passedTokens.remove(passedTokens.size() - 1);
-                if (passedTokens.size() == 0) {
+                if (passedTokens.isEmpty()) {
                     value = beginToken + value + endToken;
                     duplicateToken = false;
                 }
             }
-        } else if (passedTokens.size() > 0) {
+        } else if (!passedTokens.isEmpty()) {
             // remove last seen token when crawling out of recursion
             passedTokens.remove(passedTokens.size() - 1);
         }
diff --git a/src/main/org/apache/tools/ant/types/FilterSetCollection.java b/src/main/org/apache/tools/ant/types/FilterSetCollection.java
index 8afb963..500f32f 100644
--- a/src/main/org/apache/tools/ant/types/FilterSetCollection.java
+++ b/src/main/org/apache/tools/ant/types/FilterSetCollection.java
@@ -28,7 +28,7 @@
  */
 public class FilterSetCollection {
 
-    private List<FilterSet> filterSets = new ArrayList<FilterSet>();
+    private List<FilterSet> filterSets = new ArrayList<>();
 
     /**
      * Constructor for a FilterSetCollection.
@@ -75,12 +75,7 @@
     * @return   Return true if there are filter in this set otherwise false.
     */
     public boolean hasFilters() {
-        for (FilterSet filterSet : filterSets) {
-            if (filterSet.hasFilters()) {
-                return true;
-            }
-        }
-        return false;
+        return filterSets.stream().anyMatch(FilterSet::hasFilters);
     }
 }
 
diff --git a/src/main/org/apache/tools/ant/types/FlexInteger.java b/src/main/org/apache/tools/ant/types/FlexInteger.java
index d757429..9bce762 100644
--- a/src/main/org/apache/tools/ant/types/FlexInteger.java
+++ b/src/main/org/apache/tools/ant/types/FlexInteger.java
@@ -48,6 +48,7 @@
      * Overridden method to return the decimal value for display
      * @return a string version of the integer
      */
+    @Override
     public String toString() {
         return value.toString();
     }
diff --git a/src/main/org/apache/tools/ant/types/LogLevel.java b/src/main/org/apache/tools/ant/types/LogLevel.java
index a02b948..5c66d99 100644
--- a/src/main/org/apache/tools/ant/types/LogLevel.java
+++ b/src/main/org/apache/tools/ant/types/LogLevel.java
@@ -55,6 +55,7 @@
      * @see EnumeratedAttribute#getValues
      * @return the strings allowed for the level attribute
      */
+    @Override
     public String[] getValues() {
         return new String[] {
             "error",
diff --git a/src/main/org/apache/tools/ant/types/Mapper.java b/src/main/org/apache/tools/ant/types/Mapper.java
index c02e782..6b922a7 100644
--- a/src/main/org/apache/tools/ant/types/Mapper.java
+++ b/src/main/org/apache/tools/ant/types/Mapper.java
@@ -187,6 +187,7 @@
      * @param r the reference to another mapper
      * @throws BuildException if other attributes are set
      */
+    @Override
     public void setRefid(Reference r) throws BuildException {
         if (type != null || from != null || to != null) {
             throw tooManyAttributes();
@@ -306,6 +307,7 @@
         /**
          * @return the filenamemapper names
          */
+        @Override
         public String[] getValues() {
             return new String[] {"identity", "flatten", "glob",
                                  "merge", "regexp", "package", "unpackage"};
diff --git a/src/main/org/apache/tools/ant/types/Parameterizable.java b/src/main/org/apache/tools/ant/types/Parameterizable.java
index 7945a9a..188b76b 100644
--- a/src/main/org/apache/tools/ant/types/Parameterizable.java
+++ b/src/main/org/apache/tools/ant/types/Parameterizable.java
@@ -27,5 +27,5 @@
      *
      * @param parameters an array of name/type/value parameters.
      */
-    void setParameters(Parameter[] parameters);
+    void setParameters(Parameter... parameters);
 }
diff --git a/src/main/org/apache/tools/ant/types/Path.java b/src/main/org/apache/tools/ant/types/Path.java
index 70358d8..74f7c46 100644
--- a/src/main/org/apache/tools/ant/types/Path.java
+++ b/src/main/org/apache/tools/ant/types/Path.java
@@ -20,11 +20,12 @@
 
 import java.io.File;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Locale;
 import java.util.Stack;
-import java.util.Vector;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.MagicNames;
@@ -70,7 +71,6 @@
     public static Path systemClasspath = //NOSONAR
         new Path(null, System.getProperty("java.class.path"));
 
-
     /**
      * The system bootclasspath as a Path object.
      *
@@ -118,6 +118,7 @@
          * Create an iterator.
          * @return an iterator.
          */
+        @Override
         public Iterator<Resource> iterator() {
             return new FileResourceIterator(getProject(), null, parts);
         }
@@ -126,6 +127,7 @@
          * Check if this resource is only for filesystems.
          * @return true.
          */
+        @Override
         public boolean isFilesystemOnly() {
             return true;
         }
@@ -134,6 +136,7 @@
          * Get the number of resources.
          * @return the number of parts.
          */
+        @Override
         public int size() {
             return parts == null ? 0 : parts.length;
         }
@@ -193,6 +196,7 @@
      * @param r the reference to another Path
      * @throws BuildException on error
      */
+    @Override
     public void setRefid(Reference r) throws BuildException {
         if (union != null) {
             throw tooManyAttributes();
@@ -343,9 +347,9 @@
             } else if (f.getParentFile() != null && f.getParentFile().exists()
                        && containsWildcards(f.getName())) {
                 setLocation(f);
-                log("adding " + f + " which contains wildcards and may not"
-                    + " do what you intend it to do depending on your OS or"
-                    + " version of Java", Project.MSG_VERBOSE);
+                log("adding " + f
+                    + " which contains wildcards and may not do what you intend it to do depending on your OS or version of Java",
+                    Project.MSG_VERBOSE);
             } else {
                 log("dropping " + f + " from path as it doesn't exist",
                     Project.MSG_VERBOSE);
@@ -383,6 +387,7 @@
      * CLASSPATH or PATH environment variable definition.
      * @return a textual representation of the path.
      */
+    @Override
     public String toString() {
         return isReference() ? getCheckedRef().toString()
             : union == null ? "" : union.toString();
@@ -395,13 +400,13 @@
      * @return an array of strings, one for each path element
      */
     public static String[] translatePath(Project project, String source) {
-        final Vector<String> result = new Vector<String>();
         if (source == null) {
             return new String[0];
         }
+        final List<String> result = new ArrayList<>();
         PathTokenizer tok = new PathTokenizer(source);
-        StringBuffer element = new StringBuffer();
         while (tok.hasMoreTokens()) {
+            StringBuffer element = new StringBuffer();
             String pathElement = tok.nextToken();
             try {
                 element.append(resolveFile(project, pathElement).getPath());
@@ -413,8 +418,7 @@
             for (int i = 0; i < element.length(); i++) {
                 translateFileSep(element, i);
             }
-            result.addElement(element.toString());
-            element = new StringBuffer();
+            result.add(element.toString());
         }
         return result.toArray(new String[result.size()]);
     }
@@ -456,6 +460,7 @@
      * Fulfill the ResourceCollection contract.
      * @return number of elements as int.
      */
+    @Override
     public synchronized int size() {
         if (isReference()) {
             return ((Path) getCheckedRef()).size();
@@ -468,6 +473,7 @@
      * Clone this Path.
      * @return Path with shallowly cloned Resource children.
      */
+    @Override
     public Object clone() {
         try {
             Path result = (Path) super.clone();
@@ -485,6 +491,7 @@
      * @param p   the project to use to dereference the references.
      * @throws BuildException on error.
      */
+    @Override
     protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
@@ -555,22 +562,22 @@
         if (o != null) {
             order = o;
         }
-        if (order.equals("only")) {
+        if ("only".equals(order)) {
             // only: the developer knows what (s)he is doing
             result.addExisting(p, true);
 
-        } else if (order.equals("first")) {
+        } else if ("first".equals(order)) {
             // first: developer could use a little help
             result.addExisting(p, true);
             result.addExisting(this);
 
-        } else if (order.equals("ignore")) {
+        } else if ("ignore".equals(order)) {
             // ignore: don't trust anyone
             result.addExisting(this);
 
         } else {
             // last: don't trust the developer
-            if (!order.equals("last")) {
+            if (!"last".equals(order)) {
                 log("invalid value for " + MagicNames.BUILD_SYSCLASSPATH
                     + ": " + order,
                     Project.MSG_WARN);
@@ -697,6 +704,7 @@
      * are added to this container while the Iterator is in use.
      * @return a "fail-fast" Iterator.
      */
+    @Override
     public final synchronized Iterator<Resource> iterator() {
         if (isReference()) {
             return ((Path) getCheckedRef()).iterator();
@@ -713,6 +721,7 @@
      * Fulfill the ResourceCollection contract.
      * @return whether this is a filesystem-only resource collection.
      */
+    @Override
     public synchronized boolean isFilesystemOnly() {
         if (isReference()) {
             return ((Path) getCheckedRef()).isFilesystemOnly();
@@ -730,8 +739,8 @@
      */
     protected ResourceCollection assertFilesystemOnly(ResourceCollection rc) {
         if (rc != null && !(rc.isFilesystemOnly())) {
-            throw new BuildException(getDataTypeName()
-                + " allows only filesystem resources.");
+            throw new BuildException("%s allows only filesystem resources.",
+                getDataTypeName());
         }
         return rc;
     }
@@ -749,7 +758,7 @@
             return false;
         }
         try {
-            Method listMethod = getClass().getMethod("list", (Class[]) null);
+            Method listMethod = getClass().getMethod("list");
             return !listMethod.getDeclaringClass().equals(Path.class);
         } catch (Exception e) {
             //shouldn't happen, but
@@ -770,7 +779,7 @@
      */
     private static boolean containsWildcards(String path) {
         return path != null
-            && (path.indexOf("*") > -1 || path.indexOf("?") > -1);
+            && (path.indexOf('*') > -1 || path.indexOf('?') > -1);
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/PatternSet.java b/src/main/org/apache/tools/ant/types/PatternSet.java
index 9fb9405..c958d8e 100644
--- a/src/main/org/apache/tools/ant/types/PatternSet.java
+++ b/src/main/org/apache/tools/ant/types/PatternSet.java
@@ -23,12 +23,13 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.StringTokenizer;
+import java.util.function.Predicate;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.PropertyHelper;
-import org.apache.tools.ant.util.FileUtils;
 
 /**
  * Named collection of include/exclude tags.
@@ -38,10 +39,10 @@
  *
  */
 public class PatternSet extends DataType implements Cloneable {
-    private List<NameEntry> includeList = new ArrayList<NameEntry>();
-    private List<NameEntry> excludeList = new ArrayList<NameEntry>();
-    private List<NameEntry> includesFileList = new ArrayList<NameEntry>();
-    private List<NameEntry> excludesFileList = new ArrayList<NameEntry>();
+    private List<NameEntry> includeList = new ArrayList<>();
+    private List<NameEntry> excludeList = new ArrayList<>();
+    private List<NameEntry> includesFileList = new ArrayList<>();
+    private List<NameEntry> excludesFileList = new ArrayList<>();
 
     /**
      * inner class to hold a name on list.  "If" and "Unless" attributes
@@ -150,8 +151,9 @@
         /**
          * @return a printable form of this object.
          */
+        @Override
         public String toString() {
-            StringBuffer buf = new StringBuffer();
+            StringBuilder buf = new StringBuilder();
             if (name == null) {
                 buf.append("noname");
             } else {
@@ -181,9 +183,11 @@
             setProject(p.getProject());
             addConfiguredPatternset(p);
         }
+        @Override
         public String[] getIncludePatterns(Project p) {
             return super.getExcludePatterns(p);
         }
+        @Override
         public String[] getExcludePatterns(Project p) {
             return super.getIncludePatterns(p);
         }
@@ -205,6 +209,7 @@
      * @param r the reference to another patternset.
      * @throws BuildException on error.
      */
+    @Override
     public void setRefid(Reference r) throws BuildException {
         if (!includeList.isEmpty() || !excludeList.isEmpty()) {
             throw tooManyAttributes();
@@ -290,7 +295,7 @@
         if (isReference()) {
             throw tooManyAttributes();
         }
-        if (includes != null && includes.length() > 0) {
+        if (includes != null && !includes.isEmpty()) {
             StringTokenizer tok = new StringTokenizer(includes, ", ", false);
             while (tok.hasMoreTokens()) {
                 createInclude().setName(tok.nextToken());
@@ -308,7 +313,7 @@
         if (isReference()) {
             throw tooManyAttributes();
         }
-        if (excludes != null && excludes.length() > 0) {
+        if (excludes != null && !excludes.isEmpty()) {
             StringTokenizer tok = new StringTokenizer(excludes, ", ", false);
             while (tok.hasMoreTokens()) {
                 createExclude().setName(tok.nextToken());
@@ -358,26 +363,19 @@
     private void readPatterns(File patternfile, List<NameEntry> patternlist, Project p)
             throws BuildException {
 
-        BufferedReader patternReader = null;
-        try {
-            // Get a FileReader
-            patternReader = new BufferedReader(new FileReader(patternfile));
+        try (BufferedReader patternReader =
+            new BufferedReader(new FileReader(patternfile))) {
 
             // Create one NameEntry in the appropriate pattern list for each
             // line in the file.
-            String line = patternReader.readLine();
-            while (line != null) {
-                if (line.length() > 0) {
-                    line = p.replaceProperties(line);
-                    addPatternToList(patternlist).setName(line);
-                }
-                line = patternReader.readLine();
-            }
+            patternReader.lines()
+                .filter(((Predicate<String>) String::isEmpty).negate())
+                .map(p::replaceProperties)
+                .forEach(line -> addPatternToList(patternlist).setName(line));
+
         } catch (IOException ioe)  {
             throw new BuildException("An error occurred while reading from pattern file: "
                     + patternfile, ioe);
-        } finally {
-            FileUtils.close(patternReader);
         }
     }
 
@@ -444,8 +442,8 @@
             return getRef(p).hasPatterns(p);
         }
         dieOnCircularReference(p);
-        return includesFileList.size() > 0 || excludesFileList.size() > 0
-                || includeList.size() > 0 || excludeList.size() > 0;
+        return !(includesFileList.isEmpty() && excludesFileList.isEmpty()
+            && includeList.isEmpty() && excludeList.isEmpty());
     }
 
     /**
@@ -460,24 +458,18 @@
      * Convert a vector of NameEntry elements into an array of Strings.
      */
     private String[] makeArray(List<NameEntry> list, Project p) {
-        if (list.size() == 0) {
+        if (list.isEmpty()) {
             return null;
         }
-        ArrayList<String> tmpNames = new ArrayList<String>();
-        for (NameEntry ne : list) {
-            String pattern = ne.evalName(p);
-            if (pattern != null && pattern.length() > 0) {
-                tmpNames.add(pattern);
-            }
-        }
-        return tmpNames.toArray(new String[tmpNames.size()]);
+        return list.stream().map(ne -> ne.evalName(p)).filter(Objects::nonNull)
+            .filter(pattern -> !pattern.isEmpty()).toArray(String[]::new);
     }
 
     /**
      * Read includesfile ot excludesfile if not already done so.
      */
     private void readFiles(Project p) {
-        if (includesFileList.size() > 0) {
+        if (!includesFileList.isEmpty()) {
             for (NameEntry ne : includesFileList) {
                 String fileName = ne.evalName(p);
                 if (fileName != null) {
@@ -491,7 +483,7 @@
             }
             includesFileList.clear();
         }
-        if (excludesFileList.size() > 0) {
+        if (!excludesFileList.isEmpty()) {
             for (NameEntry ne : excludesFileList) {
                 String fileName = ne.evalName(p);
                 if (fileName != null) {
@@ -510,21 +502,24 @@
     /**
      * @return a printable form of this object.
      */
+    @Override
     public String toString() {
-        return "patternSet{ includes: " + includeList + " excludes: " + excludeList + " }";
+        return String.format("patternSet{ includes: %s excludes: %s }",
+            includeList, excludeList);
     }
 
     /**
      * @since Ant 1.6
      * @return a clone of this patternset.
      */
-    public Object clone() {
+    @Override
+    public PatternSet clone() {
         try {
             PatternSet ps = (PatternSet) super.clone();
-            ps.includeList = new ArrayList<NameEntry>(includeList);
-            ps.excludeList = new ArrayList<NameEntry>(excludeList);
-            ps.includesFileList = new ArrayList<NameEntry>(includesFileList);
-            ps.excludesFileList = new ArrayList<NameEntry>(excludesFileList);
+            ps.includeList = new ArrayList<>(includeList);
+            ps.excludeList = new ArrayList<>(excludeList);
+            ps.includesFileList = new ArrayList<>(includesFileList);
+            ps.excludesFileList = new ArrayList<>(excludesFileList);
             return ps;
         } catch (CloneNotSupportedException e) {
             throw new BuildException(e);
diff --git a/src/main/org/apache/tools/ant/types/Permissions.java b/src/main/org/apache/tools/ant/types/Permissions.java
index d0559c7..d476427 100644
--- a/src/main/org/apache/tools/ant/types/Permissions.java
+++ b/src/main/org/apache/tools/ant/types/Permissions.java
@@ -44,8 +44,8 @@
  */
 public class Permissions {
 
-    private final List<Permission> grantedPermissions = new LinkedList<Permission>();
-    private final List<Permission> revokedPermissions = new LinkedList<Permission>();
+    private final List<Permission> grantedPermissions = new LinkedList<>();
+    private final List<Permission> revokedPermissions = new LinkedList<>();
     private java.security.Permissions granted = null;
     private SecurityManager origSm = null;
     private boolean active = false;
@@ -284,7 +284,7 @@
          */
         public void setActions(final String actions) {
             actionString = actions;
-            if (actions.length() > 0) {
+            if (!actions.isEmpty()) {
                 this.actions = parseActions(actions);
             }
         }
@@ -310,10 +310,8 @@
                     if (!perm.getName().startsWith(name.substring(0, name.length() - 1))) {
                         return false;
                     }
-                } else {
-                    if (!name.equals(perm.getName())) {
-                        return false;
-                    }
+                } else if (!name.equals(perm.getName())) {
+                    return false;
                 }
             }
             if (actions != null) {
@@ -333,11 +331,11 @@
          * @param actions The actions to be parsed.
          */
         private Set<String> parseActions(final String actions) {
-            final Set<String> result = new HashSet<String>();
+            final Set<String> result = new HashSet<>();
             final StringTokenizer tk = new StringTokenizer(actions, ",");
             while (tk.hasMoreTokens()) {
                 final String item = tk.nextToken().trim();
-                if (!item.equals("")) {
+                if (!"".equals(item)) {
                     result.add(item);
                 }
             }
diff --git a/src/main/org/apache/tools/ant/types/PropertySet.java b/src/main/org/apache/tools/ant/types/PropertySet.java
index f599204..85e65d2 100644
--- a/src/main/org/apache/tools/ant/types/PropertySet.java
+++ b/src/main/org/apache/tools/ant/types/PropertySet.java
@@ -22,15 +22,16 @@
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Optional;
 import java.util.Properties;
 import java.util.Set;
 import java.util.Stack;
 import java.util.TreeMap;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -50,8 +51,8 @@
     private boolean dynamic = true;
     private boolean negate = false;
     private Set<String> cachedNames;
-    private List<PropertyRef> ptyRefs = new ArrayList<PropertyRef>();
-    private List<PropertySet> setRefs = new ArrayList<PropertySet>();
+    private List<PropertyRef> ptyRefs = new ArrayList<>();
+    private List<PropertySet> setRefs = new ArrayList<>();
     private Mapper mapper;
 
     /**
@@ -118,6 +119,7 @@
          * A debug toString().
          * @return a string version of this object.
          */
+        @Override
         public String toString() {
             return "name=" + name + ", regex=" + regex + ", prefix=" + prefix
                 + ", builtin=" + builtin;
@@ -273,12 +275,12 @@
     }
 
     /**
-     * Convert the system properties to a hashtable.
+     * Convert the system properties to a Map.
      * Use propertynames to get the list of properties (including
      * default ones).
      */
-    private Hashtable<String, Object> getAllSystemProperties() {
-        Hashtable<String, Object>  ret = new Hashtable<String, Object>();
+    private Map<String, Object> getAllSystemProperties() {
+        Map<String, Object>  ret = new HashMap<>();
         for (Enumeration<?> e = System.getProperties().propertyNames();
              e.hasMoreElements();) {
             String name = (String) e.nextElement();
@@ -312,7 +314,7 @@
 
         final Map<String, Object> effectiveProperties = getEffectiveProperties();
         final Set<String> propertyNames = getPropertyNames(effectiveProperties);
-        final Map<String, Object> result = new HashMap<String, Object>();
+        final Map<String, Object> result = new HashMap<>();
 
         //iterate through the names, get the matching values
         for (String name : propertyNames) {
@@ -349,7 +351,7 @@
     private Set<String> getPropertyNames(Map<String, Object> props) {
         Set<String> names;
         if (getDynamic() || cachedNames == null) {
-            names = new HashSet<String>();
+            names = new HashSet<>();
             addPropertyNames(names, props);
             // Add this PropertySet's nested PropertySets' property names.
             for (PropertySet set : setRefs) {
@@ -357,7 +359,7 @@
             }
             if (negate) {
                 //make a copy...
-                HashSet<String> complement = new HashSet<String>(props.keySet());
+                HashSet<String> complement = new HashSet<>(props.keySet());
                 complement.removeAll(names);
                 names = complement;
             }
@@ -427,7 +429,7 @@
      * @return the referenced PropertySet.
      */
     protected PropertySet getRef() {
-        return (PropertySet) getCheckedRef(PropertySet.class, "propertyset");
+        return getCheckedRef(PropertySet.class, "propertyset");
     }
 
     /**
@@ -437,6 +439,7 @@
      * @throws BuildException if another attribute was set, since
      *         refid and all other attributes are mutually exclusive.
      */
+    @Override
     public final void setRefid(Reference r) {
         if (!noAttributeSet) {
             throw tooManyAttributes();
@@ -475,6 +478,7 @@
         static final String SYSTEM = "system";
         static final String COMMANDLINE = "commandline";
         /** {@inheritDoc}. */
+        @Override
         public String[] getValues() {
             return new String[] {ALL, SYSTEM, COMMANDLINE};
         }
@@ -487,13 +491,14 @@
      * The output order is sorted according to the keys' <i>natural order</i>.
      * @return a string rep of this object.
      */
+    @Override
     public String toString() {
         if (isReference()) {
             return getRef().toString();
         }
         dieOnCircularReference();
         StringBuilder b = new StringBuilder();
-        TreeMap<String, Object> sorted = new TreeMap<String, Object>(getPropertyMap());
+        TreeMap<String, Object> sorted = new TreeMap<>(getPropertyMap());
         for (Entry<String, Object> e : sorted.entrySet()) {
             if (b.length() != 0) {
                 b.append(", ");
@@ -510,35 +515,27 @@
      * @return an Iterator of Resources.
      * @since Ant 1.7
      */
+    @Override
     public Iterator<Resource> iterator() {
         if (isReference()) {
             return getRef().iterator();
         }
         dieOnCircularReference();
-        final Set<String> names = getPropertyNames(getEffectiveProperties());
-
-        Mapper myMapper = getMapper();
-        final FileNameMapper m = myMapper == null ? null : myMapper.getImplementation();
-        final Iterator<String> iter = names.iterator();
-
-        return new Iterator<Resource>() {
-            public boolean hasNext() {
-                return iter.hasNext();
-            }
-            public Resource next() {
-                PropertyResource p = new PropertyResource(getProject(), iter.next());
-                return m == null ? (Resource) p : new MappedResource(p, m);
-            }
-            public void remove() {
-                throw new UnsupportedOperationException();
-            }
-        };
+        Stream<Resource> result = getPropertyNames(getEffectiveProperties())
+            .stream().map(name -> new PropertyResource(getProject(), name));
+        Optional<FileNameMapper> m =
+            Optional.ofNullable(getMapper()).map(Mapper::getImplementation);
+        if (m.isPresent()) {
+            result = result.map(p -> new MappedResource(p, m.get()));
+        }
+        return result.iterator();
     }
 
     /**
      * Fulfill the ResourceCollection contract.
      * @return the size of this ResourceCollection.
      */
+    @Override
     public int size() {
         return isReference() ? getRef().size() : getProperties().size();
     }
@@ -547,6 +544,7 @@
      * Fulfill the ResourceCollection contract.
      * @return whether this is a filesystem-only resource collection.
      */
+    @Override
     public boolean isFilesystemOnly() {
         if (isReference()) {
             return getRef().isFilesystemOnly();
@@ -555,6 +553,7 @@
         return false;
     }
 
+    @Override
     protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
diff --git a/src/main/org/apache/tools/ant/types/Quantifier.java b/src/main/org/apache/tools/ant/types/Quantifier.java
index fae3dc5..a62346f 100644
--- a/src/main/org/apache/tools/ant/types/Quantifier.java
+++ b/src/main/org/apache/tools/ant/types/Quantifier.java
@@ -17,6 +17,12 @@
  */
 package org.apache.tools.ant.types;
 
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.stream.Stream;
+
 import org.apache.tools.ant.BuildException;
 
 /**
@@ -36,61 +42,84 @@
  * @since Ant 1.7
  */
 public class Quantifier extends EnumeratedAttribute {
-    private static final String[] VALUES
-        = new String[] {"all", "each", "every", "any", "some", "one",
-                        "majority", "most", "none"};
+    private static final String[] VALUES =
+            Stream.of(Predicate.values()).map(Predicate::getNames)
+                .flatMap(Collection::stream).toArray(String[]::new);
 
     /** ALL instance */
-    public static final Quantifier ALL = new Quantifier("all");
+    public static final Quantifier ALL = new Quantifier(Predicate.ALL);
+
     /** ANY instance */
-    public static final Quantifier ANY = new Quantifier("any");
+    public static final Quantifier ANY = new Quantifier(Predicate.ANY);
+
     /** ONE instance */
-    public static final Quantifier ONE = new Quantifier("one");
+    public static final Quantifier ONE = new Quantifier(Predicate.ONE);
+
     /** MAJORITY instance */
-    public static final Quantifier MAJORITY = new Quantifier("majority");
+    public static final Quantifier MAJORITY =
+        new Quantifier(Predicate.MAJORITY);
+
     /** NONE instance */
-    public static final Quantifier NONE = new Quantifier("none");
+    public static final Quantifier NONE = new Quantifier(Predicate.NONE);
 
-    private abstract static class Predicate {
+    private enum Predicate {
+        ALL("all", "each", "every") {
+            @Override
+            boolean eval(int t, int f) {
+                return f == 0;
+            }
+        },
+
+        ANY("any", "some") {
+            @Override
+            boolean eval(int t, int f) {
+                return t > 0;
+            }
+        },
+
+        ONE("one") {
+            @Override
+            boolean eval(int t, int f) {
+                return t == 1;
+            }
+        },
+
+        MAJORITY("majority", "most") {
+            @Override
+            boolean eval(int t, int f) {
+                return t > f;
+            }
+        },
+
+        NONE("none") {
+            @Override
+            boolean eval(int t, int f) {
+                return t == 0;
+            }
+        };
+
+        static Predicate get(String name) {
+            return Stream.of(values()).filter(p -> p.names.contains(name))
+                .findFirst()
+                .orElseThrow(() -> new IllegalArgumentException(name));
+        }
+
+        final Set<String> names;
+
+        Predicate(String primaryName, String... additionalNames) {
+            Set<String> names = new LinkedHashSet<>();
+            names.add(primaryName);
+            Collections.addAll(names, additionalNames);
+            this.names = Collections.unmodifiableSet(names);
+        }
+
+        Set<String> getNames() {
+            return names;
+        }
+
         abstract boolean eval(int t, int f);
     }
 
-    private static final Predicate ALL_PRED = new Predicate() {
-        boolean eval(int t, int f) { return f == 0; }
-    };
-
-    private static final Predicate ANY_PRED = new Predicate() {
-        boolean eval(int t, int f) { return t > 0; }
-    };
-
-    private static final Predicate ONE_PRED = new Predicate() {
-        boolean eval(int t, int f) { return t == 1; }
-    };
-
-    private static final Predicate MAJORITY_PRED = new Predicate() {
-        boolean eval(int t, int f) { return t > f; }
-    };
-
-    private static final Predicate NONE_PRED = new Predicate() {
-        boolean eval(int t, int f) { return t == 0; }
-    };
-
-    private static final Predicate[] PREDS = new Predicate[VALUES.length];
-
-    static {
-        // CheckStyle:MagicNumber OFF
-        PREDS[0] = ALL_PRED;
-        PREDS[1] = ALL_PRED;
-        PREDS[2] = ALL_PRED;
-        PREDS[3] = ANY_PRED;
-        PREDS[4] = ANY_PRED;
-        PREDS[5] = ONE_PRED;
-        PREDS[6] = MAJORITY_PRED;
-        PREDS[7] = MAJORITY_PRED;
-        PREDS[8] = NONE_PRED;
-        // CheckStyle:MagicNumber ON
-    }
-
     /**
      * Default constructor.
      */
@@ -105,10 +134,15 @@
         setValue(value);
     }
 
+    private Quantifier(Predicate impl) {
+        setValue(impl.getNames().iterator().next());
+    }
+
     /**
      * Return the possible values.
      * @return String[] of EnumeratedAttribute values.
      */
+    @Override
     public String[] getValues() {
         return VALUES;
     }
@@ -139,7 +173,7 @@
         if (index == -1) {
             throw new BuildException("Quantifier value not set.");
         }
-        return PREDS[index].eval(t, f);
+        return Predicate.get(VALUES[index]).eval(t, f);
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/RedirectorElement.java b/src/main/org/apache/tools/ant/types/RedirectorElement.java
index e72d394..b97abbc 100644
--- a/src/main/org/apache/tools/ant/types/RedirectorElement.java
+++ b/src/main/org/apache/tools/ant/types/RedirectorElement.java
@@ -84,13 +84,13 @@
     private Mapper errorMapper;
 
     /** input filter chains. */
-    private Vector<FilterChain> inputFilterChains = new Vector<FilterChain>();
+    private Vector<FilterChain> inputFilterChains = new Vector<>();
 
     /** output filter chains. */
-    private Vector<FilterChain> outputFilterChains = new Vector<FilterChain>();
+    private Vector<FilterChain> outputFilterChains = new Vector<>();
 
     /** error filter chains. */
-    private Vector<FilterChain> errorFilterChains = new Vector<FilterChain>();
+    private Vector<FilterChain> errorFilterChains = new Vector<>();
 
     /** The output encoding */
     private String outputEncoding;
@@ -528,13 +528,13 @@
                 redirector.setError(toFileArray(errorTargets));
             }
         }
-        if (inputFilterChains.size() > 0) {
+        if (!inputFilterChains.isEmpty()) {
             redirector.setInputFilterChains(inputFilterChains);
         }
-        if (outputFilterChains.size() > 0) {
+        if (!outputFilterChains.isEmpty()) {
             redirector.setOutputFilterChains(outputFilterChains);
         }
-        if (errorFilterChains.size() > 0) {
+        if (!errorFilterChains.isEmpty()) {
             redirector.setErrorFilterChains(errorFilterChains);
         }
         if (inputEncoding != null) {
@@ -572,7 +572,7 @@
             return null;
         }
         //remove any null elements
-        ArrayList<File> list = new ArrayList<File>(name.length);
+        ArrayList<File> list = new ArrayList<>(name.length);
         for (int i = 0; i < name.length; i++) {
             if (name[i] != null) {
                 list.add(getProject().resolveFile(name[i]));
@@ -588,6 +588,7 @@
      * @param p   the project to use to dereference the references.
      * @throws BuildException on error.
      */
+    @Override
     protected void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
@@ -604,7 +605,6 @@
                     stk.pop();
                 }
             }
-            @SuppressWarnings("unchecked")
             final List<? extends List<FilterChain>> filterChainLists = Arrays
                     .<List<FilterChain>> asList(inputFilterChains, outputFilterChains,
                             errorFilterChains);
diff --git a/src/main/org/apache/tools/ant/types/RegularExpression.java b/src/main/org/apache/tools/ant/types/RegularExpression.java
index 18ee3f1..e2aafc3 100644
--- a/src/main/org/apache/tools/ant/types/RegularExpression.java
+++ b/src/main/org/apache/tools/ant/types/RegularExpression.java
@@ -69,12 +69,6 @@
     private String myPattern;
     private boolean setPatternPending = false;
 
-    /**
-     * default constructor
-     */
-    public RegularExpression() {
-    }
-
     private void init(Project p) {
         if (!alreadyInit) {
             this.regexp = FACTORY.newRegexp(p);
diff --git a/src/main/org/apache/tools/ant/types/Resource.java b/src/main/org/apache/tools/ant/types/Resource.java
index 5bf9814..cbe4dd2 100644
--- a/src/main/org/apache/tools/ant/types/Resource.java
+++ b/src/main/org/apache/tools/ant/types/Resource.java
@@ -21,8 +21,9 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.math.BigInteger;
+import java.util.Collections;
 import java.util.Iterator;
-import java.util.NoSuchElementException;
+import java.util.Optional;
 
 import org.apache.tools.ant.types.resources.FileProvider;
 
@@ -140,7 +141,7 @@
      * @return the name of this resource.
      */
     public String getName() {
-        return isReference() ? ((Resource) getCheckedRef()).getName() : name;
+        return isReference() ? getCheckedRef().getName() : name;
     }
 
     /**
@@ -159,7 +160,7 @@
      */
     public boolean isExists() {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).isExists();
+            return getCheckedRef().isExists();
         }
         //default true:
         return exists == null || exists.booleanValue();
@@ -186,7 +187,7 @@
      */
     public long getLastModified() {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getLastModified();
+            return getCheckedRef().getLastModified();
         }
         if (!isExists() || lastmodified == null) {
             return UNKNOWN_DATETIME;
@@ -210,7 +211,7 @@
      */
     public boolean isDirectory() {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).isDirectory();
+            return getCheckedRef().isDirectory();
         }
         //default false:
         return directory != null && directory.booleanValue();
@@ -243,7 +244,7 @@
      */
     public long getSize() {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getSize();
+            return getCheckedRef().getSize();
         }
         return isExists()
             ? (size != null ? size.longValue() : UNKNOWN_SIZE)
@@ -254,13 +255,13 @@
      * Clone this Resource.
      * @return copy of this.
      */
-    public Object clone() {
+    @Override
+    public Resource clone() {
         try {
-            return super.clone();
+            return (Resource) super.clone();
         } catch (CloneNotSupportedException e) {
             throw new UnsupportedOperationException(
-                    "CloneNotSupportedException for a Resource caught. "
-                    + "Derived classes must support cloning.");
+                "CloneNotSupportedException for a Resource caught. Derived classes must support cloning.");
         }
     }
 
@@ -271,9 +272,10 @@
      *         is less than, equal to, or greater than the specified Resource.
      * @since Ant 1.6
      */
+    @Override
     public int compareTo(Resource other) {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).compareTo(other);
+            return getCheckedRef().compareTo(other);
         }
         return toString().compareTo(other.toString());
     }
@@ -284,6 +286,7 @@
      * @return true if the specified Object is equal to this Resource.
      * @since Ant 1.7
      */
+    @Override
     public boolean equals(Object other) {
         if (this == other) {
             return true;
@@ -300,6 +303,7 @@
      * @return hash code as int.
      * @since Ant 1.7
      */
+    @Override
     public int hashCode() {
         if (isReference()) {
             return getCheckedRef().hashCode();
@@ -319,7 +323,7 @@
      */
     public InputStream getInputStream() throws IOException {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getInputStream();
+            return getCheckedRef().getInputStream();
         }
         throw new UnsupportedOperationException();
     }
@@ -335,7 +339,7 @@
      */
     public OutputStream getOutputStream() throws IOException {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getOutputStream();
+            return getCheckedRef().getOutputStream();
         }
         throw new UnsupportedOperationException();
     }
@@ -345,24 +349,10 @@
      * @return an Iterator of Resources.
      * @since Ant 1.7
      */
+    @Override
     public Iterator<Resource> iterator() {
-        return isReference() ? ((Resource) getCheckedRef()).iterator()
-            : new Iterator<Resource>() {
-            private boolean done = false;
-            public boolean hasNext() {
-                return !done;
-            }
-            public Resource next() {
-                if (done) {
-                    throw new NoSuchElementException();
-                }
-                done = true;
-                return Resource.this;
-            }
-            public void remove() {
-                throw new UnsupportedOperationException();
-            }
-        };
+        return isReference() ? getCheckedRef().iterator()
+            : Collections.singleton(this).iterator();
     }
 
     /**
@@ -370,8 +360,9 @@
      * @return the size of this ResourceCollection.
      * @since Ant 1.7
      */
+    @Override
     public int size() {
-        return isReference() ? ((Resource) getCheckedRef()).size() : 1;
+        return isReference() ? getCheckedRef().size() : 1;
     }
 
     /**
@@ -379,8 +370,9 @@
      * @return whether this Resource is a FileProvider.
      * @since Ant 1.7
      */
+    @Override
     public boolean isFilesystemOnly() {
-        return (isReference() && ((Resource) getCheckedRef()).isFilesystemOnly())
+        return (isReference() && getCheckedRef().isFilesystemOnly())
             || this.as(FileProvider.class) != null;
     }
 
@@ -389,6 +381,7 @@
      * @return this Resource formatted as a String.
      * @since Ant 1.7
      */
+    @Override
     public String toString() {
         if (isReference()) {
             return getCheckedRef().toString();
@@ -405,7 +398,7 @@
      * @since Ant 1.7
      */
     public final String toLongString() {
-        return isReference() ? ((Resource) getCheckedRef()).toLongString()
+        return isReference() ? getCheckedRef().toLongString()
             : getDataTypeName() + " \"" + toString() + '"';
     }
 
@@ -413,6 +406,7 @@
      * Overrides the base version.
      * @param r the Reference to set.
      */
+    @Override
     public void setRefid(Reference r) {
         if (name != null
             || exists != null
@@ -443,4 +437,20 @@
     public <T> T as(Class<T> clazz) {
         return clazz.isAssignableFrom(getClass()) ? clazz.cast(this) : null;
     }
+
+    /**
+     * Return {@link #as(Class)} as an {@link Optional}.
+     * @param <T> desired type
+     * @param clazz a class
+     * @return {@link Optional} resource of a desired type
+     * @since Ant 1.10.2
+     */
+    public <T> Optional<T> asOptional(Class<T> clazz) {
+        return Optional.ofNullable(as(clazz));
+    }
+
+    @Override
+    protected Resource getCheckedRef() {
+        return (Resource) super.getCheckedRef();
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/ResourceCollection.java b/src/main/org/apache/tools/ant/types/ResourceCollection.java
index a82c8b5..85af5c9 100644
--- a/src/main/org/apache/tools/ant/types/ResourceCollection.java
+++ b/src/main/org/apache/tools/ant/types/ResourceCollection.java
@@ -1,50 +1,61 @@
 /*
- *  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.
- *
+ * 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.
  */
 package org.apache.tools.ant.types;
 
-import java.util.Iterator;
+import java.util.stream.Stream;
 
 /**
  * Interface describing a collection of Resources.
+ *
  * @since Ant 1.7
  */
 public interface ResourceCollection extends Iterable<Resource> {
 
     /**
-     * Gets the contents of this collection.
-     * @return all resources in the collection
-     */
-    Iterator<Resource> iterator();
-
-    /**
      * Learn the number of contained Resources.
+     *
      * @return number of elements as int.
      */
     int size();
 
     /**
      * Indicate whether this ResourceCollection is composed entirely of
-     * Resources accessible via local filesystem conventions. If true,
-     * all resources returned from this collection should
-     * respond with a {@link org.apache.tools.ant.types.resources.FileProvider}
-     * when asked via {@link Resource#as}.
+     * Resources accessible via local filesystem conventions. If true, all
+     * resources returned from this collection should respond with a
+     * {@link org.apache.tools.ant.types.resources.FileProvider} when asked via
+     * {@link Resource#as}.
+     *
      * @return whether this is a filesystem-only resource collection.
      */
     boolean isFilesystemOnly();
 
+    /**
+     * Return a {@link Stream} over this {@link ResourceCollection}.
+     * @return {@link Stream} of {@link Resource}
+     * @since Ant 1.10.2
+     */
+    default Stream<? extends Resource> stream() {
+        final Stream.Builder<Resource> b = Stream.builder();
+        forEach(b);
+        return b.build();
+    }
+
+    /**
+     * Learn whether this {@link ResourceCollection} is empty.
+     * @return boolean
+     */
+    default boolean isEmpty() {
+        return size() == 0;
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/TarFileSet.java b/src/main/org/apache/tools/ant/types/TarFileSet.java
index 6446e9b..49bcaa2 100644
--- a/src/main/org/apache/tools/ant/types/TarFileSet.java
+++ b/src/main/org/apache/tools/ant/types/TarFileSet.java
@@ -178,6 +178,7 @@
      * Create a new scanner.
      * @return the created scanner.
      */
+    @Override
     protected ArchiveScanner newArchiveScanner() {
         TarScanner zs = new TarScanner();
         zs.setEncoding(getEncoding());
@@ -192,6 +193,7 @@
      * @param r the <code>Reference</code> to use.
      * @throws BuildException on error
      */
+    @Override
     public void setRefid(Reference r) throws BuildException {
         if (userNameSet || userIdSet || groupNameSet || groupIdSet) {
             throw tooManyAttributes();
@@ -205,19 +207,20 @@
      * @param p the project to use
      * @return the abstract fileset instance
      */
+    @Override
     protected AbstractFileSet getRef(Project p) {
         dieOnCircularReference(p);
         Object o = getRefid().getReferencedObject(p);
         if (o instanceof TarFileSet) {
             return (AbstractFileSet) o;
-        } else if (o instanceof FileSet) {
+        }
+        if (o instanceof FileSet) {
             TarFileSet zfs = new TarFileSet((FileSet) o);
             configureFileSet(zfs);
             return zfs;
-        } else {
-            String msg = getRefid().getRefId() + " doesn\'t denote a tarfileset or a fileset";
-            throw new BuildException(msg);
         }
+        String msg = getRefid().getRefId() + " doesn\'t denote a tarfileset or a fileset";
+        throw new BuildException(msg);
     }
 
     /**
@@ -226,6 +229,7 @@
      * specific attributes.
      * @param zfs the archive fileset to configure.
      */
+    @Override
     protected void configureFileSet(ArchiveFileSet zfs) {
         super.configureFileSet(zfs);
         if (zfs instanceof TarFileSet) {
@@ -242,12 +246,12 @@
      * as this one.
      * @return the cloned tarFileSet
      */
-    public Object clone() {
+    @Override
+    public TarFileSet clone() {
         if (isReference()) {
             return ((TarFileSet) getRef(getProject())).clone();
-        } else {
-            return super.clone();
         }
+        return (TarFileSet) super.clone();
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/types/TarScanner.java b/src/main/org/apache/tools/ant/types/TarScanner.java
index a3c7f6d..f5b3a39 100644
--- a/src/main/org/apache/tools/ant/types/TarScanner.java
+++ b/src/main/org/apache/tools/ant/types/TarScanner.java
@@ -23,7 +23,6 @@
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.types.resources.TarResource;
-import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.tar.TarEntry;
 import org.apache.tools.tar.TarInputStream;
 
@@ -53,35 +52,30 @@
             Map<String, Resource> fileEntries, Map<String, Resource> matchFileEntries,
             Map<String, Resource> dirEntries, Map<String, Resource> matchDirEntries) {
 
-        TarEntry entry = null;
-        TarInputStream ti = null;
-
-        try {
+        try (TarInputStream ti = new TarInputStream(src.getInputStream(), encoding)) {
             try {
-                ti = new TarInputStream(src.getInputStream(), encoding);
-            } catch (IOException ex) {
-                throw new BuildException("problem opening " + srcFile, ex);
-            }
-            while ((entry = ti.getNextEntry()) != null) {
-                Resource r = new TarResource(src, entry);
-                String name = entry.getName();
-                if (entry.isDirectory()) {
-                    name = trimSeparator(name);
-                    dirEntries.put(name, r);
-                    if (match(name)) {
-                        matchDirEntries.put(name, r);
-                    }
-                } else {
-                    fileEntries.put(name, r);
-                    if (match(name)) {
-                        matchFileEntries.put(name, r);
+                TarEntry entry = null;
+                while ((entry = ti.getNextEntry()) != null) {
+                    Resource r = new TarResource(src, entry);
+                    String name = entry.getName();
+                    if (entry.isDirectory()) {
+                        name = trimSeparator(name);
+                        dirEntries.put(name, r);
+                        if (match(name)) {
+                            matchDirEntries.put(name, r);
+                        }
+                    } else {
+                        fileEntries.put(name, r);
+                        if (match(name)) {
+                            matchFileEntries.put(name, r);
+                        }
                     }
                 }
+            } catch (IOException ex) {
+                throw new BuildException("problem reading " + srcFile, ex);
             }
         } catch (IOException ex) {
-            throw new BuildException("problem reading " + srcFile, ex);
-        } finally {
-            FileUtils.close(ti);
+            throw new BuildException("problem opening " + srcFile, ex);
         }
     }
 }
diff --git a/src/main/org/apache/tools/ant/types/XMLCatalog.java b/src/main/org/apache/tools/ant/types/XMLCatalog.java
index 7001359..09dea53 100644
--- a/src/main/org/apache/tools/ant/types/XMLCatalog.java
+++ b/src/main/org/apache/tools/ant/types/XMLCatalog.java
@@ -19,13 +19,13 @@
 package org.apache.tools.ant.types;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Method;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
+import java.nio.file.Files;
 import java.util.Stack;
 import java.util.Vector;
 
@@ -353,6 +353,7 @@
      * @param r the reference to which this catalog instance is associated
      * @exception BuildException if this instance already has been configured.
      */
+    @Override
     public void setRefid(Reference r) throws BuildException {
         if (!elements.isEmpty()) {
             throw tooManyAttributes();
@@ -369,6 +370,7 @@
      * @return the resolved entity.
      * @see org.xml.sax.EntityResolver#resolveEntity
      */
+    @Override
     public InputSource resolveEntity(String publicId, String systemId)
         throws SAXException, IOException {
 
@@ -400,6 +402,7 @@
      * @throws TransformerException if an error occurs.
      * @see javax.xml.transform.URIResolver#resolve
      */
+    @Override
     public Source resolve(String href, String base)
         throws TransformerException {
 
@@ -425,7 +428,7 @@
             // setEntityResolver (see setEntityResolver javadoc comment)
             //
             source = new SAXSource();
-            URL baseURL = null;
+            URL baseURL;
             try {
                 if (base == null) {
                     baseURL = FILE_UTILS.getFileURL(getProject().getBaseDir());
@@ -445,6 +448,7 @@
         return source;
     }
 
+    @Override
     protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
@@ -492,7 +496,7 @@
 
         if (catalogResolver == null) {
 
-            AntClassLoader loader = null;
+            AntClassLoader loader;
             // Memory-Leak in line below
             loader = getProject().createClassLoader(Path.systemClasspath);
 
@@ -587,12 +591,9 @@
      *         of the Resource or null if no such information is available.
      */
     private ResourceLocation findMatchingEntry(String publicId) {
-        for (ResourceLocation element : getElements()) {
-            if (element.getPublicId().equals(publicId)) {
-                return element;
-            }
-        }
-        return null;
+        return getElements().stream()
+            .filter(e -> e.getPublicId().equals(publicId)).findFirst()
+            .orElse(null);
     }
 
     /**
@@ -625,7 +626,7 @@
         String uri = matchingEntry.getLocation();
         // the following line seems to be necessary on Windows under JDK 1.2
         uri = uri.replace(File.separatorChar, '/');
-        URL baseURL = null;
+        URL baseURL;
 
         //
         // The ResourceLocation may specify a relative path for its
@@ -642,7 +643,6 @@
             }
         }
 
-        InputSource source = null;
         URL url = null;
         try {
             url = new URL(baseURL, uri);
@@ -667,14 +667,15 @@
             }
         }
 
-        if (url != null && url.getProtocol().equals("file")) {
+        InputSource source = null;
+        if (url != null && "file".equals(url.getProtocol())) {
             String fileName = FILE_UTILS.fromURI(url.toString());
             if (fileName != null) {
                 log("fileName " + fileName, Project.MSG_DEBUG);
                 File resFile = new File(fileName);
                 if (resFile.exists() && resFile.canRead()) {
                     try {
-                        source = new InputSource(new FileInputStream(resFile));
+                        source = new InputSource(Files.newInputStream(resFile.toPath()));
                         String sysid = JAXPUtils.getSystemId(resFile);
                         source.setSystemId(sysid);
                         log("catalog entry matched a readable file: '"
@@ -698,14 +699,13 @@
 
         InputSource source = null;
 
-        AntClassLoader loader = null;
         Path cp = classpath;
         if (cp != null) {
             cp = classpath.concatSystemClasspath("ignore");
         } else {
             cp = (new Path(getProject())).concatSystemClasspath("last");
         }
-        loader = getProject().createClassLoader(cp);
+        AntClassLoader loader = getProject().createClassLoader(cp);
 
         //
         // for classpath lookup we ignore the base directory
@@ -734,7 +734,7 @@
     private InputSource urlLookup(ResourceLocation matchingEntry) {
 
         String uri = matchingEntry.getLocation();
-        URL baseURL = null;
+        URL baseURL;
 
         //
         // The ResourceLocation may specify a relative url for its
@@ -751,15 +751,15 @@
             }
         }
 
-        InputSource source = null;
-        URL url = null;
+        URL url;
 
         try {
             url = new URL(baseURL, uri);
         } catch (MalformedURLException ex) {
-            // ignore
+            url = null;
         }
 
+        InputSource source = null;
         if (url != null) {
             try {
                 InputStream is = null;
@@ -789,10 +789,6 @@
      * the ExternalResolver strategy.
      */
     private interface CatalogResolver extends URIResolver, EntityResolver {
-
-        InputSource resolveEntity(String publicId, String systemId);
-
-        Source resolve(String href, String base) throws TransformerException;
     }
 
     /**
@@ -809,6 +805,7 @@
                 Project.MSG_VERBOSE);
         }
 
+        @Override
         public InputSource resolveEntity(String publicId,
                                          String systemId) {
             InputSource result = null;
@@ -834,6 +831,7 @@
             return result;
         }
 
+        @Override
         public Source resolve(String href, String base)
             throws TransformerException {
 
@@ -945,14 +943,15 @@
                 Project.MSG_VERBOSE);
         }
 
+        @Override
         public InputSource resolveEntity(String publicId,
                                          String systemId) {
-            InputSource result = null;
 
             processExternalCatalogs();
 
             ResourceLocation matchingEntry = findMatchingEntry(publicId);
 
+            InputSource result;
             if (matchingEntry != null) {
 
                 log("Matching catalog entry found for publicId: '"
@@ -996,11 +995,12 @@
             return result;
         }
 
+        @Override
         public Source resolve(String href, String base)
             throws TransformerException {
 
-            SAXSource result = null;
-            InputSource source = null;
+            SAXSource result;
+            InputSource source;
 
             processExternalCatalogs();
 
diff --git a/src/main/org/apache/tools/ant/types/ZipFileSet.java b/src/main/org/apache/tools/ant/types/ZipFileSet.java
index 24f0ccd..84362a1 100644
--- a/src/main/org/apache/tools/ant/types/ZipFileSet.java
+++ b/src/main/org/apache/tools/ant/types/ZipFileSet.java
@@ -58,6 +58,7 @@
      * Return a new archive scanner based on this one.
      * @return a new ZipScanner with the same encoding as this one.
      */
+    @Override
     protected ArchiveScanner newArchiveScanner() {
         ZipScanner zs = new ZipScanner();
         zs.setEncoding(getEncoding());
@@ -70,19 +71,20 @@
      * @param p the project to use
      * @return the abstract fileset instance
      */
+    @Override
     protected AbstractFileSet getRef(Project p) {
         dieOnCircularReference(p);
         Object o = getRefid().getReferencedObject(p);
         if (o instanceof ZipFileSet) {
             return (AbstractFileSet) o;
-        } else if (o instanceof FileSet) {
+        }
+        if (o instanceof FileSet) {
             ZipFileSet zfs = new ZipFileSet((FileSet) o);
             configureFileSet(zfs);
             return zfs;
-        } else {
-            String msg = getRefid().getRefId() + " doesn\'t denote a zipfileset or a fileset";
-            throw new BuildException(msg);
         }
+        String msg = getRefid().getRefId() + " doesn\'t denote a zipfileset or a fileset";
+        throw new BuildException(msg);
     }
 
     /**
@@ -90,28 +92,12 @@
      * as this one.
      * @return the cloned zipFileSet
      */
-    public Object clone() {
+    @Override
+    public ZipFileSet clone() {
         if (isReference()) {
             return ((ZipFileSet) getRef(getProject())).clone();
-        } else {
-            return super.clone();
         }
-    }
-
-    /**
-     * A check attributes for zipFileSet.
-     * If there is a reference, and
-     * it is a ZipFileSet, the zip fileset attributes
-     * cannot be used.
-     */
-    private void checkZipFileSetAttributesAllowed() {
-        if (getProject() == null
-            || (isReference()
-                && (getRefid().getReferencedObject(
-                        getProject())
-                    instanceof ZipFileSet))) {
-            checkAttributesAllowed();
-        }
+        return (ZipFileSet) super.clone();
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/ZipScanner.java b/src/main/org/apache/tools/ant/types/ZipScanner.java
index 0539222..a3df040 100644
--- a/src/main/org/apache/tools/ant/types/ZipScanner.java
+++ b/src/main/org/apache/tools/ant/types/ZipScanner.java
@@ -52,31 +52,20 @@
      * resources found inside the archive that matched all include
      * patterns and didn't match any exclude patterns.
      */
+    @Override
     protected void fillMapsFromArchive(Resource src, String encoding,
             Map<String, Resource> fileEntries, Map<String, Resource> matchFileEntries,
             Map<String, Resource> dirEntries, Map<String, Resource> matchDirEntries) {
-        ZipEntry entry = null;
-        ZipFile zf = null;
 
-        File srcFile = null;
-        FileProvider fp = src.as(FileProvider.class);
-        if (fp != null) {
-            srcFile = fp.getFile();
-        } else {
-            throw new BuildException("Only file provider resources are supported");
-        }
+        File srcFile = src.asOptional(FileProvider.class)
+            .map(FileProvider::getFile).orElseThrow(() -> new BuildException(
+                "Only file provider resources are supported"));
 
-        try {
-            try {
-                zf = new ZipFile(srcFile, encoding);
-            } catch (ZipException ex) {
-                throw new BuildException("Problem reading " + srcFile, ex);
-            } catch (IOException ex) {
-                throw new BuildException("Problem opening " + srcFile, ex);
-            }
+        try (ZipFile zf = new ZipFile(srcFile, encoding)) {
+
             Enumeration<ZipEntry> e = zf.getEntries();
             while (e.hasMoreElements()) {
-                entry = e.nextElement();
+                ZipEntry entry = e.nextElement();
                 Resource r = new ZipResource(srcFile, encoding, entry);
                 String name = entry.getName();
                 if (entry.isDirectory()) {
@@ -92,8 +81,10 @@
                     }
                 }
             }
-        } finally {
-            ZipFile.closeQuietly(zf);
+        } catch (ZipException ex) {
+            throw new BuildException("Problem reading " + srcFile, ex);
+        } catch (IOException ex) {
+            throw new BuildException("Problem opening " + srcFile, ex);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/org/apache/tools/ant/types/defaults.properties b/src/main/org/apache/tools/ant/types/defaults.properties
index 29771db..160c7a7 100644
--- a/src/main/org/apache/tools/ant/types/defaults.properties
+++ b/src/main/org/apache/tools/ant/types/defaults.properties
@@ -94,6 +94,7 @@
 javaresource=org.apache.tools.ant.types.resources.JavaResource
 multirootfileset=org.apache.tools.ant.types.resources.MultiRootFileSet
 javaconstant=org.apache.tools.ant.types.resources.JavaConstantResource
+xzresource=org.apache.tools.ant.types.optional.xz.XzResource
 
 #tokenizer implementations
 linetokenizer=org.apache.tools.ant.util.LineTokenizer
diff --git a/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java b/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java
index ce8f39c..052a037 100644
--- a/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java
+++ b/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java
@@ -47,6 +47,7 @@
      * Empty implementation.
      * @param ignore ignored.
      */
+    @Override
     public void setFrom(final String ignore) {
     }
 
@@ -54,10 +55,12 @@
      * Empty implementation.
      * @param ignore ignored.
      */
+    @Override
     public void setTo(final String ignore) {
     }
 
     /** {@inheritDoc}. */
+    @Override
     public String[] mapFileName(final String sourceFileName) {
         if (dirs <= 0) {
             throw new BuildException("dirs must be set to a positive number");
diff --git a/src/main/org/apache/tools/ant/types/mappers/FilterMapper.java b/src/main/org/apache/tools/ant/types/mappers/FilterMapper.java
index 501da50..b4c07e9 100644
--- a/src/main/org/apache/tools/ant/types/mappers/FilterMapper.java
+++ b/src/main/org/apache/tools/ant/types/mappers/FilterMapper.java
@@ -41,6 +41,7 @@
      * @param from a string
      * @throws BuildException always
      */
+    @Override
     public void setFrom(String from) {
         throw new UnsupportedAttributeException(
             "filtermapper doesn't support the \"from\" attribute.", "from");
@@ -51,6 +52,7 @@
      * @param to a string
      * @throws BuildException always
      */
+    @Override
     public void setTo(String to) {
         throw new UnsupportedAttributeException(
             "filtermapper doesn't support the \"to\" attribute.", "to");
@@ -62,6 +64,7 @@
      * @return  a one-element array of converted filenames, or null if
      *          the filterchain returns an empty string.
      */
+    @Override
     public String[] mapFileName(String sourceFileName) {
         try {
             Reader stringReader = new StringReader(sourceFileName);
@@ -69,15 +72,14 @@
             helper.setBufferSize(BUFFER_SIZE);
             helper.setPrimaryReader(stringReader);
             helper.setProject(getProject());
-            Vector<FilterChain> filterChains = new Vector<FilterChain>();
+            Vector<FilterChain> filterChains = new Vector<>();
             filterChains.add(this);
             helper.setFilterChains(filterChains);
             String result = FileUtils.safeReadFully(helper.getAssembledReader());
-            if (result.length() == 0) {
+            if (result.isEmpty()) {
                 return null;
-            } else {
-                return new String[] {result};
             }
+            return new String[] {result};
         } catch (BuildException ex) {
             throw ex;
         } catch (Exception ex) {
diff --git a/src/main/org/apache/tools/ant/types/optional/AbstractScriptComponent.java b/src/main/org/apache/tools/ant/types/optional/AbstractScriptComponent.java
index 2028075..84a9e8b 100644
--- a/src/main/org/apache/tools/ant/types/optional/AbstractScriptComponent.java
+++ b/src/main/org/apache/tools/ant/types/optional/AbstractScriptComponent.java
@@ -45,6 +45,7 @@
      * Set the project.
      * @param project the owner of this component.
      */
+    @Override
     public void setProject(Project project) {
         super.setProject(project);
         helper.setProjectComponent(this);
@@ -155,4 +156,14 @@
     public void setSetBeans(boolean setBeans) {
         helper.setSetBeans(setBeans);
     }
+
+    /**
+     * Set the encoding of the script from an external file; optional.
+     *
+     * @param encoding the encoding of the file containing the script source.
+     * @since Ant 1.10.2
+     */
+    public void setEncoding(String encoding) {
+        helper.setEncoding(encoding);
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/optional/ScriptCondition.java b/src/main/org/apache/tools/ant/types/optional/ScriptCondition.java
index fac02bf..76b2337 100644
--- a/src/main/org/apache/tools/ant/types/optional/ScriptCondition.java
+++ b/src/main/org/apache/tools/ant/types/optional/ScriptCondition.java
@@ -41,6 +41,7 @@
      * @throws org.apache.tools.ant.BuildException
      *          if an error occurs
      */
+    @Override
     public boolean eval() throws BuildException {
         initScriptRunner();
         executeScript("ant_condition");
diff --git a/src/main/org/apache/tools/ant/types/optional/ScriptFilter.java b/src/main/org/apache/tools/ant/types/optional/ScriptFilter.java
index 67d3cce..c88c087 100644
--- a/src/main/org/apache/tools/ant/types/optional/ScriptFilter.java
+++ b/src/main/org/apache/tools/ant/types/optional/ScriptFilter.java
@@ -53,6 +53,7 @@
      * Set the project.
      * @param project the owner of this component.
      */
+    @Override
     public void setProject(Project project) {
         super.setProject(project);
         helper.setProjectComponent(this);
@@ -105,6 +106,7 @@
      * @param token the token to be filtered
      * @return the filtered token
      */
+    @Override
     public String filter(String token) {
         init();
         setToken(token);
@@ -180,4 +182,14 @@
     public void setSetBeans(boolean setBeans) {
         helper.setSetBeans(setBeans);
     }
+
+    /**
+     * Set the encoding of the script from an external file; optional.
+     *
+     * @param encoding the encoding of the file containing the script source.
+     * @since Ant 1.10.2
+     */
+    public void setEncoding(String encoding) {
+        helper.setEncoding(encoding);
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/optional/ScriptMapper.java b/src/main/org/apache/tools/ant/types/optional/ScriptMapper.java
index 36347a7..5fd3edf 100644
--- a/src/main/org/apache/tools/ant/types/optional/ScriptMapper.java
+++ b/src/main/org/apache/tools/ant/types/optional/ScriptMapper.java
@@ -35,8 +35,8 @@
      *
      * @param from a string.
      */
+    @Override
     public void setFrom(String from) {
-
     }
 
     /**
@@ -44,15 +44,15 @@
      *
      * @param to a string.
      */
+    @Override
     public void setTo(String to) {
-
     }
 
     /**
      * Reset the list of files
      */
     public void clear() {
-        files = new ArrayList<String>(1);
+        files = new ArrayList<>(1);
     }
 
     /**
@@ -77,15 +77,15 @@
      *         null if it does not.
      */
 
+    @Override
     public String[] mapFileName(String sourceFileName) {
         initScriptRunner();
         getRunner().addBean("source", sourceFileName);
         clear();
         executeScript("ant_mapper");
-        if (files.size() == 0) {
+        if (files.isEmpty()) {
             return null;
-        } else {
-            return files.toArray(new String[files.size()]);
         }
+        return files.toArray(new String[files.size()]);
     }
 }
diff --git a/src/main/org/apache/tools/ant/types/optional/ScriptSelector.java b/src/main/org/apache/tools/ant/types/optional/ScriptSelector.java
index c07ed13..da9f062 100644
--- a/src/main/org/apache/tools/ant/types/optional/ScriptSelector.java
+++ b/src/main/org/apache/tools/ant/types/optional/ScriptSelector.java
@@ -59,6 +59,7 @@
      * Set the project.
      * @param project the owner of this component.
      */
+    @Override
     public void setProject(Project project) {
         super.setProject(project);
         helper.setProjectComponent(this);
@@ -166,6 +167,7 @@
      *
      * @return whether the file should be selected or not
      */
+    @Override
     public boolean isSelected(File basedir, String filename, File file) {
         init();
         setSelected(true);
@@ -220,4 +222,13 @@
         this.selected = selected;
     }
 
+    /**
+     * Set the encoding of the script from an external file; optional.
+     *
+     * @param encoding the encoding of the file containing the script source.
+     * @since Ant 1.10.2
+     */
+    public void setEncoding(String encoding) {
+        helper.setEncoding(encoding);
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/optional/depend/ClassfileSet.java b/src/main/org/apache/tools/ant/types/optional/depend/ClassfileSet.java
index f2fe69b..7f9ff2d 100644
--- a/src/main/org/apache/tools/ant/types/optional/depend/ClassfileSet.java
+++ b/src/main/org/apache/tools/ant/types/optional/depend/ClassfileSet.java
@@ -41,12 +41,12 @@
      * classes which must be included in the fileset and which are the
      * starting point for the dependency search.
      */
-    private List<String> rootClasses = new ArrayList<String>();
+    private List<String> rootClasses = new ArrayList<>();
 
     /**
      * The list of filesets which contain root classes.
      */
-    private List<FileSet> rootFileSets = new ArrayList<FileSet>();
+    private List<FileSet> rootFileSets = new ArrayList<>();
 
     /**
      * Inner class used to contain info about root classes.
@@ -81,6 +81,16 @@
     }
 
     /**
+     * Create a ClassfileSet from another ClassfileSet.
+     *
+     * @param s the other classfileset.
+     */
+    protected ClassfileSet(ClassfileSet s) {
+        super(s);
+        rootClasses.addAll(s.rootClasses);
+    }
+
+    /**
      * Add a fileset to which contains a collection of root classes used to
      * drive the search from classes.
      *
@@ -93,16 +103,6 @@
     }
 
     /**
-     * Create a ClassfileSet from another ClassfileSet.
-     *
-     * @param s the other classfileset.
-     */
-    protected ClassfileSet(ClassfileSet s) {
-        super(s);
-        rootClasses.addAll(s.rootClasses);
-    }
-
-    /**
      * Set the root class attribute.
      *
      * @param rootClass the name of the root class.
@@ -118,6 +118,7 @@
      *
      * @return a dependency scanner.
      */
+    @Override
     public DirectoryScanner getDirectoryScanner(Project p) {
         if (isReference()) {
             return getRef(p).getDirectoryScanner(p);
@@ -125,7 +126,7 @@
         dieOnCircularReference(p);
         DirectoryScanner parentScanner = super.getDirectoryScanner(p);
         DependScanner scanner = new DependScanner(parentScanner);
-        final Vector<String> allRootClasses = new Vector<String>(rootClasses);
+        final Vector<String> allRootClasses = new Vector<>(rootClasses);
         for (FileSet additionalRootSet : rootFileSets) {
             DirectoryScanner additionalScanner
                 = additionalRootSet.getDirectoryScanner(p);
@@ -160,11 +161,13 @@
      *
      * @return a clone of the class file set.
      */
-    public Object clone() {
+    @Override
+    public ClassfileSet clone() {
         return new ClassfileSet(isReference()
             ? (ClassfileSet) (getRef(getProject())) : this);
     }
 
+    @Override
     protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p) {
         if (isChecked()) {
             return;
diff --git a/src/main/org/apache/tools/ant/types/optional/depend/DependScanner.java b/src/main/org/apache/tools/ant/types/optional/depend/DependScanner.java
index 27a1fdd..4f2e1eb 100644
--- a/src/main/org/apache/tools/ant/types/optional/depend/DependScanner.java
+++ b/src/main/org/apache/tools/ant/types/optional/depend/DependScanner.java
@@ -19,8 +19,10 @@
 
 import java.io.File;
 import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.Set;
 import java.util.Vector;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.DirectoryScanner;
@@ -48,7 +50,7 @@
      */
     private Vector<String> included;
 
-    private Vector<File> additionalBaseDirs = new Vector<File>();
+    private Vector<File> additionalBaseDirs = new Vector<>();
 
     /**
      * The parent scanner which gives the basic set of files. Only files which
@@ -82,15 +84,13 @@
      *
      * @return the names of the files.
      */
+    @Override
     public String[] getIncludedFiles() {
-        String[] files = new String[getIncludedFilesCount()];
-        for (int i = 0; i < files.length; i++) {
-            files[i] = (String) included.elementAt(i);
-        }
-        return files;
+        return included.toArray(new String[getIncludedFilesCount()]);
     }
 
     /** {@inheritDoc}. */
+    @Override
     public synchronized int getIncludedFilesCount() {
         if (included == null) {
             throw new IllegalStateException();
@@ -103,12 +103,14 @@
      *
      * @exception IllegalStateException when basedir was set incorrectly.
      */
+    @Override
     public synchronized void scan() throws IllegalStateException {
-        included = new Vector<String>();
+        included = new Vector<>();
         String analyzerClassName = DEFAULT_ANALYZER_CLASS;
-        DependencyAnalyzer analyzer = null;
+        DependencyAnalyzer analyzer;
         try {
-            Class<? extends DependencyAnalyzer> analyzerClass = Class.forName(analyzerClassName)
+            Class<? extends DependencyAnalyzer> analyzerClass =
+                Class.forName(analyzerClassName)
                     .asSubclass(DependencyAnalyzer.class);
             analyzer = analyzerClass.newInstance();
         } catch (Exception e) {
@@ -116,28 +118,22 @@
                                      + analyzerClassName, e);
         }
         analyzer.addClassPath(new Path(null, basedir.getPath()));
-        for (Enumeration<File> e = additionalBaseDirs.elements(); e.hasMoreElements();) {
-            File additionalBaseDir = e.nextElement();
-            analyzer.addClassPath(new Path(null, additionalBaseDir.getPath()));
-        }
+        additionalBaseDirs.stream().map(File::getPath)
+            .map(p -> new Path(null, p)).forEach(analyzer::addClassPath);
 
-        for (Enumeration<String> e = rootClasses.elements(); e.hasMoreElements();) {
-            String rootClass = e.nextElement();
-            analyzer.addRootClass(rootClass);
-        }
+        rootClasses.forEach(analyzer::addRootClass);
+
+        Set<String> parentSet = Stream.of(parentScanner.getIncludedFiles())
+            .collect(Collectors.toSet());
+
         Enumeration<String> e = analyzer.getClassDependencies();
 
-        String[] parentFiles = parentScanner.getIncludedFiles();
-        Hashtable<String, String> parentSet = new Hashtable<String, String>();
-        for (int i = 0; i < parentFiles.length; ++i) {
-            parentSet.put(parentFiles[i], parentFiles[i]);
-        }
         while (e.hasMoreElements()) {
-            String classname = (String) e.nextElement();
-            String filename = classname.replace('.', File.separatorChar);
-            filename = filename + ".class";
+            String classname = e.nextElement();
+            String filename =
+                classname.replace('.', File.separatorChar) + ".class";
             File depFile = new File(basedir, filename);
-            if (depFile.exists() && parentSet.containsKey(filename)) {
+            if (depFile.exists() && parentSet.contains(filename)) {
                 // This is included
                 included.addElement(filename);
             }
@@ -147,6 +143,7 @@
     /**
      * @see DirectoryScanner#addDefaultExcludes
      */
+    @Override
     public void addDefaultExcludes() {
     }
 
@@ -154,6 +151,7 @@
      * @see DirectoryScanner#getExcludedDirectories
      * {@inheritDoc}.
      */
+    @Override
     public String[] getExcludedDirectories() {
         return null;
     }
@@ -162,6 +160,7 @@
      * @see DirectoryScanner#getExcludedFiles
      * {@inheritDoc}.
      */
+    @Override
     public String[] getExcludedFiles() {
         return null;
     }
@@ -170,6 +169,7 @@
      * @see DirectoryScanner#getIncludedDirectories
      * {@inheritDoc}.
      */
+    @Override
     public String[] getIncludedDirectories() {
         return new String[0];
     }
@@ -178,6 +178,7 @@
      * @see DirectoryScanner#getIncludedDirsCount
      * {@inheritDoc}.
      */
+    @Override
     public int getIncludedDirsCount() {
         return 0;
     }
@@ -186,6 +187,7 @@
      * @see DirectoryScanner#getNotIncludedDirectories
      * {@inheritDoc}.
      */
+    @Override
     public String[] getNotIncludedDirectories() {
         return null;
     }
@@ -194,7 +196,7 @@
      * @see DirectoryScanner#getNotIncludedFiles
      * {@inheritDoc}.
      */
-    /** {@inheritDoc}. */
+    @Override
     public String[] getNotIncludedFiles() {
         return null;
     }
@@ -203,7 +205,7 @@
      * @see DirectoryScanner#setExcludes
      * {@inheritDoc}.
      */
-    /** {@inheritDoc}. */
+    @Override
     public void setExcludes(String[] excludes) {
     }
 
@@ -211,7 +213,7 @@
      * @see DirectoryScanner#setIncludes
      * {@inheritDoc}.
      */
-    /** {@inheritDoc}. */
+    @Override
     public void setIncludes(String[] includes) {
     }
 
@@ -219,7 +221,7 @@
      * @see DirectoryScanner#setCaseSensitive
      * {@inheritDoc}.
      */
-    /** {@inheritDoc}. */
+    @Override
     public void setCaseSensitive(boolean isCaseSensitive) {
     }
 
diff --git a/src/main/org/apache/tools/ant/types/optional/image/Arc.java b/src/main/org/apache/tools/ant/types/optional/image/Arc.java
index 3d8b29b..a1d4709 100644
--- a/src/main/org/apache/tools/ant/types/optional/image/Arc.java
+++ b/src/main/org/apache/tools/ant/types/optional/image/Arc.java
@@ -74,23 +74,24 @@
      * @todo refactor using an EnumeratedAttribute
      */
     public void setType(String strType) {
-        if (strType.equalsIgnoreCase("open")) {
+        if ("open".equalsIgnoreCase(strType)) {
             type = Arc2D.OPEN;
-        } else if (strType.equalsIgnoreCase("pie")) {
+        } else if ("pie".equalsIgnoreCase(strType)) {
             type = Arc2D.PIE;
-        } else if (strType.equalsIgnoreCase("chord")) {
+        } else if ("chord".equalsIgnoreCase(strType)) {
             type = Arc2D.CHORD;
         }
     }
 
     /** {@inheritDoc}. */
+    @Override
     public PlanarImage executeDrawOperation() {
         BufferedImage bi = new BufferedImage(width + (stroke_width * 2),
             height + (stroke_width * 2), BufferedImage.TYPE_4BYTE_ABGR_PRE);
 
-        Graphics2D graphics = (Graphics2D) bi.getGraphics();
+        Graphics2D graphics = bi.createGraphics();
 
-        if (!stroke.equals("transparent")) {
+        if (!"transparent".equalsIgnoreCase(stroke)) {
             BasicStroke bStroke = new BasicStroke(stroke_width);
             graphics.setColor(ColorMapper.getColorByName(stroke));
             graphics.setStroke(bStroke);
@@ -98,24 +99,21 @@
                 height, start, stop, type));
         }
 
-        if (!fill.equals("transparent")) {
+        if (!"transparent".equalsIgnoreCase(fill)) {
             graphics.setColor(ColorMapper.getColorByName(fill));
             graphics.fill(new Arc2D.Double(stroke_width, stroke_width,
                 width, height, start, stop, type));
         }
 
-
-        final int size = instructions.size();
-        for (int i = 0; i < size; i++) {
-            ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+        for (ImageOperation instr : instructions) {
             if (instr instanceof DrawOperation) {
                 PlanarImage img = ((DrawOperation) instr).executeDrawOperation();
                 graphics.drawImage(img.getAsBufferedImage(), null, 0, 0);
             } else if (instr instanceof TransformOperation) {
-                graphics = (Graphics2D) bi.getGraphics();
                 PlanarImage image = ((TransformOperation) instr)
                     .executeTransformOperation(PlanarImage.wrapRenderedImage(bi));
                 bi = image.getAsBufferedImage();
+                graphics = bi.createGraphics();
             }
         }
         return PlanarImage.wrapRenderedImage(bi);
diff --git a/src/main/org/apache/tools/ant/types/optional/image/ColorMapper.java b/src/main/org/apache/tools/ant/types/optional/image/ColorMapper.java
index 88e2871..14470fd 100644
--- a/src/main/org/apache/tools/ant/types/optional/image/ColorMapper.java
+++ b/src/main/org/apache/tools/ant/types/optional/image/ColorMapper.java
@@ -24,9 +24,6 @@
  * @see org.apache.tools.ant.taskdefs.optional.image.Image
  */
 public final class ColorMapper {
-    /** private constructor for Utility class */
-    private ColorMapper() {
-    }
 
     /** black string */
     public static final String COLOR_BLACK = "black";
@@ -69,34 +66,42 @@
      * @todo refactor to use an EnumeratedAttribute (maybe?)
      */
     public static Color getColorByName(String colorName) {
-        if (colorName.equalsIgnoreCase(COLOR_BLACK)) {
-            return Color.black;
-        } else if (colorName.equalsIgnoreCase(COLOR_BLUE)) {
+        switch (colorName.toLowerCase()) {
+        case COLOR_BLUE:
             return Color.blue;
-        } else if (colorName.equalsIgnoreCase(COLOR_CYAN)) {
+        case COLOR_CYAN:
             return Color.cyan;
-        } else if (colorName.equalsIgnoreCase(COLOR_DARKGRAY) || colorName.equalsIgnoreCase(COLOR_DARKGREY)) {
+        case COLOR_DARKGRAY:
+        case COLOR_DARKGREY:
             return Color.darkGray;
-        } else if (colorName.equalsIgnoreCase(COLOR_GRAY) || colorName.equalsIgnoreCase(COLOR_GREY)) {
+        case COLOR_GRAY:
+        case COLOR_GREY:
             return Color.gray;
-        } else if (colorName.equalsIgnoreCase(COLOR_LIGHTGRAY) || colorName.equalsIgnoreCase(COLOR_LIGHTGREY)) {
+        case COLOR_LIGHTGRAY:
+        case COLOR_LIGHTGREY:
             return Color.lightGray;
-        } else if (colorName.equalsIgnoreCase(COLOR_GREEN)) {
+        case COLOR_GREEN:
             return Color.green;
-        } else if (colorName.equalsIgnoreCase(COLOR_MAGENTA)) {
+        case COLOR_MAGENTA:
             return Color.magenta;
-        } else if (colorName.equalsIgnoreCase(COLOR_ORANGE)) {
+        case COLOR_ORANGE:
             return Color.orange;
-        } else if (colorName.equalsIgnoreCase(COLOR_PINK)) {
+        case COLOR_PINK:
             return Color.pink;
-        } else if (colorName.equalsIgnoreCase(COLOR_RED)) {
+        case COLOR_RED:
             return Color.red;
-        } else if (colorName.equalsIgnoreCase(COLOR_WHITE)) {
+        case COLOR_WHITE:
             return Color.white;
-        } else if (colorName.equalsIgnoreCase(COLOR_YELLOW)) {
+        case COLOR_YELLOW:
             return Color.yellow;
+        case COLOR_BLACK:
+        default:
+            return Color.black;
         }
-        return Color.black;
+    }
+
+    /** private constructor for Utility class */
+    private ColorMapper() {
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/optional/image/Draw.java b/src/main/org/apache/tools/ant/types/optional/image/Draw.java
index 2f097d5..b2cfab9 100644
--- a/src/main/org/apache/tools/ant/types/optional/image/Draw.java
+++ b/src/main/org/apache/tools/ant/types/optional/image/Draw.java
@@ -49,11 +49,13 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void addRectangle(Rectangle rect) {
         instructions.add(rect);
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void addText(Text text) {
         instructions.add(text);
     }
@@ -75,13 +77,12 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public PlanarImage executeTransformOperation(PlanarImage image) {
         BufferedImage bi = image.getAsBufferedImage();
-        Graphics2D graphics = (Graphics2D) bi.getGraphics();
+        Graphics2D graphics = bi.createGraphics();
 
-        final int size = instructions.size();
-        for (int i = 0; i < size; i++) {
-            ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+        for (ImageOperation instr : instructions) {
             if (instr instanceof DrawOperation) {
                 PlanarImage op = ((DrawOperation) instr).executeDrawOperation();
                 log("\tDrawing to x=" + xloc + " y=" + yloc);
@@ -92,11 +93,8 @@
                 BufferedImage child = op.getAsBufferedImage();
                 log("\tDrawing to x=" + xloc + " y=" + yloc);
                 graphics.drawImage(child, null, xloc, yloc);
-                PlanarImage.wrapRenderedImage(bi);
             }
         }
-        image = PlanarImage.wrapRenderedImage(bi);
-
-        return image;
+        return PlanarImage.wrapRenderedImage(bi);
     }
 }
diff --git a/src/main/org/apache/tools/ant/types/optional/image/Ellipse.java b/src/main/org/apache/tools/ant/types/optional/image/Ellipse.java
index 9fa1802..8b35afa 100644
--- a/src/main/org/apache/tools/ant/types/optional/image/Ellipse.java
+++ b/src/main/org/apache/tools/ant/types/optional/image/Ellipse.java
@@ -51,35 +51,33 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public PlanarImage executeDrawOperation() {
         BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR_PRE);
 
-        Graphics2D graphics = (Graphics2D) bi.getGraphics();
+        Graphics2D graphics = bi.createGraphics();
 
-        if (!stroke.equals("transparent")) {
+        if (!"transparent".equalsIgnoreCase(stroke)) {
             BasicStroke bStroke = new BasicStroke(stroke_width);
             graphics.setColor(ColorMapper.getColorByName(stroke));
             graphics.setStroke(bStroke);
             graphics.draw(new Ellipse2D.Double(0, 0, width, height));
         }
 
-        if (!fill.equals("transparent")) {
+        if (!"transparent".equalsIgnoreCase(fill)) {
             graphics.setColor(ColorMapper.getColorByName(fill));
             graphics.fill(new Ellipse2D.Double(0, 0, width, height));
         }
 
-
-        final int size = instructions.size();
-        for (int i = 0; i < size; i++) {
-            ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+        for (ImageOperation instr : instructions) {
             if (instr instanceof DrawOperation) {
                 PlanarImage img = ((DrawOperation) instr).executeDrawOperation();
                 graphics.drawImage(img.getAsBufferedImage(), null, 0, 0);
             } else if (instr instanceof TransformOperation) {
-                graphics = (Graphics2D) bi.getGraphics();
                 PlanarImage image = ((TransformOperation) instr)
                     .executeTransformOperation(PlanarImage.wrapRenderedImage(bi));
                 bi = image.getAsBufferedImage();
+                graphics = bi.createGraphics();
             }
         }
         return PlanarImage.wrapRenderedImage(bi);
diff --git a/src/main/org/apache/tools/ant/types/optional/image/ImageOperation.java b/src/main/org/apache/tools/ant/types/optional/image/ImageOperation.java
index d72fe04..7ff6af8 100644
--- a/src/main/org/apache/tools/ant/types/optional/image/ImageOperation.java
+++ b/src/main/org/apache/tools/ant/types/optional/image/ImageOperation.java
@@ -27,7 +27,7 @@
  */
 public abstract class ImageOperation extends DataType {
      // CheckStyle:VisibilityModifier OFF - bc
-    protected Vector<ImageOperation> instructions = new Vector<ImageOperation>();
+    protected Vector<ImageOperation> instructions = new Vector<>();
      // CheckStyle:VisibilityModifier ON
 
     /**
diff --git a/src/main/org/apache/tools/ant/types/optional/image/Rectangle.java b/src/main/org/apache/tools/ant/types/optional/image/Rectangle.java
index e2d5bb1..b15272f 100644
--- a/src/main/org/apache/tools/ant/types/optional/image/Rectangle.java
+++ b/src/main/org/apache/tools/ant/types/optional/image/Rectangle.java
@@ -68,41 +68,39 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public PlanarImage executeDrawOperation() {
         log("\tCreating Rectangle w=" + width + " h=" + height + " arcw="
             + arcwidth + " arch=" + archeight);
         BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR_PRE);
 
-        Graphics2D graphics = (Graphics2D) bi.getGraphics();
+        Graphics2D graphics = bi.createGraphics();
 
-        if (!stroke.equals("transparent")) {
+        if (!"transparent".equalsIgnoreCase(stroke)) {
             BasicStroke bStroke = new BasicStroke(stroke_width);
             graphics.setColor(ColorMapper.getColorByName(stroke));
             graphics.setStroke(bStroke);
 
-            if ((arcwidth != 0) || (archeight != 0)) {
-                graphics.drawRoundRect(0, 0, width, height, arcwidth, archeight);
-            } else {
+            if (arcwidth == 0 && archeight == 0) {
                 graphics.drawRect(0, 0, width, height);
+            } else {
+                graphics.drawRoundRect(0, 0, width, height, arcwidth, archeight);
             }
         }
 
-        if (!fill.equals("transparent")) {
+        if (!"transparent".equalsIgnoreCase(fill)) {
             graphics.setColor(ColorMapper.getColorByName(fill));
-            if ((arcwidth != 0) || (archeight != 0)) {
+            if (arcwidth == 0 && archeight == 0) {
+                graphics.fillRect(stroke_width, stroke_width,
+                    width - (stroke_width * 2), height - (stroke_width * 2));
+            } else {
                 graphics.fillRoundRect(stroke_width, stroke_width,
                     width - (stroke_width * 2), height - (stroke_width * 2),
                     arcwidth, archeight);
-            } else {
-                graphics.fillRect(stroke_width, stroke_width,
-                    width - (stroke_width * 2), height - (stroke_width * 2));
             }
         }
 
-
-        final int size = instructions.size();
-        for (int i = 0; i < size; i++) {
-            ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+        for (ImageOperation instr : instructions) {
             if (instr instanceof DrawOperation) {
                 PlanarImage img = ((DrawOperation) instr).executeDrawOperation();
                 graphics.drawImage(img.getAsBufferedImage(), null, 0, 0);
diff --git a/src/main/org/apache/tools/ant/types/optional/image/Rotate.java b/src/main/org/apache/tools/ant/types/optional/image/Rotate.java
index 3d7a03a..3c813a8 100644
--- a/src/main/org/apache/tools/ant/types/optional/image/Rotate.java
+++ b/src/main/org/apache/tools/ant/types/optional/image/Rotate.java
@@ -67,24 +67,21 @@
      * @param image The image to perform the transformation on.
      * @return the transformed image.
      */
+    @Override
     public PlanarImage executeTransformOperation(PlanarImage image) {
-        BufferedImage bi = null;
-        final int size = instructions.size();
-        for (int i = 0; i < size; i++) {
-            ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+        for (ImageOperation instr : instructions) {
             if (instr instanceof DrawOperation) {
                 // If this TransformOperation has DrawOperation children
                 // then Rotate the first child and return.
                 System.out.println("Exec'ing Draws");
                 PlanarImage op = ((DrawOperation) instr).executeDrawOperation();
-                image = performRotate(op);
-                return image;
-            } else if (instr instanceof TransformOperation) {
-                bi = image.getAsBufferedImage();
+                return performRotate(op);
+            }
+            if (instr instanceof TransformOperation) {
+                BufferedImage bi = image.getAsBufferedImage();
                 System.out.println("Exec'ing Transforms");
                 image = ((TransformOperation) instr)
                     .executeTransformOperation(PlanarImage.wrapRenderedImage(bi));
-                bi = image.getAsBufferedImage();
             }
         }
         System.out.println("Exec'ing as TransformOperation");
@@ -100,16 +97,14 @@
      *  ONE image.
      * @return the image.
      */
+    @Override
     public PlanarImage executeDrawOperation() {
-        final int size = instructions.size();
-        for (int i = 0; i < size; i++) {
-            ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+        for (ImageOperation instr : instructions) {
             if (instr instanceof DrawOperation) {
                 // If this TransformOperation has DrawOperation children
                 // then Rotate the first child and return.
                 PlanarImage op = ((DrawOperation) instr).executeDrawOperation();
-                op = performRotate(op);
-                return op;
+                return performRotate(op);
             }
         }
         return null;
diff --git a/src/main/org/apache/tools/ant/types/optional/image/Scale.java b/src/main/org/apache/tools/ant/types/optional/image/Scale.java
index 532694d..156e47f 100644
--- a/src/main/org/apache/tools/ant/types/optional/image/Scale.java
+++ b/src/main/org/apache/tools/ant/types/optional/image/Scale.java
@@ -41,8 +41,9 @@
     /** Enumerated class for proportions attribute. */
     public static class ProportionsAttribute extends EnumeratedAttribute {
         /** {@inheritDoc}. */
+        @Override
         public String[] getValues() {
-            return new String[] {"ignore", "width", "height", "cover", "fit"};
+            return new String[] { "ignore", "width", "height", "cover", "fit" };
         }
     }
 
@@ -76,16 +77,14 @@
      * @return the value converted from the width string.
      */
     public float getWidth() {
-        float width = 0.0F;
         int percIndex = widthStr.indexOf('%');
         if (percIndex > 0) {
-            width = Float.parseFloat(widthStr.substring(0, percIndex));
             xPercent = true;
+            float width = Float.parseFloat(widthStr.substring(0, percIndex));
             return width / HUNDRED;
-        } else {
-            xPercent = false;
-            return Float.parseFloat(widthStr);
         }
+        xPercent = false;
+        return Float.parseFloat(widthStr);
     }
 
     /**
@@ -95,13 +94,12 @@
     public float getHeight() {
         int percIndex = heightStr.indexOf('%');
         if (percIndex > 0) {
-            float height = Float.parseFloat(heightStr.substring(0, percIndex));
             yPercent = true;
+            float height = Float.parseFloat(heightStr.substring(0, percIndex));
             return height / HUNDRED;
-        } else {
-            yPercent = false;
-            return Float.parseFloat(heightStr);
         }
+        yPercent = false;
+        return Float.parseFloat(heightStr);
     }
 
     /**
@@ -116,10 +114,10 @@
         float yFl = getHeight();
 
         if (!xPercent) {
-            xFl = (xFl / image.getWidth());
+            xFl = xFl / image.getWidth();
         }
         if (!yPercent) {
-            yFl = (yFl / image.getHeight());
+            yFl = yFl / image.getHeight();
         }
 
         if ("width".equals(proportions)) {
@@ -134,8 +132,8 @@
             xFl = yFl;
         }
 
-        pb.add(new Float(xFl));
-        pb.add(new Float(yFl));
+        pb.add(Float.valueOf(xFl));
+        pb.add(Float.valueOf(yFl));
 
         log("\tScaling to " + (xFl * HUNDRED) + "% x "
             + (yFl * HUNDRED) + "%");
@@ -145,18 +143,16 @@
 
 
     /** {@inheritDoc}. */
+    @Override
     public PlanarImage executeTransformOperation(PlanarImage image) {
-        BufferedImage bi = null;
-        final int size = instructions.size();
-        for (int i = 0; i < size; i++) {
-            ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+        for (ImageOperation instr : instructions) {
             if (instr instanceof DrawOperation) {
                 return performScale(image);
-            } else if (instr instanceof TransformOperation) {
-                bi = image.getAsBufferedImage();
+            }
+            if (instr instanceof TransformOperation) {
+                BufferedImage bi = image.getAsBufferedImage();
                 image = ((TransformOperation) instr)
                     .executeTransformOperation(PlanarImage.wrapRenderedImage(bi));
-                bi = image.getAsBufferedImage();
             }
         }
         return performScale(image);
@@ -164,10 +160,9 @@
 
 
     /** {@inheritDoc}. */
+    @Override
     public PlanarImage executeDrawOperation() {
-        final int size = instructions.size();
-        for (int i = 0; i < size; i++) {
-            ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+        for (ImageOperation instr : instructions) {
             if (instr instanceof DrawOperation) {
                 PlanarImage image = null;
                 // If this TransformOperation has DrawOperation children
diff --git a/src/main/org/apache/tools/ant/types/optional/image/Text.java b/src/main/org/apache/tools/ant/types/optional/image/Text.java
index 5ba010a..4f92d31 100644
--- a/src/main/org/apache/tools/ant/types/optional/image/Text.java
+++ b/src/main/org/apache/tools/ant/types/optional/image/Text.java
@@ -91,6 +91,7 @@
      * Draw the text.
      * @return the resultant image.
      */
+    @Override
     public PlanarImage executeDrawOperation() {
         log("\tCreating Text \"" + strText + "\"");
 
@@ -98,19 +99,18 @@
         int height = 1;
 
         BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR_PRE);
-        Graphics2D graphics = (Graphics2D) bi.getGraphics();
+        Graphics2D graphics = bi.createGraphics();
         graphics.setRenderingHint(
             RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
         graphics.setRenderingHint(
             RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
-        Font f = new Font(font, Font.PLAIN, point);
+        Font f = createFont();
         FontMetrics fmetrics = graphics.getFontMetrics(f);
         height = fmetrics.getMaxAscent() + fmetrics.getMaxDescent();
         width = fmetrics.stringWidth(strText);
 
-
         bi = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR_PRE);
-        graphics = (Graphics2D) bi.getGraphics();
+        graphics = bi.createGraphics();
 
         graphics.setRenderingHint(
             RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
@@ -120,7 +120,17 @@
         graphics.setFont(f);
         graphics.setColor(ColorMapper.getColorByName(color));
         graphics.drawString(strText, 0, height - fmetrics.getMaxDescent());
-        PlanarImage image = PlanarImage.wrapRenderedImage(bi);
-        return image;
+        return PlanarImage.wrapRenderedImage(bi);
+    }
+
+    private Font createFont() {
+        int style = Font.PLAIN;
+        if (bold) {
+            style |= Font.BOLD;
+        }
+        if (italic) {
+            style |= Font.ITALIC;
+        }
+        return new Font(font, style, point);
     }
 }
diff --git a/src/main/org/apache/tools/ant/types/optional/image/TransformOperation.java b/src/main/org/apache/tools/ant/types/optional/image/TransformOperation.java
index 896e5d1..3429ba7 100644
--- a/src/main/org/apache/tools/ant/types/optional/image/TransformOperation.java
+++ b/src/main/org/apache/tools/ant/types/optional/image/TransformOperation.java
@@ -32,6 +32,7 @@
     public abstract PlanarImage executeTransformOperation(PlanarImage img);
 
      /** {@inheritDoc}. */
+    @Override
     public void addRectangle(Rectangle instr) {
         instructions.add(instr);
     }
diff --git a/src/main/org/apache/tools/ant/types/optional/xz/XzResource.java b/src/main/org/apache/tools/ant/types/optional/xz/XzResource.java
new file mode 100644
index 0000000..8f2908e
--- /dev/null
+++ b/src/main/org/apache/tools/ant/types/optional/xz/XzResource.java
@@ -0,0 +1,82 @@
+/*
+ *  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.
+ *
+ */
+package org.apache.tools.ant.types.optional.xz;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.CompressedResource;
+import org.tukaani.xz.LZMA2Options;
+import org.tukaani.xz.XZInputStream;
+import org.tukaani.xz.XZOutputStream;
+
+/**
+ * A XZ compressed resource.
+ *
+ * <p>Wraps around another resource, delegates all queries to that
+ * other resource but uncompresses/compresses streams on the fly.</p>
+ *
+ * @since Ant 1.10.1
+ */
+public class XzResource extends CompressedResource {
+
+    /** A no-arg constructor */
+    public XzResource() {
+    }
+
+    /**
+     * Constructor with another resource to wrap.
+     * @param other the resource to wrap.
+     */
+    public XzResource(ResourceCollection other) {
+        super(other);
+    }
+
+    /**
+     * Decompress on the fly using java.util.zip.XZInputStream.
+     * @param in the stream to wrap.
+     * @return the wrapped stream.
+     * @throws IOException if there is a problem.
+     */
+    @Override
+    protected InputStream wrapStream(InputStream in) throws IOException {
+        return new XZInputStream(in);
+    }
+
+    /**
+     * Compress on the fly using java.util.zip.XZOutStream.
+     * @param out the stream to wrap.
+     * @return the wrapped stream.
+     * @throws IOException if there is a problem.
+     */
+     @Override
+    protected OutputStream wrapStream(OutputStream out) throws IOException {
+        return new XZOutputStream(out, new LZMA2Options());
+    }
+
+    /**
+     * Get the name of the compression method.
+     * @return the string "XZ".
+     */
+    @Override
+    protected String getCompressionName() {
+        return "XZ";
+    }
+}
diff --git a/src/main/org/apache/tools/ant/types/resolver/ApacheCatalog.java b/src/main/org/apache/tools/ant/types/resolver/ApacheCatalog.java
index 66ed7ff..04047da 100644
--- a/src/main/org/apache/tools/ant/types/resolver/ApacheCatalog.java
+++ b/src/main/org/apache/tools/ant/types/resolver/ApacheCatalog.java
@@ -54,6 +54,7 @@
      *  will be a total of two ApacheCatalog instances, and so on.</p>
      * @return the catalog.
      */
+    @Override
     protected Catalog newCatalog() {
         final ApacheCatalog cat = (ApacheCatalog) super.newCatalog();
         cat.setResolver(resolver);
@@ -85,6 +86,7 @@
      *
      * @param entry The CatalogEntry to process.
      */
+    @Override
     public void addEntry(final CatalogEntry entry) {
 
         final int type = entry.getEntryType();
diff --git a/src/main/org/apache/tools/ant/types/resolver/ApacheCatalogResolver.java b/src/main/org/apache/tools/ant/types/resolver/ApacheCatalogResolver.java
index f036247..fccedf7 100644
--- a/src/main/org/apache/tools/ant/types/resolver/ApacheCatalogResolver.java
+++ b/src/main/org/apache/tools/ant/types/resolver/ApacheCatalogResolver.java
@@ -19,7 +19,6 @@
 package org.apache.tools.ant.types.resolver;
 
 import java.io.IOException;
-import java.net.MalformedURLException;
 import java.net.URL;
 
 import org.apache.tools.ant.BuildException;
@@ -104,7 +103,7 @@
 
         final Catalog catalog = getCatalog();
         if (!(catalog instanceof ApacheCatalog)) {
-            throw new BuildException("Wrong catalog type found: " + catalog.getClass().getName());
+            throw new BuildException("Wrong catalog type found: %s", catalog.getClass().getName());
         }
         final ApacheCatalog apacheCatalog = (ApacheCatalog) catalog;
 
@@ -113,9 +112,7 @@
 
         try {
             apacheCatalog.parseCatalog(file);
-        } catch (final MalformedURLException ex) {
-            throw new BuildException(ex);
-        } catch (final IOException ex) {
+        } catch (IOException ex) {
             throw new BuildException(ex);
         }
     }
diff --git a/src/main/org/apache/tools/ant/types/resources/AbstractClasspathResource.java b/src/main/org/apache/tools/ant/types/resources/AbstractClasspathResource.java
index 5805c7c..9bc1481 100644
--- a/src/main/org/apache/tools/ant/types/resources/AbstractClasspathResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/AbstractClasspathResource.java
@@ -154,14 +154,10 @@
             return  ((Resource) getCheckedRef()).isExists();
         }
         dieOnCircularReference();
-        InputStream is = null;
-        try {
-            is = getInputStream();
+        try (InputStream is = getInputStream()) {
             return is != null;
         } catch (IOException ex) {
             return false;
-        } finally {
-            FileUtils.close(is);
         }
     }
 
@@ -181,18 +177,21 @@
         return !classLoader.needsCleanup()
             ? openInputStream(classLoader.getLoader())
             : new FilterInputStream(openInputStream(classLoader.getLoader())) {
-                    public void close() throws IOException {
-                        FileUtils.close(in);
-                        classLoader.cleanup();
+                @Override
+                public void close() throws IOException {
+                    FileUtils.close(in);
+                    classLoader.cleanup();
+                }
+
+                @Override
+                protected void finalize() throws Throwable {
+                    try {
+                        close();
+                    } finally {
+                        super.finalize();
                     }
-                    protected void finalize() throws Throwable {
-                        try {
-                            close();
-                        } finally {
-                            super.finalize();
-                        }
-                    }
-                };
+                }
+            };
     }
 
     /**
@@ -204,10 +203,10 @@
      */
     protected ClassLoaderWithFlag getClassLoader() {
         ClassLoader cl = null;
-        boolean clNeedsCleanup = false;
         if (loader != null) {
             cl = (ClassLoader) loader.getReferencedObject();
         }
+        boolean clNeedsCleanup = false;
         if (cl == null) {
             if (getClasspath() != null) {
                 Path p = getClasspath().concatSystemClasspath("ignore");
@@ -261,8 +260,15 @@
             loader = l;
             cleanup = needsCleanup && l instanceof AntClassLoader;
         }
-        public ClassLoader getLoader() { return loader; }
-        public boolean needsCleanup() { return cleanup; }
+
+        public ClassLoader getLoader() {
+            return loader;
+        }
+
+        public boolean needsCleanup() {
+            return cleanup;
+        }
+
         public void cleanup() {
             if (cleanup) {
                 ((AntClassLoader) loader).cleanup();
diff --git a/src/main/org/apache/tools/ant/types/resources/AbstractResourceCollectionWrapper.java b/src/main/org/apache/tools/ant/types/resources/AbstractResourceCollectionWrapper.java
index 5e4c3a3..b73d99c 100644
--- a/src/main/org/apache/tools/ant/types/resources/AbstractResourceCollectionWrapper.java
+++ b/src/main/org/apache/tools/ant/types/resources/AbstractResourceCollectionWrapper.java
@@ -20,6 +20,7 @@
 import java.io.File;
 import java.util.Iterator;
 import java.util.Stack;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -85,6 +86,7 @@
      * Fulfill the ResourceCollection contract.
      * @return an Iterator of Resources.
      */
+    @Override
     public final synchronized Iterator<Resource> iterator() {
         if (isReference()) {
             return ((AbstractResourceCollectionWrapper) getCheckedRef()).iterator();
@@ -107,6 +109,7 @@
      * Fulfill the ResourceCollection contract.
      * @return number of elements as int.
      */
+    @Override
     public synchronized int size() {
         if (isReference()) {
             return ((AbstractResourceCollectionWrapper) getCheckedRef()).size();
@@ -182,24 +185,19 @@
     }
 
     /**
-     * Format this BaseResourceCollectionWrapper as a String.
+     * Format this AbstractResourceCollectionWrapper as a String.
      * @return a descriptive <code>String</code>.
      */
+    @Override
     public synchronized String toString() {
         if (isReference()) {
             return getCheckedRef().toString();
         }
-        if (getSize() == 0) {
+        if (isEmpty()) {
             return "";
         }
-        StringBuilder sb = new StringBuilder();
-        for (Resource resource : this) {
-            if (sb.length() > 0) {
-                sb.append(File.pathSeparatorChar);
-            }
-            sb.append(resource);
-        }
-        return sb.toString();
+        return stream().map(Object::toString)
+            .collect(Collectors.joining(File.pathSeparator));
     }
 
     private BuildException oneNested() {
diff --git a/src/main/org/apache/tools/ant/types/resources/AllButFirst.java b/src/main/org/apache/tools/ant/types/resources/AllButFirst.java
index ffa665f..f6bcf49 100644
--- a/src/main/org/apache/tools/ant/types/resources/AllButFirst.java
+++ b/src/main/org/apache/tools/ant/types/resources/AllButFirst.java
@@ -17,10 +17,8 @@
  */
 package org.apache.tools.ant.types.resources;
 
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.types.Resource;
 
@@ -36,25 +34,15 @@
      * Take all elements except for the first <code>count</code> elements.
      * @return a Collection of Resources.
      */
+    @Override
     protected Collection<Resource> getCollection() {
-        int ct = getValidCount();
-        Iterator<Resource> iter = getResourceCollection().iterator();
-        List<Resource> al = new ArrayList<Resource>();
-        for (int i = 0; i < ct && iter.hasNext(); i++) {
-            // discard
-            iter.next();
-        }
-        while (iter.hasNext()) {
-            al.add(iter.next());
-        }
-        return al;
+        return getResourceCollection().stream().skip(getValidCount())
+            .collect(Collectors.toList());
     }
 
     @Override
     public synchronized int size() {
-        int sz = getResourceCollection().size();
-        int ct = getValidCount();
-        return sz > ct ? sz - ct : 0;
+        return (int) getResourceCollection().stream().skip(getValidCount()).count();
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/AllButLast.java b/src/main/org/apache/tools/ant/types/resources/AllButLast.java
index a1e6a98..03f665e 100644
--- a/src/main/org/apache/tools/ant/types/resources/AllButLast.java
+++ b/src/main/org/apache/tools/ant/types/resources/AllButLast.java
@@ -18,10 +18,11 @@
 package org.apache.tools.ant.types.resources;
 
 import java.util.Collection;
-import java.util.List;
+import java.util.Collections;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.util.CollectionUtils;
+import org.apache.tools.ant.types.ResourceCollection;
 
 /**
  * ResourceCollection that contains all resources of another
@@ -35,19 +36,20 @@
      * Take all elements except for the last <code>count</code> elements.
      * @return a Collection of Resources.
      */
+    @Override
     protected Collection<Resource> getCollection() {
         int ct = getValidCount();
-        List<Resource> result =
-            (List<Resource>) CollectionUtils.asCollection(getResourceCollection()
-                                                          .iterator());
-        return result.subList(0, result.size() - ct);
+        ResourceCollection nested = getResourceCollection();
+        if (ct > nested.size()) {
+            return Collections.emptyList();
+        }
+        return nested.stream().limit((long) nested.size() - ct)
+            .collect(Collectors.toList());
     }
 
     @Override
     public synchronized int size() {
-        int sz = getResourceCollection().size();
-        int ct = getValidCount();
-        return sz > ct ? sz - ct : 0;
+        return Math.max(getResourceCollection().size() - getValidCount(), 0);
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/ArchiveResource.java b/src/main/org/apache/tools/ant/types/resources/ArchiveResource.java
index 2d87aa6..6ac43ea 100644
--- a/src/main/org/apache/tools/ant/types/resources/ArchiveResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/ArchiveResource.java
@@ -103,12 +103,12 @@
     public void addConfigured(ResourceCollection a) {
         checkChildrenAllowed();
         if (archive != null) {
-            throw new BuildException("you must not specify more than one"
-                                     + " archive");
+            throw new BuildException(
+                "you must not specify more than one archive");
         }
         if (a.size() != 1) {
-            throw new BuildException("only single argument resource collections"
-                                     + " are supported as archives");
+            throw new BuildException(
+                "only single argument resource collections are supported as archives");
         }
         archive = a.iterator().next();
     }
@@ -118,17 +118,17 @@
      * @return the archive as a Resource.
      */
     public Resource getArchive() {
-        return isReference()
-            ? ((ArchiveResource) getCheckedRef()).getArchive() : archive;
+        return isReference() ? getCheckedRef().getArchive() : archive;
     }
 
     /**
      * Get the last modified date of this Resource.
      * @return the last modification date.
      */
+    @Override
     public long getLastModified() {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getLastModified();
+            return getCheckedRef().getLastModified();
         }
         checkEntry();
         return super.getLastModified();
@@ -138,9 +138,10 @@
      * Get the size of this Resource.
      * @return the long size of this Resource.
      */
+    @Override
     public long getSize() {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getSize();
+            return getCheckedRef().getSize();
         }
         checkEntry();
         return super.getSize();
@@ -150,9 +151,10 @@
      * Learn whether this Resource represents a directory.
      * @return boolean flag indicating whether the entry is a directory.
      */
+    @Override
     public boolean isDirectory() {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).isDirectory();
+            return getCheckedRef().isDirectory();
         }
         checkEntry();
         return super.isDirectory();
@@ -162,9 +164,10 @@
      * Find out whether this Resource represents an existing Resource.
      * @return boolean existence flag.
      */
+    @Override
     public boolean isExists() {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).isExists();
+            return getCheckedRef().isExists();
         }
         checkEntry();
         return super.isExists();
@@ -176,7 +179,7 @@
      */
     public int getMode() {
         if (isReference()) {
-            return ((ArchiveResource) getCheckedRef()).getMode();
+            return getCheckedRef().getMode();
         }
         checkEntry();
         return mode;
@@ -186,6 +189,7 @@
      * Overrides the super version.
      * @param r the Reference to set.
      */
+    @Override
     public void setRefid(Reference r) {
         if (archive != null || modeSet) {
             throw tooManyAttributes();
@@ -199,6 +203,7 @@
      * @return a negative integer, zero, or a positive integer as this Resource
      *         is less than, equal to, or greater than the specified Resource.
      */
+    @Override
     public int compareTo(Resource another) {
         return this.equals(another) ? 0 : super.compareTo(another);
     }
@@ -209,6 +214,7 @@
      * @return true if another is a Resource representing
      *              the same entry in the same archive.
      */
+    @Override
     public boolean equals(Object another) {
         if (this == another) {
             return true;
@@ -216,7 +222,7 @@
         if (isReference()) {
             return getCheckedRef().equals(another);
         }
-        if (another == null || another.getClass() != getClass()) {
+        if (another == null || !another.getClass().equals(getClass())) {
             return false;
         }
         ArchiveResource r = (ArchiveResource) another;
@@ -228,6 +234,7 @@
      * Get the hash code for this Resource.
      * @return hash code as int.
      */
+    @Override
     public int hashCode() {
         return super.hashCode()
             * (getArchive() == null ? NULL_ARCHIVE : getArchive().hashCode());
@@ -237,6 +244,7 @@
      * Format this Resource as a String.
      * @return String representation of this Resource.
      */
+    @Override
     public String toString() {
         return isReference() ? getCheckedRef().toString()
             : getArchive().toString() + ':' + getName();
@@ -260,10 +268,10 @@
             throw new BuildException("archive attribute not set");
         }
         if (!r.isExists()) {
-            throw new BuildException(r.toString() + " does not exist.");
+            throw new BuildException("%s does not exist.", r);
         }
         if (r.isDirectory()) {
-            throw new BuildException(r + " denotes a directory.");
+            throw new BuildException("%s denotes a directory.", r);
         }
         fetchEntry();
         haveEntry = true;
@@ -277,6 +285,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p) {
         if (isChecked()) {
             return;
@@ -290,4 +299,9 @@
             setChecked(true);
         }
     }
+
+    @Override
+    protected ArchiveResource getCheckedRef() {
+        return (ArchiveResource) super.getCheckedRef();
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/Archives.java b/src/main/org/apache/tools/ant/types/resources/Archives.java
index 24bfd28..23c18f3 100644
--- a/src/main/org/apache/tools/ant/types/resources/Archives.java
+++ b/src/main/org/apache/tools/ant/types/resources/Archives.java
@@ -21,6 +21,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Stack;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -31,7 +32,6 @@
 import org.apache.tools.ant.types.ResourceCollection;
 import org.apache.tools.ant.types.TarFileSet;
 import org.apache.tools.ant.types.ZipFileSet;
-import org.apache.tools.ant.util.CollectionUtils;
 
 /**
  * A resource collection that treats all nested resources as archives
@@ -78,16 +78,13 @@
      *
      * @return int
      */
+    @Override
     public int size() {
         if (isReference()) {
-            return ((Archives) getCheckedRef()).size();
+            return getCheckedRef().size();
         }
         dieOnCircularReference();
-        int total = 0;
-        for (final Iterator<ArchiveFileSet> i = grabArchives(); i.hasNext();) {
-            total += i.next().size();
-        }
-        return total;
+        return streamArchives().mapToInt(ArchiveFileSet::size).sum();
     }
 
     /**
@@ -97,15 +94,11 @@
      */
     public Iterator<Resource> iterator() {
         if (isReference()) {
-            return ((Archives) getCheckedRef()).iterator();
+            return getCheckedRef().iterator();
         }
         dieOnCircularReference();
-        final List<Resource> l = new LinkedList<Resource>();
-        for (final Iterator<ArchiveFileSet> i = grabArchives(); i.hasNext();) {
-            l.addAll(CollectionUtils
-                     .asCollection(i.next().iterator()));
-        }
-        return l.iterator();
+        return streamArchives().flatMap(ResourceCollection::stream)
+            .map(Resource.class::cast).iterator();
     }
 
     /**
@@ -113,9 +106,10 @@
      */
     public boolean isFilesystemOnly() {
         if (isReference()) {
-            return ((Archives) getCheckedRef()).isFilesystemOnly();
+            return getCheckedRef().isFilesystemOnly();
         }
         dieOnCircularReference();
+        // TODO check each archive in turn?
         return false;
     }
 
@@ -126,8 +120,8 @@
      */
     @Override
     public void setRefid(final Reference r) {
-        if (zips.getResourceCollections().size() > 0
-            || tars.getResourceCollections().size() > 0) {
+        if (!(zips.getResourceCollections().isEmpty()
+            && tars.getResourceCollections().isEmpty())) {
             throw tooManyAttributes();
         }
         super.setRefid(r);
@@ -140,7 +134,7 @@
      * @return a cloned instance.
      */
     @Override
-    public Object clone() {
+    public Archives clone() {
         try {
             final Archives a = (Archives) super.clone();
             a.zips = (Union) zips.clone();
@@ -160,14 +154,20 @@
      * @return Iterator&lt;ArchiveFileSet&gt;
      */
     protected Iterator<ArchiveFileSet> grabArchives() {
-        final List<ArchiveFileSet> l = new LinkedList<ArchiveFileSet>();
+        return streamArchives().iterator();
+    }
+
+    // TODO this is a pretty expensive operation and so the result
+    // should be cached.
+    private Stream<ArchiveFileSet> streamArchives() {
+        final List<ArchiveFileSet> l = new LinkedList<>();
         for (final Resource r : zips) {
             l.add(configureArchive(new ZipFileSet(), r));
         }
         for (final Resource r : tars) {
             l.add(configureArchive(new TarFileSet(), r));
         }
-        return l.iterator();
+        return l.stream();
     }
 
     /**
@@ -208,4 +208,9 @@
         }
     }
 
+    @Override
+    protected Archives getCheckedRef() {
+        return (Archives) super.getCheckedRef();
+    }
+
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/BCFileSet.java b/src/main/org/apache/tools/ant/types/resources/BCFileSet.java
index aa99a4a..6d8aaf8 100644
--- a/src/main/org/apache/tools/ant/types/resources/BCFileSet.java
+++ b/src/main/org/apache/tools/ant/types/resources/BCFileSet.java
@@ -47,6 +47,7 @@
      * @return an Iterator of Resources.
      * @since Ant 1.7
      */
+    @Override
     public Iterator<Resource> iterator() {
         if (isReference()) {
             return ((FileSet) getRef(getProject())).iterator();
@@ -62,6 +63,7 @@
      * @return number of elements as int.
      * @since Ant 1.7
      */
+    @Override
     public int size() {
         if (isReference()) {
             return ((FileSet) getRef(getProject())).size();
diff --git a/src/main/org/apache/tools/ant/types/resources/BZip2Resource.java b/src/main/org/apache/tools/ant/types/resources/BZip2Resource.java
index 0c2dd4b..787407b 100644
--- a/src/main/org/apache/tools/ant/types/resources/BZip2Resource.java
+++ b/src/main/org/apache/tools/ant/types/resources/BZip2Resource.java
@@ -53,6 +53,7 @@
      * @return the wrapped stream.
      * @throws IOException if there is a problem.
      */
+    @Override
     protected InputStream wrapStream(InputStream in) throws IOException {
         for (int i = 0; i < MAGIC.length; i++) {
             if (in.read() != MAGIC[i]) {
@@ -68,6 +69,7 @@
      * @return the wrapped stream.
      * @throws IOException if there is a problem.
      */
+    @Override
     protected OutputStream wrapStream(OutputStream out) throws IOException {
         for (int i = 0; i < MAGIC.length; i++) {
             out.write(MAGIC[i]);
@@ -79,6 +81,7 @@
      * Get the name of the compression method.
      * @return the string "Bzip2".
      */
+    @Override
     protected String getCompressionName() {
         return "Bzip2";
     }
diff --git a/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionContainer.java b/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionContainer.java
index c794aed..c26f8a4 100644
--- a/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionContainer.java
+++ b/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionContainer.java
@@ -24,6 +24,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Stack;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -37,7 +38,7 @@
  */
 public abstract class BaseResourceCollectionContainer
         extends DataType implements ResourceCollection, Cloneable {
-    private List<ResourceCollection> rc = new ArrayList<ResourceCollection>();
+    private List<ResourceCollection> rc = new ArrayList<>();
     private Collection<Resource> coll = null;
     private boolean cache = true;
 
@@ -45,7 +46,6 @@
      * Create a new BaseResourceCollectionContainer.
      */
     public BaseResourceCollectionContainer() {
-        // TODO Auto-generated constructor stub
     }
 
     /**
@@ -121,9 +121,7 @@
             throw noChildrenAllowed();
         }
         try {
-            for (ResourceCollection resourceCollection : c) {
-                add(resourceCollection);
-            }
+            c.forEach(this::add);
         } catch (ClassCastException e) {
             throw new BuildException(e);
         }
@@ -135,9 +133,10 @@
      * are added to this container while the Iterator is in use.
      * @return a "fail-fast" Iterator.
      */
+    @Override
     public final synchronized Iterator<Resource> iterator() {
         if (isReference()) {
-            return ((BaseResourceCollectionContainer) getCheckedRef()).iterator();
+            return getCheckedRef().iterator();
         }
         dieOnCircularReference();
         return new FailFast(this, cacheCollection().iterator());
@@ -147,9 +146,11 @@
      * Fulfill the ResourceCollection contract.
      * @return number of elements as int.
      */
+    @Override
     public synchronized int size() {
         if (isReference()) {
-            return getCheckedRef(BaseResourceCollectionContainer.class, getDataTypeName()).size();
+            return getCheckedRef(BaseResourceCollectionContainer.class,
+                getDataTypeName()).size();
         }
         dieOnCircularReference();
         return cacheCollection().size();
@@ -159,27 +160,20 @@
      * Fulfill the ResourceCollection contract.
      * @return whether this is a filesystem-only resource collection.
      */
+    @Override
     public synchronized boolean isFilesystemOnly() {
         if (isReference()) {
-            return ((BaseResourceCollectionContainer) getCheckedRef()).isFilesystemOnly();
+            return getCheckedRef().isFilesystemOnly();
         }
         dieOnCircularReference();
         //first the easy way, if all children are filesystem-only, return true:
-        boolean goEarly = true;
-        for (Iterator<ResourceCollection> i = rc.iterator(); goEarly && i.hasNext();) {
-            goEarly = i.next().isFilesystemOnly();
-        }
-        if (goEarly) {
+        if (rc.stream().allMatch(ResourceCollection::isFilesystemOnly)) {
             return true;
         }
         /* now check each Resource in case the child only
            lets through files from any children IT may have: */
-        for (Resource r : cacheCollection()) {
-            if (r.as(FileProvider.class) == null) {
-                return false;
-            }
-        }
-        return true;
+        return cacheCollection().stream()
+            .allMatch(r -> r.asOptional(FileProvider.class).isPresent());
     }
 
     /**
@@ -226,11 +220,12 @@
      * collections is shallowly cloned.
      * @return a cloned instance.
      */
-    public Object clone() {
+    @Override
+    public BaseResourceCollectionContainer clone() {
         try {
             BaseResourceCollectionContainer c
                 = (BaseResourceCollectionContainer) super.clone();
-            c.rc = new ArrayList<ResourceCollection>(rc);
+            c.rc = new ArrayList<>(rc);
             c.coll = null;
             return c;
         } catch (CloneNotSupportedException e) {
@@ -242,21 +237,21 @@
      * Format this BaseResourceCollectionContainer as a String.
      * @return a descriptive <code>String</code>.
      */
+    @Override
     public synchronized String toString() {
         if (isReference()) {
             return getCheckedRef().toString();
         }
-        if (cacheCollection().size() == 0) {
+        if (cacheCollection().isEmpty()) {
             return "";
         }
-        StringBuilder sb = new StringBuilder();
-        for (Resource resource : coll) {
-            if (sb.length() > 0) {
-                sb.append(File.pathSeparatorChar);
-            }
-            sb.append(resource);
-        }
-        return sb.toString();
+        return coll.stream().map(Object::toString)
+            .collect(Collectors.joining(File.pathSeparator));
+    }
+
+    @Override
+    protected BaseResourceCollectionContainer getCheckedRef() {
+        return (BaseResourceCollectionContainer) super.getCheckedRef();
     }
 
     private synchronized Collection<Resource> cacheCollection() {
diff --git a/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java b/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java
index 2734620..66f292b 100644
--- a/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java
+++ b/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java
@@ -32,10 +32,12 @@
 
     private Collection<Resource> coll = null;
 
+    @Override
     protected Iterator<Resource> createIterator() {
         return cacheCollection().iterator();
     }
 
+    @Override
     protected int getSize() {
         return cacheCollection().size();
     }
diff --git a/src/main/org/apache/tools/ant/types/resources/CompressedResource.java b/src/main/org/apache/tools/ant/types/resources/CompressedResource.java
index 2c72c26..d77c16c 100644
--- a/src/main/org/apache/tools/ant/types/resources/CompressedResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/CompressedResource.java
@@ -47,6 +47,7 @@
      * @return this Resource formatted as a String.
      * @since Ant 1.7
      */
+    @Override
     public String toString() {
         return getCompressionName() + " compressed " + super.toString();
     }
diff --git a/src/main/org/apache/tools/ant/types/resources/ContentTransformingResource.java b/src/main/org/apache/tools/ant/types/resources/ContentTransformingResource.java
index 19e86b3..fd34ee2 100644
--- a/src/main/org/apache/tools/ant/types/resources/ContentTransformingResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/ContentTransformingResource.java
@@ -23,7 +23,6 @@
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.types.ResourceCollection;
-import org.apache.tools.ant.util.FileUtils;
 
 /**
  * A resource that transforms the content of another resource.
@@ -58,9 +57,7 @@
     @Override
     public long getSize() {
         if (isExists()) {
-            InputStream in = null;
-            try {
-                in = getInputStream();
+            try (InputStream in = getInputStream()) {
                 final byte[] buf = new byte[BUFFER_SIZE];
                 int size = 0;
                 int readNow;
@@ -69,14 +66,11 @@
                 }
                 return size;
             } catch (final IOException ex) {
-                throw new BuildException("caught exception while reading "
-                                         + getName(), ex);
-            } finally {
-                FileUtils.close(in);
+                throw new BuildException(
+                    "caught exception while reading " + getName(), ex);
             }
-        } else {
-            return 0;
         }
+        return 0;
     }
 
     /**
@@ -120,24 +114,16 @@
     public <T> T as(final Class<T> clazz) {
         if (Appendable.class.isAssignableFrom(clazz)) {
             if (isAppendSupported()) {
-                final Appendable a =
-                    getResource().as(Appendable.class);
+                final Appendable a = getResource().as(Appendable.class);
                 if (a != null) {
-                    return clazz.cast(new Appendable() {
-                        public OutputStream getAppendOutputStream()
-                                throws IOException {
-                            OutputStream out = a.getAppendOutputStream();
-                            if (out != null) {
-                                out = wrapStream(out);
-                            }
-                            return out;
-                        }
+                    return clazz.cast((Appendable) () -> {
+                        OutputStream out = a.getAppendOutputStream();
+                        return out == null ? null : wrapStream(out);
                     });
                 }
             }
             return null;
         }
-
         return FileProvider.class.isAssignableFrom(clazz)
             ? null : getResource().as(clazz);
     }
diff --git a/src/main/org/apache/tools/ant/types/resources/Difference.java b/src/main/org/apache/tools/ant/types/resources/Difference.java
index 3f3c983..920f9bc 100644
--- a/src/main/org/apache/tools/ant/types/resources/Difference.java
+++ b/src/main/org/apache/tools/ant/types/resources/Difference.java
@@ -38,16 +38,17 @@
      * Calculate the difference of the nested ResourceCollections.
      * @return a Collection of Resources.
      */
+    @Override
     protected Collection<Resource> getCollection() {
         List<ResourceCollection> rcs = getResourceCollections();
         int size = rcs.size();
         if (size < 2) {
-            throw new BuildException("The difference of " + size
-                + " resource collection" + ((size == 1) ? "" : "s")
-                + " is undefined.");
+            throw new BuildException(
+                "The difference of %d resource %s is undefined.", size,
+                size == 1 ? "collection" : "collections");
         }
-        Set<Resource> hs = new HashSet<Resource>();
-        List<Resource> al = new ArrayList<Resource>();
+        Set<Resource> hs = new HashSet<>();
+        List<Resource> al = new ArrayList<>();
         for (ResourceCollection rc : rcs) {
             for (Resource r : rc) {
                 if (hs.add(r)) {
diff --git a/src/main/org/apache/tools/ant/types/resources/FailFast.java b/src/main/org/apache/tools/ant/types/resources/FailFast.java
index dc962bb..f8da1b9 100644
--- a/src/main/org/apache/tools/ant/types/resources/FailFast.java
+++ b/src/main/org/apache/tools/ant/types/resources/FailFast.java
@@ -32,7 +32,7 @@
  * @since Ant 1.7
  */
 /*package-private*/ class FailFast implements Iterator<Resource> {
-    private static final WeakHashMap<Object, Set<FailFast>> MAP = new WeakHashMap<Object, Set<FailFast>>();
+    private static final WeakHashMap<Object, Set<FailFast>> MAP = new WeakHashMap<>();
 
     /**
      * Invalidate any in-use Iterators from the specified Object.
@@ -46,12 +46,7 @@
     }
 
     private static synchronized void add(FailFast f) {
-        Set<FailFast> s = MAP.get(f.parent);
-        if (s == null) {
-            s = new HashSet<FailFast>();
-            MAP.put(f.parent, s);
-        }
-        s.add(f);
+        MAP.computeIfAbsent(f.parent, k -> new HashSet<>()).add(f);
     }
 
     private static synchronized void remove(FailFast f) {
@@ -95,6 +90,7 @@
      * Fulfill the Iterator contract.
      * @return true if there are more elements.
      */
+    @Override
     public boolean hasNext() {
         if (wrapped == null) {
             return false;
@@ -108,6 +104,7 @@
      * @return the next element.
      * @throws NoSuchElementException if no more elements.
      */
+    @Override
     public Resource next() {
         if (wrapped == null || !wrapped.hasNext()) {
             throw new NoSuchElementException();
@@ -127,6 +124,7 @@
      * Fulfill the Iterator contract.
      * @throws UnsupportedOperationException always.
      */
+    @Override
     public void remove() {
         throw new UnsupportedOperationException();
     }
diff --git a/src/main/org/apache/tools/ant/types/resources/FileResource.java b/src/main/org/apache/tools/ant/types/resources/FileResource.java
index e967907..5a8ba90 100644
--- a/src/main/org/apache/tools/ant/types/resources/FileResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/FileResource.java
@@ -18,11 +18,10 @@
 package org.apache.tools.ant.types.resources;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.file.Files;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -106,9 +105,10 @@
      * Get the file represented by this FileResource.
      * @return the File.
      */
+    @Override
     public File getFile() {
         if (isReference()) {
-            return ((FileResource) getCheckedRef()).getFile();
+            return getCheckedRef().getFile();
         }
         dieOnCircularReference();
         synchronized (this) {
@@ -139,7 +139,7 @@
      */
     public File getBaseDir() {
         if (isReference()) {
-            return ((FileResource) getCheckedRef()).getBaseDir();
+            return getCheckedRef().getBaseDir();
         }
         dieOnCircularReference();
         return baseDir;
@@ -149,6 +149,7 @@
      * Overrides the super version.
      * @param r the Reference to set.
      */
+    @Override
     public void setRefid(Reference r) {
         if (file != null || baseDir != null) {
             throw tooManyAttributes();
@@ -162,9 +163,10 @@
      * only will be returned.
      * @return the name of this resource.
      */
+    @Override
     public String getName() {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getName();
+            return getCheckedRef().getName();
         }
         File b = getBaseDir();
         return b == null ? getNotNullFile().getName()
@@ -175,8 +177,9 @@
      * Learn whether this file exists.
      * @return true if this resource exists.
      */
+    @Override
     public boolean isExists() {
-        return isReference() ? ((Resource) getCheckedRef()).isExists()
+        return isReference() ? getCheckedRef().isExists()
             : getNotNullFile().exists();
     }
 
@@ -184,9 +187,10 @@
      * Get the modification time in milliseconds since 01.01.1970 .
      * @return 0 if the resource does not exist.
      */
+    @Override
     public long getLastModified() {
         return isReference()
-            ? ((Resource) getCheckedRef()).getLastModified()
+            ? getCheckedRef().getLastModified()
             : getNotNullFile().lastModified();
     }
 
@@ -194,8 +198,9 @@
      * Learn whether the resource is a directory.
      * @return boolean flag indicating if the resource is a directory.
      */
+    @Override
     public boolean isDirectory() {
-        return isReference() ? ((Resource) getCheckedRef()).isDirectory()
+        return isReference() ? getCheckedRef().isDirectory()
             : getNotNullFile().isDirectory();
     }
 
@@ -203,8 +208,9 @@
      * Get the size of this Resource.
      * @return the size, as a long, 0 if the Resource does not exist.
      */
+    @Override
     public long getSize() {
-        return isReference() ? ((Resource) getCheckedRef()).getSize()
+        return isReference() ? getCheckedRef().getSize()
             : getNotNullFile().length();
     }
 
@@ -213,10 +219,10 @@
      * @return an InputStream object.
      * @throws IOException if an error occurs.
      */
+    @Override
     public InputStream getInputStream() throws IOException {
-        return isReference()
-            ? ((Resource) getCheckedRef()).getInputStream()
-            : new FileInputStream(getNotNullFile());
+        return isReference() ? getCheckedRef().getInputStream()
+            : Files.newInputStream(getNotNullFile().toPath());
     }
 
     /**
@@ -227,9 +233,10 @@
      * @throws UnsupportedOperationException if OutputStreams are not
      *         supported for this Resource type.
      */
+    @Override
     public OutputStream getOutputStream() throws IOException {
         if (isReference()) {
-            return ((FileResource) getCheckedRef()).getOutputStream();
+            return getCheckedRef().getOutputStream();
         }
         return getOutputStream(false);
     }
@@ -237,9 +244,10 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public OutputStream getAppendOutputStream() throws IOException {
         if (isReference()) {
-            return ((FileResource) getCheckedRef()).getAppendOutputStream();
+            return getCheckedRef().getAppendOutputStream();
         }
         return getOutputStream(true);
     }
@@ -256,7 +264,7 @@
                 p.mkdirs();
             }
         }
-        return append ? new FileOutputStream(f.getAbsolutePath(), true) : new FileOutputStream(f);
+        return FileUtils.newOutputStream(f.toPath(), append);
     }
 
     /**
@@ -265,9 +273,10 @@
      * @return a negative integer, zero, or a positive integer as this FileResource
      *         is less than, equal to, or greater than the specified Resource.
      */
+    @Override
     public int compareTo(Resource another) {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).compareTo(another);
+            return getCheckedRef().compareTo(another);
         }
         if (this.equals(another)) {
             return 0;
@@ -294,6 +303,7 @@
      * @param another the other Object to compare.
      * @return true if another is a FileResource representing the same file.
      */
+    @Override
     public boolean equals(Object another) {
         if (this == another) {
             return true;
@@ -314,6 +324,7 @@
      * Get the hash code for this Resource.
      * @return hash code as int.
      */
+    @Override
     public int hashCode() {
         if (isReference()) {
             return getCheckedRef().hashCode();
@@ -325,6 +336,7 @@
      * Get the string representation of this Resource.
      * @return this FileResource formatted as a String.
      */
+    @Override
     public String toString() {
         if (isReference()) {
             return getCheckedRef().toString();
@@ -340,9 +352,10 @@
      * Fulfill the ResourceCollection contract.
      * @return whether this Resource is a FileResource.
      */
+    @Override
     public boolean isFilesystemOnly() {
         if (isReference()) {
-            return ((FileResource) getCheckedRef()).isFilesystemOnly();
+            return getCheckedRef().isFilesystemOnly();
         }
         dieOnCircularReference();
         return true;
@@ -352,9 +365,10 @@
      * Implement the Touchable interface.
      * @param modTime new last modification time.
      */
+    @Override
     public void touch(long modTime) {
         if (isReference()) {
-            ((FileResource) getCheckedRef()).touch(modTime);
+            getCheckedRef().touch(modTime);
             return;
         }
         if (!getNotNullFile().setLastModified(modTime)) {
@@ -383,6 +397,7 @@
      * @throws BuildException if desired
      * @since Ant1.8
      */
+    @Override
     public Resource getResource(String path) {
         File newfile = FILE_UTILS.resolveFile(getFile(), path);
         FileResource fileResource = new FileResource(newfile);
@@ -391,4 +406,9 @@
         }
         return fileResource;
     }
+
+    @Override
+    protected FileResource getCheckedRef() {
+        return (FileResource) super.getCheckedRef();
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/FileResourceIterator.java b/src/main/org/apache/tools/ant/types/resources/FileResourceIterator.java
index 6d8849c..2584117 100644
--- a/src/main/org/apache/tools/ant/types/resources/FileResourceIterator.java
+++ b/src/main/org/apache/tools/ant/types/resources/FileResourceIterator.java
@@ -114,6 +114,7 @@
      * Find out whether this FileResourceIterator has more elements.
      * @return whether there are more Resources to iterate over.
      */
+    @Override
     public boolean hasNext() {
         return pos < files.length;
     }
@@ -122,6 +123,7 @@
      * Get the next element from this FileResourceIterator.
      * @return the next Object.
      */
+    @Override
     public Resource next() {
         return nextResource();
     }
@@ -129,6 +131,7 @@
     /**
      * Not implemented.
      */
+    @Override
     public void remove() {
         throw new UnsupportedOperationException();
     }
diff --git a/src/main/org/apache/tools/ant/types/resources/Files.java b/src/main/org/apache/tools/ant/types/resources/Files.java
index 521bcc8..00e5d4d 100644
--- a/src/main/org/apache/tools/ant/types/resources/Files.java
+++ b/src/main/org/apache/tools/ant/types/resources/Files.java
@@ -21,6 +21,7 @@
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.Vector;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.DirectoryScanner;
@@ -39,11 +40,8 @@
 public class Files extends AbstractSelectorContainer
     implements ResourceCollection {
 
-    private static final Iterator<Resource> EMPTY_ITERATOR
-        = Collections.<Resource>emptySet().iterator();
-
     private PatternSet defaultPatterns = new PatternSet();
-    private Vector<PatternSet> additionalPatterns = new Vector<PatternSet>();
+    private Vector<PatternSet> additionalPatterns = new Vector<>();
 
     private boolean useDefaultExcludes = true;
     private boolean caseSensitive = true;
@@ -82,6 +80,7 @@
      * @param r the <code>Reference</code> to use.
      * @throws BuildException if there is a problem.
      */
+    @Override
     public void setRefid(Reference r) throws BuildException {
         if (hasPatterns(defaultPatterns)) {
             throw tooManyAttributes();
@@ -258,7 +257,7 @@
      * @return the defaultexclusions value.
      */
     public synchronized boolean getDefaultexcludes() {
-        return (isReference())
+        return isReference()
             ? getRef().getDefaultexcludes() : useDefaultExcludes;
     }
 
@@ -280,7 +279,7 @@
      * collection is case-sensitive.
      */
     public synchronized boolean isCaseSensitive() {
-        return (isReference())
+        return isReference()
             ? getRef().isCaseSensitive() : caseSensitive;
     }
 
@@ -302,7 +301,7 @@
      *         should be followed.
      */
     public synchronized boolean isFollowSymlinks() {
-        return (isReference())
+        return isReference()
             ? getRef().isFollowSymlinks() : followSymlinks;
     }
 
@@ -310,6 +309,7 @@
      * Fulfill the ResourceCollection contract.
      * @return an Iterator of Resources.
      */
+    @Override
     public synchronized Iterator<Resource> iterator() {
         if (isReference()) {
             return getRef().iterator();
@@ -319,7 +319,7 @@
         int fct = ds.getIncludedFilesCount();
         int dct = ds.getIncludedDirsCount();
         if (fct + dct == 0) {
-            return EMPTY_ITERATOR;
+            return Collections.emptyIterator();
         }
         FileResourceIterator result = new FileResourceIterator(getProject());
         if (fct > 0) {
@@ -335,6 +335,7 @@
      * Fulfill the ResourceCollection contract.
      * @return number of elements as int.
      */
+    @Override
     public synchronized int size() {
         if (isReference()) {
             return getRef().size();
@@ -354,15 +355,8 @@
             return getRef().hasPatterns();
         }
         dieOnCircularReference();
-        if (hasPatterns(defaultPatterns)) {
-            return true;
-        }
-        for (PatternSet patternSet : additionalPatterns) {
-            if (hasPatterns(patternSet)) {
-                return true;
-            }
-        }
-        return false;
+        return hasPatterns(defaultPatterns)
+            || additionalPatterns.stream().anyMatch(this::hasPatterns);
     }
 
     /**
@@ -370,6 +364,7 @@
      *
      * @param selector the new <code>FileSelector</code> to add.
      */
+    @Override
     public synchronized void appendSelector(FileSelector selector) {
         if (isReference()) {
             throw noChildrenAllowed();
@@ -382,22 +377,13 @@
      * Format this Files collection as a String.
      * @return a descriptive <code>String</code>.
      */
+    @Override
     public String toString() {
         if (isReference()) {
             return getRef().toString();
         }
-        Iterator<Resource> i = iterator();
-        if (!i.hasNext()) {
-            return "";
-        }
-        StringBuffer sb = new StringBuffer();
-        while (i.hasNext()) {
-            if (sb.length() > 0) {
-                sb.append(File.pathSeparatorChar);
-            }
-            sb.append(i.next());
-        }
-        return sb.toString();
+        return isEmpty() ? "" : stream().map(Object::toString)
+            .collect(Collectors.joining(File.pathSeparator));
     }
 
     /**
@@ -405,7 +391,8 @@
      * (the list of selectors is a shallow clone of this instance's list).
      * @return a cloned Object.
      */
-    public synchronized Object clone() {
+    @Override
+    public synchronized Files clone() {
         if (isReference()) {
             return getRef().clone();
         }
@@ -451,11 +438,7 @@
         dieOnCircularReference();
         PatternSet ps = new PatternSet();
         ps.append(defaultPatterns, p);
-        final int count = additionalPatterns.size();
-        for (int i = 0; i < count; i++) {
-            Object o = additionalPatterns.elementAt(i);
-            ps.append((PatternSet) o, p);
-        }
+        additionalPatterns.forEach(pat -> ps.append(pat, p));
         return ps;
     }
 
@@ -464,6 +447,7 @@
      * @return true indicating that all elements of a Files collection
      *              will be FileResources.
      */
+    @Override
     public boolean isFilesystemOnly() {
         return true;
     }
diff --git a/src/main/org/apache/tools/ant/types/resources/First.java b/src/main/org/apache/tools/ant/types/resources/First.java
index ea9e7d0..05cf1e2 100644
--- a/src/main/org/apache/tools/ant/types/resources/First.java
+++ b/src/main/org/apache/tools/ant/types/resources/First.java
@@ -17,10 +17,8 @@
  */
 package org.apache.tools.ant.types.resources;
 
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.types.Resource;
 
@@ -35,14 +33,10 @@
      * Take the first <code>count</code> elements.
      * @return a Collection of Resources.
      */
+    @Override
     protected Collection<Resource> getCollection() {
-        int ct = getValidCount();
-        Iterator<Resource> iter = getResourceCollection().iterator();
-        List<Resource> al = new ArrayList<Resource>(ct);
-        for (int i = 0; i < ct && iter.hasNext(); i++) {
-            al.add(iter.next());
-        }
-        return al;
+        return getResourceCollection().stream().limit(getValidCount())
+            .collect(Collectors.toList());
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/GZipResource.java b/src/main/org/apache/tools/ant/types/resources/GZipResource.java
index 3f95a69..e37b539 100644
--- a/src/main/org/apache/tools/ant/types/resources/GZipResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/GZipResource.java
@@ -23,6 +23,8 @@
 import java.util.zip.GZIPInputStream;
 import java.util.zip.GZIPOutputStream;
 
+import org.apache.tools.ant.types.ResourceCollection;
+
 /**
  * A GZip compressed resource.
  *
@@ -41,7 +43,7 @@
      * Constructor with another resource to wrap.
      * @param other the resource to wrap.
      */
-    public GZipResource(org.apache.tools.ant.types.ResourceCollection other) {
+    public GZipResource(ResourceCollection other) {
         super(other);
     }
 
@@ -51,6 +53,7 @@
      * @return the wrapped stream.
      * @throws IOException if there is a problem.
      */
+    @Override
     protected InputStream wrapStream(InputStream in) throws IOException {
         return new GZIPInputStream(in);
     }
@@ -61,7 +64,8 @@
      * @return the wrapped stream.
      * @throws IOException if there is a problem.
      */
-     protected OutputStream wrapStream(OutputStream out) throws IOException {
+    @Override
+    protected OutputStream wrapStream(OutputStream out) throws IOException {
         return new GZIPOutputStream(out);
     }
 
@@ -69,6 +73,7 @@
      * Get the name of the compression method.
      * @return the string "GZip".
      */
+    @Override
     protected String getCompressionName() {
         return "GZip";
     }
diff --git a/src/main/org/apache/tools/ant/types/resources/Intersect.java b/src/main/org/apache/tools/ant/types/resources/Intersect.java
index cdbeed0..667d259 100644
--- a/src/main/org/apache/tools/ant/types/resources/Intersect.java
+++ b/src/main/org/apache/tools/ant/types/resources/Intersect.java
@@ -22,11 +22,14 @@
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.types.ResourceCollection;
 
+
 /**
  * ResourceCollection representing the intersection
  * of multiple nested ResourceCollections.
@@ -38,27 +41,23 @@
      * Calculate the intersection of the nested ResourceCollections.
      * @return a Collection of Resources.
      */
+    @Override
     protected Collection<Resource> getCollection() {
         List<ResourceCollection> rcs = getResourceCollections();
         int size = rcs.size();
         if (size < 2) {
-            throw new BuildException("The intersection of " + size
-                + " resource collection" + ((size == 1) ? "" : "s")
-                + " is undefined.");
+            throw new BuildException(
+                "The intersection of %d resource %s is undefined.", size,
+                size == 1 ? "collection" : "collections");
         }
+
+        final Function<ResourceCollection, Set<Resource>> toSet =
+            c -> c.stream().collect(Collectors.toSet());
+
         Iterator<ResourceCollection> rc = rcs.iterator();
-        Set<Resource> s = new LinkedHashSet<Resource>(collect(rc.next()));
-        while (rc.hasNext()) {
-            s.retainAll(collect(rc.next()));
-        }
+        Set<Resource> s = new LinkedHashSet<>(toSet.apply(rc.next()));
+        rc.forEachRemaining(c -> s.retainAll(toSet.apply(c)));
         return s;
     }
 
-    private Set<Resource> collect(ResourceCollection rc) {
-        Set<Resource> result = new LinkedHashSet<Resource>();
-        for (Resource r : rc) {
-            result.add(r);
-        }
-        return result;
-    }
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/JavaConstantResource.java b/src/main/org/apache/tools/ant/types/resources/JavaConstantResource.java
index e8c8f02..9ce721b 100644
--- a/src/main/org/apache/tools/ant/types/resources/JavaConstantResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/JavaConstantResource.java
@@ -36,6 +36,7 @@
      * @return an open input stream for the resource
      * @throws IOException if an error occurs.
      */
+    @Override
     protected InputStream openInputStream(ClassLoader cl) throws IOException {
         String constant = getName();
         if (constant == null) {
diff --git a/src/main/org/apache/tools/ant/types/resources/JavaResource.java b/src/main/org/apache/tools/ant/types/resources/JavaResource.java
index a927d3f..d6467e8 100644
--- a/src/main/org/apache/tools/ant/types/resources/JavaResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/JavaResource.java
@@ -79,20 +79,20 @@
      * Get the URL represented by this Resource.
      * @since Ant 1.8.0
      */
+    @Override
     public URL getURL() {
         if (isReference()) {
-            return ((JavaResource) getCheckedRef()).getURL();
+            return getCheckedRef().getURL();
         }
         AbstractClasspathResource.ClassLoaderWithFlag classLoader =
             getClassLoader();
         if (classLoader.getLoader() == null) {
             return ClassLoader.getSystemResource(getName());
-        } else {
-            try {
-                return classLoader.getLoader().getResource(getName());
-            } finally {
-                classLoader.cleanup();
-            }
+        }
+        try {
+            return classLoader.getLoader().getResource(getName());
+        } finally {
+            classLoader.cleanup();
         }
     }
 
@@ -103,9 +103,10 @@
      * JavaResource is less than, equal to, or greater than the
      * specified Resource.
      */
+    @Override
     public int compareTo(Resource another) {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).compareTo(another);
+            return getCheckedRef().compareTo(another);
         }
         if (another.getClass().equals(getClass())) {
             JavaResource otherjr = (JavaResource) another;
@@ -138,4 +139,8 @@
         return super.compareTo(another);
     }
 
+    @Override
+    protected JavaResource getCheckedRef() {
+        return (JavaResource) super.getCheckedRef();
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/Last.java b/src/main/org/apache/tools/ant/types/resources/Last.java
index 312271b..575e768 100644
--- a/src/main/org/apache/tools/ant/types/resources/Last.java
+++ b/src/main/org/apache/tools/ant/types/resources/Last.java
@@ -17,10 +17,9 @@
  */
 package org.apache.tools.ant.types.resources;
 
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Iterator;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -38,33 +37,29 @@
      * Take the last <code>count</code> elements.
      * @return a Collection of Resources.
      */
+    @Override
     protected Collection<Resource> getCollection() {
         int count = getValidCount();
         ResourceCollection rc = getResourceCollection();
-        int i = count;
-        Iterator<Resource> iter = rc.iterator();
         int size = rc.size();
-        for (; i < size; i++) {
-            iter.next();
-        }
+        int skip = Math.max(0, size - count);
 
-        List<Resource> al = new ArrayList<Resource>(count);
-        for (; iter.hasNext(); i++) {
-            al.add(iter.next());
-        }
-        int found = al.size();
+        List<Resource> result =
+            rc.stream().skip(skip).collect(Collectors.toList());
+
+        int found = result.size();
         if (found == count || (size < count && found == size)) {
-            return al;
+            return result;
         }
-
         //mismatch:
-        String msg = "Resource collection " + rc + " reports size " + size
-            + " but returns " + i + " elements.";
+        String msg = String.format(
+            "Resource collection %s reports size %d but returns %d elements.",
+            rc, size, found + skip);
 
         //size was understated -> too many results; warn and continue:
         if (found > count) {
             log(msg, Project.MSG_WARN);
-            return al.subList(found - count, found);
+            return result.subList(found - count, found);
         }
         //size was overstated; we missed some and are now in error-land:
         throw new BuildException(msg);
diff --git a/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java b/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java
index bdcc95d..b470403 100644
--- a/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java
+++ b/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java
@@ -21,6 +21,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.function.Supplier;
 
 import org.apache.tools.ant.types.Resource;
 
@@ -32,24 +33,23 @@
         AbstractResourceCollectionWrapper {
 
     /** List of cached resources */
-    private final List<Resource> cachedResources = new ArrayList<Resource>();
+    private final List<Resource> cachedResources = new ArrayList<>();
 
-    private FilteringIterator filteringIterator;
+    private Iterator<Resource> filteringIterator;
+
+    private final Supplier<Iterator<Resource>> filteringIteratorSupplier =
+        () -> new FilteringIterator(getResourceCollection().iterator());
 
     @Override
     protected Iterator<Resource> createIterator() {
-        Iterator<Resource> iterator;
         if (isCache()) {
             if (filteringIterator == null) {
                 // no worry of thread safety here, see function's contract
-                filteringIterator = new FilteringIterator(
-                        getResourceCollection().iterator());
+                filteringIterator = filteringIteratorSupplier.get();
             }
-            iterator = new CachedIterator(filteringIterator);
-        } else {
-            iterator = new FilteringIterator(getResourceCollection().iterator());
+            return new CachedIterator(filteringIterator);
         }
-        return iterator;
+        return filteringIteratorSupplier.get();
     }
 
     @Override
@@ -84,10 +84,11 @@
 
         protected final Iterator<Resource> it;
 
-        public FilteringIterator(final Iterator<Resource> it) {
+        FilteringIterator(final Iterator<Resource> it) {
             this.it = it;
         }
 
+        @Override
         public boolean hasNext() {
             if (ended) {
                 return false;
@@ -105,6 +106,7 @@
             return true;
         }
 
+        @Override
         public Resource next() {
             if (!hasNext()) {
                 throw new UnsupportedOperationException();
@@ -114,9 +116,6 @@
             return r;
         }
 
-        public void remove() {
-            throw new UnsupportedOperationException();
-        }
     }
 
     /**
@@ -125,7 +124,7 @@
      */
     private class CachedIterator implements Iterator<Resource> {
 
-        int cusrsor = 0;
+        int cursor = 0;
 
         private final Iterator<Resource> it;
 
@@ -140,10 +139,11 @@
             this.it = it;
         }
 
+        @Override
         public boolean hasNext() {
             synchronized (cachedResources) {
                 // have we already cached the next entry ?
-                if (cachedResources.size() > cusrsor) {
+                if (cachedResources.size() > cursor) {
                     return true;
                 }
                 // does the wrapped iterator any more resource ?
@@ -157,6 +157,7 @@
             return true;
         }
 
+        @Override
         public Resource next() {
             // first check that we have some to deliver
             if (!hasNext()) {
@@ -165,10 +166,11 @@
             synchronized (cachedResources) {
                 // return the cached entry as hasNext should have put one for
                 // this iterator
-                return cachedResources.get(cusrsor++);
+                return cachedResources.get(cursor++);
             }
         }
 
+        @Override
         public void remove() {
             throw new UnsupportedOperationException();
         }
diff --git a/src/main/org/apache/tools/ant/types/resources/LogOutputResource.java b/src/main/org/apache/tools/ant/types/resources/LogOutputResource.java
index 9b48658..a13fe17 100644
--- a/src/main/org/apache/tools/ant/types/resources/LogOutputResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/LogOutputResource.java
@@ -55,6 +55,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public OutputStream getAppendOutputStream() throws IOException {
         return outputStream;
     }
@@ -62,6 +63,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public OutputStream getOutputStream() throws IOException {
         return outputStream;
     }
diff --git a/src/main/org/apache/tools/ant/types/resources/MappedResourceCollection.java b/src/main/org/apache/tools/ant/types/resources/MappedResourceCollection.java
index 9df69cf..c870cc1 100644
--- a/src/main/org/apache/tools/ant/types/resources/MappedResourceCollection.java
+++ b/src/main/org/apache/tools/ant/types/resources/MappedResourceCollection.java
@@ -18,10 +18,11 @@
 package org.apache.tools.ant.types.resources;
 
 import java.io.File;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.Stack;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -122,10 +123,10 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public boolean isFilesystemOnly() {
         if (isReference()) {
-            return ((MappedResourceCollection) getCheckedRef())
-                .isFilesystemOnly();
+            return getCheckedRef().isFilesystemOnly();
         }
         checkInitialized();
         return false;
@@ -134,9 +135,10 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public int size() {
         if (isReference()) {
-            return ((MappedResourceCollection) getCheckedRef()).size();
+            return getCheckedRef().size();
         }
         checkInitialized();
         return cacheCollection().size();
@@ -145,9 +147,10 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public Iterator<Resource> iterator() {
         if (isReference()) {
-            return ((MappedResourceCollection) getCheckedRef()).iterator();
+            return getCheckedRef().iterator();
         }
         checkInitialized();
         return cacheCollection().iterator();
@@ -157,6 +160,7 @@
      * Overrides the base version.
      * @param r the Reference to set.
      */
+    @Override
     public void setRefid(Reference r) {
         if (nested != null || mapper != null) {
             throw tooManyAttributes();
@@ -168,7 +172,8 @@
      * Implement clone.  The nested resource collection and mapper are copied.
      * @return a cloned instance.
      */
-    public Object clone() {
+    @Override
+    public MappedResourceCollection clone() {
         try {
             MappedResourceCollection c =
                 (MappedResourceCollection) super.clone();
@@ -188,6 +193,7 @@
      * @param p   the project to use to dereference the references.
      * @throws BuildException on error.
      */
+    @Override
     protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
@@ -209,8 +215,9 @@
 
     private void checkInitialized() {
         if (nested == null) {
-            throw new BuildException("A nested resource collection element is"
-                                     + " required", getLocation());
+            throw new BuildException(
+                "A nested resource collection element is required",
+                getLocation());
         }
         dieOnCircularReference();
     }
@@ -223,46 +230,36 @@
     }
 
     private Collection<Resource> getCollection() {
-        Collection<Resource> collected = new ArrayList<Resource>();
         FileNameMapper m =
-            mapper != null ? mapper.getImplementation() : new IdentityMapper();
-        for (Resource r : nested) {
-            if (enableMultipleMappings) {
-                String[] n = m.mapFileName(r.getName());
-                if (n != null) {
-                    for (int i = 0; i < n.length; i++) {
-                        collected.add(new MappedResource(r,
-                                                         new MergingMapper(n[i]))
-                                      );
-                    }
-                }
-            } else {
-                collected.add(new MappedResource(r, m));
-            }
+            mapper == null ? new IdentityMapper() : mapper.getImplementation();
+
+        Stream<MappedResource> stream;
+        if (enableMultipleMappings) {
+            stream = nested.stream()
+                .flatMap(r -> Stream.of(m.mapFileName(r.getName()))
+                    .map(MergingMapper::new)
+                    .map(mm -> new MappedResource(r, mm)));
+        } else {
+            stream = nested.stream().map(r -> new MappedResource(r, m));
         }
-        return collected;
+        return stream.collect(Collectors.toList());
     }
 
     /**
      * Format this resource collection as a String.
      * @return a descriptive <code>String</code>.
      */
+    @Override
     public String toString() {
         if (isReference()) {
             return getCheckedRef().toString();
         }
-        Iterator<Resource> i = iterator();
-        if (!i.hasNext()) {
-            return "";
-        }
-        StringBuffer sb = new StringBuffer();
-        while (i.hasNext()) {
-            if (sb.length() > 0) {
-                sb.append(File.pathSeparatorChar);
-            }
-            sb.append(i.next());
-        }
-        return sb.toString();
+        return isEmpty() ? "" : stream().map(Object::toString)
+            .collect(Collectors.joining(File.pathSeparator));
     }
 
+    @Override
+    protected MappedResourceCollection getCheckedRef() {
+        return (MappedResourceCollection) super.getCheckedRef();
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/MultiRootFileSet.java b/src/main/org/apache/tools/ant/types/resources/MultiRootFileSet.java
index 1161558..d2f3eb6 100644
--- a/src/main/org/apache/tools/ant/types/resources/MultiRootFileSet.java
+++ b/src/main/org/apache/tools/ant/types/resources/MultiRootFileSet.java
@@ -112,21 +112,21 @@
      * @return the cloned MultiRootFileSet.
      */
     @Override
-    public Object clone() {
+    public MultiRootFileSet clone() {
         if (isReference()) {
             return ((MultiRootFileSet) getRef(getProject())).clone();
-        } else {
-            final MultiRootFileSet fs = (MultiRootFileSet) super.clone();
-            fs.baseDirs = new ArrayList<File>(baseDirs);
-            fs.union = null;
-            return fs;
         }
+        final MultiRootFileSet fs = (MultiRootFileSet) super.clone();
+        fs.baseDirs = new ArrayList<>(baseDirs);
+        fs.union = null;
+        return fs;
     }
 
     /**
      * Fulfill the ResourceCollection contract.
      * @return an Iterator of Resources.
      */
+    @Override
     public Iterator<Resource> iterator() {
         if (isReference()) {
             return ((MultiRootFileSet) getRef(getProject())).iterator();
@@ -138,6 +138,7 @@
      * Fulfill the ResourceCollection contract.
      * @return number of elements as int.
      */
+    @Override
     public int size() {
         if (isReference()) {
             return ((MultiRootFileSet) getRef(getProject())).size();
@@ -149,6 +150,7 @@
      * Always returns true.
      * @return true indicating that all elements will be FileResources.
      */
+    @Override
     public boolean isFilesystemOnly() {
         return true;
     }
@@ -202,10 +204,12 @@
             setDir(dir);
         }
 
+        @Override
         public boolean isFilesystemOnly() {
             return true;
         }
 
+        @Override
         public Iterator<Resource> iterator() {
             final DirectoryScanner ds = getDirectoryScanner(getProject());
             String[] names = type == SetType.file
@@ -222,6 +226,7 @@
                                             names);
         }
 
+        @Override
         public int size() {
             final DirectoryScanner ds = getDirectoryScanner(getProject());
             int count = type == SetType.file
diff --git a/src/main/org/apache/tools/ant/types/resources/PropertyResource.java b/src/main/org/apache/tools/ant/types/resources/PropertyResource.java
index a7cecb4..d72881d 100644
--- a/src/main/org/apache/tools/ant/types/resources/PropertyResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/PropertyResource.java
@@ -39,6 +39,7 @@
         = Resource.getMagicNumber("PropertyResource".getBytes());
 
     private static final InputStream UNSET = new InputStream() {
+        @Override
         public int read() {
             return -1;
         }
@@ -66,7 +67,7 @@
      */
     public String getValue() {
         if (isReference()) {
-            return ((PropertyResource) getCheckedRef()).getValue();
+            return getCheckedRef().getValue();
         }
         Project p = getProject();
         return p == null ? null : p.getProperty(getName());
@@ -79,7 +80,7 @@
      */
     public Object getObjectValue() {
         if (isReference()) {
-            return ((PropertyResource) getCheckedRef()).getObjectValue();
+            return getCheckedRef().getObjectValue();
         }
         Project p = getProject();
         return p == null ? null : PropertyHelper.getProperty(p, getName());
@@ -89,6 +90,7 @@
      * Find out whether this Resource exists.
      * @return true if the Property is set, false otherwise.
      */
+    @Override
     public boolean isExists() {
         if (isReferenceOrProxy()) {
             return getReferencedOrProxied().isExists();
@@ -101,6 +103,7 @@
      * @return the size, as a long, 0 if the Resource does not exist (for
      *         compatibility with java.io.File), or UNKNOWN_SIZE if not known.
      */
+    @Override
     public long getSize() {
         if (isReferenceOrProxy()) {
             return getReferencedOrProxied().getSize();
@@ -115,6 +118,7 @@
      * @param o object to compare
      * @return true if equal to o
      */
+    @Override
     public boolean equals(Object o) {
         if (super.equals(o)) {
             return true;
@@ -126,6 +130,7 @@
      * Get the hash code for this Resource.
      * @return hash code as int.
      */
+    @Override
     public int hashCode() {
         if (isReferenceOrProxy()) {
             return getReferencedOrProxied().hashCode();
@@ -136,6 +141,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public String toString() {
         if (isReferenceOrProxy()) {
             return getReferencedOrProxied().toString();
@@ -151,6 +157,7 @@
      * @throws UnsupportedOperationException if InputStreams are not
      *         supported for this Resource type.
      */
+    @Override
     public InputStream getInputStream() throws IOException {
         if (isReferenceOrProxy()) {
             return getReferencedOrProxied().getInputStream();
@@ -167,6 +174,7 @@
      * @throws UnsupportedOperationException if OutputStreams are not
      *         supported for this Resource type.
      */
+    @Override
     public OutputStream getOutputStream() throws IOException {
         if (isReferenceOrProxy()) {
             return getReferencedOrProxied().getOutputStream();
@@ -194,7 +202,7 @@
      */
     protected Resource getReferencedOrProxied() {
         if (isReference()) {
-            return (Resource) getCheckedRef(Resource.class, "resource");
+            return getCheckedRef(Resource.class, "resource");
         }
         Object o = getObjectValue();
         if (o instanceof Resource) {
@@ -203,4 +211,9 @@
         throw new IllegalStateException(
                 "This PropertyResource does not reference or proxy another Resource");
     }
+
+    @Override
+    protected PropertyResource getCheckedRef() {
+        return (PropertyResource) super.getCheckedRef();
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/ResourceDecorator.java b/src/main/org/apache/tools/ant/types/resources/ResourceDecorator.java
index 2d87fb1..ace0de2 100644
--- a/src/main/org/apache/tools/ant/types/resources/ResourceDecorator.java
+++ b/src/main/org/apache/tools/ant/types/resources/ResourceDecorator.java
@@ -59,12 +59,12 @@
     public final void addConfigured(ResourceCollection a) {
         checkChildrenAllowed();
         if (resource != null) {
-            throw new BuildException("you must not specify more than one"
-                                     + " resource");
+            throw new BuildException(
+                "you must not specify more than one resource");
         }
         if (a.size() != 1) {
-            throw new BuildException("only single argument resource collections"
-                                     + " are supported");
+            throw new BuildException(
+                "only single argument resource collections are supported");
         }
         setChecked(false);
         resource = a.iterator().next();
@@ -238,6 +238,7 @@
      * @param name not used.
      * @throws BuildException always.
      */
+    @Override
     public void setName(String name) throws BuildException {
         throw new BuildException("you can't change the name of a "
                                  + getDataTypeName());
@@ -247,6 +248,7 @@
      * Set the exists attribute.
      * @param exists if true, this resource exists.
      */
+    @Override
     public void setExists(boolean exists) {
         throw new BuildException("you can't change the exists state of a "
                                  + getDataTypeName());
@@ -257,6 +259,7 @@
      * @param lastmodified not used.
      * @throws BuildException always.
      */
+    @Override
     public void setLastModified(long lastmodified) throws BuildException {
         throw new BuildException("you can't change the timestamp of a "
                                  + getDataTypeName());
@@ -267,6 +270,7 @@
      * @param directory not used.
      * @throws BuildException always.
      */
+    @Override
     public void setDirectory(boolean directory) throws BuildException {
         throw new BuildException("you can't change the directory state of a "
                                  + getDataTypeName());
@@ -277,6 +281,7 @@
      * @param size not used.
      * @throws BuildException always.
      */
+    @Override
     public void setSize(long size) throws BuildException {
         throw new BuildException("you can't change the size of a "
                                  + getDataTypeName());
diff --git a/src/main/org/apache/tools/ant/types/resources/ResourceList.java b/src/main/org/apache/tools/ant/types/resources/ResourceList.java
index b24277d..aee4a78 100644
--- a/src/main/org/apache/tools/ant/types/resources/ResourceList.java
+++ b/src/main/org/apache/tools/ant/types/resources/ResourceList.java
@@ -22,6 +22,7 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Stack;
@@ -36,7 +37,6 @@
 import org.apache.tools.ant.types.Reference;
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.types.ResourceCollection;
-import org.apache.tools.ant.util.FileUtils;
 
 /**
  * Reads a resource as text document and creates a resource for each
@@ -44,8 +44,8 @@
  * @since Ant 1.8.0
  */
 public class ResourceList extends DataType implements ResourceCollection {
-    private final Vector<FilterChain> filterChains = new Vector<FilterChain>();
-    private final ArrayList<ResourceCollection> textDocuments = new ArrayList<ResourceCollection>();
+    private final Vector<FilterChain> filterChains = new Vector<>();
+    private final ArrayList<ResourceCollection> textDocuments = new ArrayList<>();
     private final Union cachedResources = new Union();
     private volatile boolean cached = false;
     private String encoding = null;
@@ -105,11 +105,12 @@
      *
      * @param r Reference
      */
+    @Override
     public void setRefid(Reference r) throws BuildException {
         if (encoding != null) {
             throw tooManyAttributes();
         }
-        if (filterChains.size() > 0 || textDocuments.size() > 0) {
+        if (!(filterChains.isEmpty() && textDocuments.isEmpty())) {
             throw noChildrenAllowed();
         }
         super.setRefid(r);
@@ -122,9 +123,10 @@
      *
      * @return a "fail-fast" Iterator.
      */
+    @Override
     public final synchronized Iterator<Resource> iterator() {
         if (isReference()) {
-            return ((ResourceList) getCheckedRef()).iterator();
+            return getCheckedRef().iterator();
         }
         return cache().iterator();
     }
@@ -134,9 +136,10 @@
      *
      * @return number of elements as int.
      */
+    @Override
     public synchronized int size() {
         if (isReference()) {
-            return ((ResourceList) getCheckedRef()).size();
+            return getCheckedRef().size();
         }
         return cache().size();
     }
@@ -146,9 +149,10 @@
      *
      * @return whether this is a filesystem-only resource collection.
      */
+    @Override
     public synchronized boolean isFilesystemOnly() {
         if (isReference()) {
-            return ((ResourceList) getCheckedRef()).isFilesystemOnly();
+            return getCheckedRef().isFilesystemOnly();
         }
         return cache().isFilesystemOnly();
     }
@@ -161,6 +165,7 @@
      * @param p   the project to use to dereference the references.
      * @throws BuildException on error.
      */
+    @Override
     protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
@@ -181,65 +186,53 @@
         }
     }
 
+    @Override
+    protected ResourceList getCheckedRef() {
+        return (ResourceList) super.getCheckedRef();
+    }
+
     private synchronized ResourceCollection cache() {
         if (!cached) {
             dieOnCircularReference();
-            for (ResourceCollection rc : textDocuments) {
-                for (Resource r : rc) {
-                    cachedResources.add(read(r));
-                }
-            }
+            textDocuments.stream().flatMap(ResourceCollection::stream)
+                .map(this::read).forEach(cachedResources::add);
             cached = true;
         }
         return cachedResources;
     }
 
     private ResourceCollection read(Resource r) {
-        BufferedInputStream bis = null;
-        try {
-            bis = new BufferedInputStream(r.getInputStream());
-            Reader input = null;
-            if (encoding == null) {
-                input = new InputStreamReader(bis);
-            } else {
-                input = new InputStreamReader(bis, encoding);
-            }
-            ChainReaderHelper crh = new ChainReaderHelper();
-            crh.setPrimaryReader(input);
-            crh.setFilterChains(filterChains);
-            crh.setProject(getProject());
+        try (BufferedReader reader = new BufferedReader(open(r))) {
             Union streamResources = new Union();
-            BufferedReader reader = new BufferedReader(crh.getAssembledReader());
-            try {
-                streamResources.setCache(true);
-
-                String line = null;
-                while ((line = reader.readLine()) != null) {
-                    streamResources.add(parse(line));
-                }
-            } finally {
-                reader.close();
-            }
-
+            streamResources.setCache(true);
+            reader.lines().map(this::parse).forEach(streamResources::add);
             return streamResources;
         } catch (final IOException ioe) {
             throw new BuildException("Unable to read resource " + r.getName()
                                      + ": " + ioe, ioe, getLocation());
-        } finally {
-            FileUtils.close(bis);
         }
     }
 
+    private Reader open(Resource r) throws IOException {
+        ChainReaderHelper crh = new ChainReaderHelper();
+        crh.setPrimaryReader(new InputStreamReader(
+            new BufferedInputStream(r.getInputStream()), encoding == null
+                ? Charset.defaultCharset() : Charset.forName(encoding)));
+        crh.setFilterChains(filterChains);
+        crh.setProject(getProject());
+        return crh.getAssembledReader();
+    }
+
     private Resource parse(final String line) {
-        PropertyHelper propertyHelper
-            = (PropertyHelper) PropertyHelper.getPropertyHelper(getProject());
+        PropertyHelper propertyHelper =
+            PropertyHelper.getPropertyHelper(getProject());
         Object expanded = propertyHelper.parseProperties(line);
         if (expanded instanceof Resource) {
             return (Resource) expanded;
         }
         String expandedLine = expanded.toString();
-        int colon = expandedLine.indexOf(":");
-        if (colon != -1) {
+        int colon = expandedLine.indexOf(':');
+        if (colon >= 0) {
             // could be an URL or an absolute file on an OS with drives
             try {
                 return new URLResource(expandedLine);
@@ -252,4 +245,5 @@
         }
         return new FileResource(getProject(), expandedLine);
     }
+
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/Resources.java b/src/main/org/apache/tools/ant/types/resources/Resources.java
index 1e029b2..4b3d4dd 100644
--- a/src/main/org/apache/tools/ant/types/resources/Resources.java
+++ b/src/main/org/apache/tools/ant/types/resources/Resources.java
@@ -20,13 +20,14 @@
 
 import java.io.File;
 import java.util.AbstractCollection;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.Stack;
-import java.util.Vector;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -43,12 +44,15 @@
 public class Resources extends DataType implements ResourceCollection {
     /** static empty ResourceCollection */
     public static final ResourceCollection NONE = new ResourceCollection() {
+        @Override
         public boolean isFilesystemOnly() {
             return true;
         }
+        @Override
         public Iterator<Resource> iterator() {
             return EMPTY_ITERATOR;
         }
+        @Override
         public int size() {
             return 0;
         }
@@ -56,12 +60,15 @@
 
     /** static empty Iterator */
     public static final Iterator<Resource> EMPTY_ITERATOR = new Iterator<Resource>() {
+        @Override
         public Resource next() {
             throw new NoSuchElementException();
         }
+        @Override
         public boolean hasNext() {
             return false;
         }
+        @Override
         public void remove() {
             throw new UnsupportedOperationException();
         }
@@ -72,9 +79,11 @@
 
         MyCollection() {
         }
+        @Override
         public int size() {
             return getCache().size();
         }
+        @Override
         public Iterator<Resource> iterator() {
             return getCache().iterator();
         }
@@ -92,27 +101,30 @@
             private Iterator<ResourceCollection> rci = getNested().iterator();
             private Iterator<Resource> ri = null;
 
+            @Override
             public boolean hasNext() {
                 boolean result = ri != null && ri.hasNext();
                 while (!result && rci.hasNext()) {
-                    ri = ((ResourceCollection) rci.next()).iterator();
+                    ri = rci.next().iterator();
                     result = ri.hasNext();
                 }
                 return result;
             }
+            @Override
             public Resource next() {
                 if (!hasNext()) {
                     throw new NoSuchElementException();
                 }
                 return ri.next();
             }
+            @Override
             public void remove() {
                 throw new UnsupportedOperationException();
             }
         }
     }
 
-    private Vector<ResourceCollection> rc;
+    private List<ResourceCollection> rc;
     private Collection<Resource> coll;
     private boolean cache = false;
 
@@ -152,7 +164,7 @@
             return;
         }
         if (rc == null) {
-            rc = new Vector<ResourceCollection>();
+            rc = Collections.synchronizedList(new ArrayList<>());
         }
         rc.add(c);
         invalidateExistingIterators();
@@ -164,6 +176,7 @@
      * Fulfill the ResourceCollection contract.
      * @return an Iterator of Resources.
      */
+    @Override
     public synchronized Iterator<Resource> iterator() {
         if (isReference()) {
             return getRef().iterator();
@@ -176,6 +189,7 @@
      * Fulfill the ResourceCollection contract.
      * @return number of elements as int.
      */
+    @Override
     public synchronized int size() {
         if (isReference()) {
             return getRef().size();
@@ -188,24 +202,21 @@
      * Fulfill the ResourceCollection contract.
      * @return true if all Resources represent files.
      */
+    @Override
     public boolean isFilesystemOnly() {
         if (isReference()) {
             return getRef().isFilesystemOnly();
         }
         validate();
-
-        for (Iterator<ResourceCollection> i = getNested().iterator(); i.hasNext();) {
-            if (!i.next().isFilesystemOnly()) {
-                return false;
-            }
-        }
-        return true;
+        return getNested().stream()
+            .allMatch(ResourceCollection::isFilesystemOnly);
     }
 
     /**
      * Format this <code>Resources</code> as a String.
      * @return a descriptive <code>String</code>.
      */
+    @Override
     public synchronized String toString() {
         if (isReference()) {
             return getCheckedRef().toString();
@@ -214,14 +225,8 @@
         if (coll == null || coll.isEmpty()) {
             return "";
         }
-        StringBuffer sb = new StringBuffer();
-        for (Resource r : coll) {
-            if (sb.length() > 0) {
-                sb.append(File.pathSeparatorChar);
-            }
-            sb.append(r);
-        }
-        return sb.toString();
+        return coll.stream().map(Object::toString)
+            .collect(Collectors.joining(File.pathSeparator));
     }
 
     /**
@@ -231,6 +236,7 @@
      * @param p   the project to use to dereference the references.
      * @throws BuildException on error.
      */
+    @Override
     protected void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
@@ -260,8 +266,7 @@
      * @return the referenced ResourceCollection.
      */
     private ResourceCollection getRef() {
-        return (ResourceCollection) getCheckedRef(
-            ResourceCollection.class, "ResourceCollection");
+        return getCheckedRef(ResourceCollection.class, "ResourceCollection");
     }
 
     private synchronized void validate() {
diff --git a/src/main/org/apache/tools/ant/types/resources/Restrict.java b/src/main/org/apache/tools/ant/types/resources/Restrict.java
index 2ea1a86..04256f0 100644
--- a/src/main/org/apache/tools/ant/types/resources/Restrict.java
+++ b/src/main/org/apache/tools/ant/types/resources/Restrict.java
@@ -39,13 +39,9 @@
         /**
          * Restrict the nested ResourceCollection based on the nested selectors.
          */
+        @Override
         protected boolean filterResource(Resource r) {
-            for (Iterator<ResourceSelector> i = getSelectors(); i.hasNext();) {
-                if (!i.next().isSelected(r)) {
-                    return true;
-                }
-            }
-            return false;
+            return getResourceSelectors().stream().anyMatch(rsel -> !rsel.isSelected(r));
         }
     };
 
@@ -84,6 +80,7 @@
      * Add a ResourceSelector.
      * @param s the ResourceSelector to add.
      */
+    @Override
     public synchronized void add(ResourceSelector s) {
         if (s == null) {
             return;
@@ -96,9 +93,10 @@
      * Fulfill the ResourceCollection contract.
      * @return an Iterator of Resources.
      */
+    @Override
     public final synchronized Iterator<Resource> iterator() {
         if (isReference()) {
-            return ((Restrict) getCheckedRef()).iterator();
+            return getCheckedRef().iterator();
         }
         dieOnCircularReference();
         return w.iterator();
@@ -108,9 +106,10 @@
      * Fulfill the ResourceCollection contract.
      * @return number of elements as int.
      */
+    @Override
     public synchronized int size() {
         if (isReference()) {
-            return ((Restrict) getCheckedRef()).size();
+            return getCheckedRef().size();
         }
         dieOnCircularReference();
         return w.size();
@@ -120,9 +119,10 @@
      * Fulfill the ResourceCollection contract.
      * @return whether this is a filesystem-only resource collection.
      */
+    @Override
     public synchronized boolean isFilesystemOnly() {
         if (isReference()) {
-            return ((Restrict) getCheckedRef()).isFilesystemOnly();
+            return getCheckedRef().isFilesystemOnly();
         }
         dieOnCircularReference();
         return w.isFilesystemOnly();
@@ -132,6 +132,7 @@
      * Format this Restrict collection as a String.
      * @return the String value of this collection.
      */
+    @Override
     public synchronized String toString() {
         if (isReference()) {
             return getCheckedRef().toString();
@@ -140,6 +141,7 @@
         return w.toString();
     }
 
+    @Override
     protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p) {
         if (isChecked()) {
             return;
@@ -153,4 +155,9 @@
             setChecked(true);
         }
     }
+
+    @Override
+    protected Restrict getCheckedRef() {
+        return (Restrict) super.getCheckedRef();
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/SizeLimitCollection.java b/src/main/org/apache/tools/ant/types/resources/SizeLimitCollection.java
index 2992d5b..8f6ed38 100644
--- a/src/main/org/apache/tools/ant/types/resources/SizeLimitCollection.java
+++ b/src/main/org/apache/tools/ant/types/resources/SizeLimitCollection.java
@@ -50,10 +50,9 @@
      * Efficient size implementation.
      * @return int size
      */
+    @Override
     public synchronized int size() {
-        int sz = getResourceCollection().size();
-        int ct = getValidCount();
-        return sz < ct ? sz : ct;
+        return Math.min(getResourceCollection().size(), getValidCount());
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/types/resources/Sort.java b/src/main/org/apache/tools/ant/types/resources/Sort.java
index b4dc88c..341b6c9 100644
--- a/src/main/org/apache/tools/ant/types/resources/Sort.java
+++ b/src/main/org/apache/tools/ant/types/resources/Sort.java
@@ -18,19 +18,15 @@
 package org.apache.tools.ant.types.resources;
 
 import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Stack;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.types.DataType;
 import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.ResourceCollection;
 import org.apache.tools.ant.types.resources.comparators.DelegatedResourceComparator;
 import org.apache.tools.ant.types.resources.comparators.ResourceComparator;
-import org.apache.tools.ant.util.CollectionUtils;
 
 /**
  * ResourceCollection that sorts another ResourceCollection.
@@ -48,15 +44,10 @@
      * Sort the contained elements.
      * @return a Collection of Resources.
      */
+    @Override
     protected synchronized Collection<Resource> getCollection() {
-        ResourceCollection rc = getResourceCollection();
-        Iterator<Resource> iter = rc.iterator();
-        if (!(iter.hasNext())) {
-            return Collections.emptySet();
-        }
-        List<Resource> result = (List<Resource>) CollectionUtils.asCollection(iter);
-        Collections.sort(result, comp);
-        return result;
+        return getResourceCollection().stream().map(Resource.class::cast)
+            .sorted(comp).collect(Collectors.toList());
     }
 
     /**
@@ -80,6 +71,7 @@
      * @param p   the project to use to dereference the references.
      * @throws BuildException on error.
      */
+    @Override
     protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
diff --git a/src/main/org/apache/tools/ant/types/resources/StringResource.java b/src/main/org/apache/tools/ant/types/resources/StringResource.java
index 9a52982..9a2a0ad 100644
--- a/src/main/org/apache/tools/ant/types/resources/StringResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/StringResource.java
@@ -149,8 +149,8 @@
      */
     @Override
     public synchronized long getSize() {
-        return isReference() ? ((Resource) getCheckedRef()).getSize()
-                : getContent().length();
+        return isReference() ? getCheckedRef().getSize()
+            : getContent().length();
     }
 
     /**
@@ -188,7 +188,7 @@
     @Override
     public synchronized InputStream getInputStream() throws IOException {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getInputStream();
+            return getCheckedRef().getInputStream();
         }
         String content = getContent();
         if (content == null) {
@@ -209,7 +209,7 @@
     @Override
     public synchronized OutputStream getOutputStream() throws IOException {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getOutputStream();
+            return getCheckedRef().getOutputStream();
         }
         if (getValue() != null) {
             throw new ImmutableResourceException();
@@ -237,19 +237,9 @@
         return getValue();
     }
 
-    /**
-     * This method is only for use by our private helper output stream.
-     * It contains specific logic for expanding properties.
-     * @param output the output
-     */
-    private void setValueFromOutputStream(String output) {
-        String value;
-        if (getProject() != null) {
-            value = getProject().replaceProperties(output);
-        } else {
-            value = output;
-        }
-        setValue(value);
+    @Override
+    protected StringResource getCheckedRef() {
+        return (StringResource) super.getCheckedRef();
     }
 
     private class StringResourceFilterOutputStream extends FilterOutputStream {
@@ -266,7 +256,18 @@
             String result = encoding == null
                     ? baos.toString() : baos.toString(encoding);
 
-            StringResource.this.setValueFromOutputStream(result);
+            setValueFromOutputStream(result);
         }
+
+        private void setValueFromOutputStream(String output) {
+            String value;
+            if (getProject() != null) {
+                value = getProject().replaceProperties(output);
+            } else {
+                value = output;
+            }
+            setValue(value);
+        }
+
     }
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/TarResource.java b/src/main/org/apache/tools/ant/types/resources/TarResource.java
index b906a65..7713e44 100644
--- a/src/main/org/apache/tools/ant/types/resources/TarResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/TarResource.java
@@ -74,13 +74,14 @@
      * @throws IOException if the tar file cannot be opened,
      *         or the entry cannot be read.
      */
+    @Override
     public InputStream getInputStream() throws IOException {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getInputStream();
+            return getCheckedRef().getInputStream();
         }
         Resource archive = getArchive();
         final TarInputStream i = new TarInputStream(archive.getInputStream());
-        TarEntry te = null;
+        TarEntry te;
         while ((te = i.getNextEntry()) != null) {
             if (te.getName().equals(getName())) {
                 return i;
@@ -100,9 +101,10 @@
      * @throws UnsupportedOperationException if OutputStreams are not
      *         supported for this Resource type.
      */
+    @Override
     public OutputStream getOutputStream() throws IOException {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getOutputStream();
+            return getCheckedRef().getOutputStream();
         }
         throw new UnsupportedOperationException(
             "Use the tar task for tar output.");
@@ -113,7 +115,7 @@
      */
     public String getUserName() {
         if (isReference()) {
-            return ((TarResource) getCheckedRef()).getUserName();
+            return getCheckedRef().getUserName();
         }
         checkEntry();
         return userName;
@@ -124,7 +126,7 @@
      */
     public String getGroup() {
         if (isReference()) {
-            return ((TarResource) getCheckedRef()).getGroup();
+            return getCheckedRef().getGroup();
         }
         checkEntry();
         return groupName;
@@ -135,7 +137,7 @@
      */
     public int getUid() {
         if (isReference()) {
-            return ((TarResource) getCheckedRef()).getUid();
+            return getCheckedRef().getUid();
         }
         checkEntry();
         return uid;
@@ -146,7 +148,7 @@
      */
     public int getGid() {
         if (isReference()) {
-            return ((TarResource) getCheckedRef()).getGid();
+            return getCheckedRef().getGid();
         }
         checkEntry();
         return gid;
@@ -155,11 +157,10 @@
     /**
      * fetches information from the named entry inside the archive.
      */
+    @Override
     protected void fetchEntry() {
         Resource archive = getArchive();
-        TarInputStream i = null;
-        try {
-            i = new TarInputStream(archive.getInputStream());
+        try (TarInputStream i = new TarInputStream(archive.getInputStream())) {
             TarEntry te = null;
             while ((te = i.getNextEntry()) != null) {
                 if (te.getName().equals(getName())) {
@@ -170,12 +171,15 @@
         } catch (IOException e) {
             log(e.getMessage(), Project.MSG_DEBUG);
             throw new BuildException(e);
-        } finally {
-            FileUtils.close(i);
         }
         setEntry(null);
     }
 
+    @Override
+    protected TarResource getCheckedRef() {
+        return (TarResource) super.getCheckedRef();
+    }
+
     private void setEntry(TarEntry e) {
         if (e == null) {
             setExists(false);
diff --git a/src/main/org/apache/tools/ant/types/resources/Tokens.java b/src/main/org/apache/tools/ant/types/resources/Tokens.java
index 458f8c1..c8e9110 100644
--- a/src/main/org/apache/tools/ant/types/resources/Tokens.java
+++ b/src/main/org/apache/tools/ant/types/resources/Tokens.java
@@ -19,10 +19,11 @@
 
 import java.io.IOException;
 import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 import java.util.Stack;
 
 import org.apache.tools.ant.BuildException;
@@ -31,7 +32,6 @@
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.types.ResourceCollection;
 import org.apache.tools.ant.util.ConcatResourceInputStream;
-import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.LineTokenizer;
 import org.apache.tools.ant.util.Tokenizer;
 
@@ -51,38 +51,26 @@
      */
     protected synchronized Collection<Resource> getCollection() {
         ResourceCollection rc = getResourceCollection();
-        if (rc.size() == 0) {
+        if (rc.isEmpty()) {
             return Collections.emptySet();
         }
         if (tokenizer == null) {
             tokenizer = new LineTokenizer();
         }
-        ConcatResourceInputStream cat = new ConcatResourceInputStream(rc);
-        cat.setManagingComponent(this);
-
-        InputStreamReader rdr = null;
-        try {
-            if (encoding == null) {
-                rdr = new InputStreamReader(cat);
-            } else {
-                try {
-                    rdr = new InputStreamReader(cat, encoding);
-                } catch (UnsupportedEncodingException e) {
-                    throw new BuildException(e);
-                }
-            }
-            ArrayList<Resource> result = new ArrayList<Resource>();
-            for (String s = tokenizer.getToken(rdr); s != null; s = tokenizer.getToken(rdr)) {
-                StringResource resource = new StringResource(s);
-                resource.setProject(getProject());
+        try (ConcatResourceInputStream cat = new ConcatResourceInputStream(rc);
+                InputStreamReader rdr = new InputStreamReader(cat,
+                    encoding == null ? Charset.defaultCharset()
+                        : Charset.forName(encoding))) {
+            cat.setManagingComponent(this);
+            List<Resource> result = new ArrayList<>();
+            for (String s = tokenizer.getToken(rdr); s != null; s =
+                tokenizer.getToken(rdr)) {
+                StringResource resource = new StringResource(getProject(), s);
                 result.add(resource);
             }
             return result;
         } catch (IOException e) {
             throw new BuildException("Error reading tokens", e);
-        } finally {
-            FileUtils.close(rdr);
-            FileUtils.close(cat);
         }
     }
 
@@ -117,6 +105,7 @@
      * @param p   the project to use to dereference the references.
      * @throws BuildException on error.
      */
+    @Override
     protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
diff --git a/src/main/org/apache/tools/ant/types/resources/Union.java b/src/main/org/apache/tools/ant/types/resources/Union.java
index 5b07395..43c1b57 100644
--- a/src/main/org/apache/tools/ant/types/resources/Union.java
+++ b/src/main/org/apache/tools/ant/types/resources/Union.java
@@ -17,12 +17,12 @@
  */
 package org.apache.tools.ant.types.resources;
 
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.LinkedHashSet;
-import java.util.List;
 import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.types.Resource;
@@ -84,8 +84,7 @@
         if (isReference()) {
             return getCheckedRef(Union.class, getDataTypeName()).list();
         }
-        final Collection<String> result = getAllToStrings();
-        return result.toArray(new String[result.size()]);
+        return streamResources().map(Object::toString).toArray(String[]::new);
     }
 
     /**
@@ -96,14 +95,14 @@
         if (isReference()) {
             return getCheckedRef(Union.class, getDataTypeName()).listResources();
         }
-        final Collection<Resource> result = getAllResources();
-        return result.toArray(new Resource[result.size()]);
+        return streamResources().toArray(Resource[]::new);
     }
 
     /**
      * Unify the contained Resources.
      * @return a Collection of Resources.
      */
+    @Override
     protected Collection<Resource> getCollection() {
         return getAllResources();
     }
@@ -118,7 +117,8 @@
     @Deprecated
     @SuppressWarnings("unchecked")
     protected <T> Collection<T> getCollection(boolean asString) { // TODO untypable
-        return asString ? (Collection<T>) getAllToStrings() : (Collection<T>) getAllResources();
+        return asString ? (Collection<T>) getAllToStrings()
+            : (Collection<T>) getAllResources();
     }
 
     /**
@@ -126,12 +126,8 @@
      * @return Collection&lt;String&gt;
      */
     protected Collection<String> getAllToStrings() {
-        final Set<Resource> allResources = getAllResources();
-        final ArrayList<String> result = new ArrayList<String>(allResources.size());
-        for (Resource r : allResources) {
-            result.add(r.toString());
-        }
-        return result;
+        return streamResources(Object::toString)
+            .collect(Collectors.toCollection(LinkedHashSet::new));
     }
 
     /**
@@ -139,19 +135,17 @@
      * @return Set&lt;Resource&gt;
      */
     protected Set<Resource> getAllResources() {
-        final List<ResourceCollection> resourceCollections = getResourceCollections();
-        if (resourceCollections.isEmpty()) {
-            return Collections.emptySet();
-        }
-        final LinkedHashSet<Resource> result = new LinkedHashSet<Resource>(
-                resourceCollections.size() * 2);
-        for (ResourceCollection resourceCollection : resourceCollections) {
-            for (Resource r : resourceCollection) {
-                result.add(r);
-            }
-        }
-        return result;
+        return streamResources()
+            .collect(Collectors.toCollection(LinkedHashSet::new));
     }
 
-}
+    private Stream<? extends Resource> streamResources() {
+        return streamResources(Function.identity());
+    }
 
+    private <T> Stream<? extends T> streamResources(
+        Function<? super Resource, ? extends T> mapper) {
+        return getResourceCollections().stream()
+            .flatMap(ResourceCollection::stream).map(mapper).distinct();
+    }
+}
diff --git a/src/main/org/apache/tools/ant/types/resources/comparators/Date.java b/src/main/org/apache/tools/ant/types/resources/comparators/Date.java
index b6be66b..ab7ed25 100644
--- a/src/main/org/apache/tools/ant/types/resources/comparators/Date.java
+++ b/src/main/org/apache/tools/ant/types/resources/comparators/Date.java
@@ -17,6 +17,8 @@
  */
 package org.apache.tools.ant.types.resources.comparators;
 
+import java.util.Comparator;
+
 import org.apache.tools.ant.types.Resource;
 
 /**
@@ -32,14 +34,8 @@
      *         argument is less than, equal to, or greater than the second.
      */
     protected int resourceCompare(Resource foo, Resource bar) {
-        long diff = foo.getLastModified() - bar.getLastModified();
-        if (diff > 0) {
-            return +1;
-        } else if (diff < 0) {
-            return -1;
-        } else {
-            return 0;
-        }
+        return Comparator.comparingLong(Resource::getLastModified).compare(foo,
+            bar);
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/comparators/DelegatedResourceComparator.java b/src/main/org/apache/tools/ant/types/resources/comparators/DelegatedResourceComparator.java
index aa2f55a..28f6793 100644
--- a/src/main/org/apache/tools/ant/types/resources/comparators/DelegatedResourceComparator.java
+++ b/src/main/org/apache/tools/ant/types/resources/comparators/DelegatedResourceComparator.java
@@ -17,7 +17,7 @@
  */
 package org.apache.tools.ant.types.resources.comparators;
 
-import java.util.Iterator;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Stack;
 import java.util.Vector;
@@ -47,7 +47,7 @@
         if (c == null) {
             return;
         }
-        resourceComparators = (resourceComparators == null) ? new Vector<ResourceComparator>() : resourceComparators;
+        resourceComparators = (resourceComparators == null) ? new Vector<>() : resourceComparators;
         resourceComparators.add(c);
         setChecked(false);
     }
@@ -58,6 +58,7 @@
      * @param o the object to check against.
      * @return true if there is equality.
      */
+    @Override
     public synchronized boolean equals(Object o) {
         if (o == this) {
             return true;
@@ -76,6 +77,7 @@
      * Hashcode based on the rules for equality.
      * @return a hashcode.
      */
+    @Override
     public synchronized int hashCode() {
         if (isReference()) {
             return getCheckedRef().hashCode();
@@ -84,16 +86,9 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected synchronized int resourceCompare(Resource foo, Resource bar) {
-        //if no nested, natural order:
-        if (resourceComparators == null || resourceComparators.isEmpty()) {
-            return foo.compareTo(bar);
-        }
-        int result = 0;
-        for (Iterator<ResourceComparator> i = resourceComparators.iterator(); result == 0 && i.hasNext();) {
-            result = i.next().resourceCompare(foo, bar);
-        }
-        return result;
+        return composite(resourceComparators).compare(foo, bar);
     }
 
     /**
@@ -103,6 +98,7 @@
      * @param p   the Project to resolve against.
      * @throws BuildException on error.
      */
+    @Override
     protected void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
@@ -122,4 +118,18 @@
             setChecked(true);
         }
     }
+
+    private static Comparator<Resource> composite(List<? extends Comparator<Resource>> foo) {
+        Comparator<Resource> result = null;
+        if (foo != null) {
+            for (Comparator<Resource> comparator : foo) {
+                if (result == null) {
+                    result = comparator;
+                    continue;
+                }
+                result = result.thenComparing(comparator);
+            }
+        }
+        return result == null ? Comparator.naturalOrder() : result;
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/comparators/Exists.java b/src/main/org/apache/tools/ant/types/resources/comparators/Exists.java
index 5832150..c66d6fb 100644
--- a/src/main/org/apache/tools/ant/types/resources/comparators/Exists.java
+++ b/src/main/org/apache/tools/ant/types/resources/comparators/Exists.java
@@ -17,6 +17,8 @@
  */
 package org.apache.tools.ant.types.resources.comparators;
 
+import java.util.Comparator;
+
 import org.apache.tools.ant.types.Resource;
 
 /**
@@ -33,11 +35,7 @@
      *         argument is less than, equal to, or greater than the second.
      */
     protected int resourceCompare(Resource foo, Resource bar) {
-        boolean f = foo.isExists();
-        if (f == bar.isExists()) {
-            return 0;
-        }
-        return f ? 1 : -1;
+        return Comparator.comparing(Resource::isExists).compare(foo, bar);
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/comparators/FileSystem.java b/src/main/org/apache/tools/ant/types/resources/comparators/FileSystem.java
index 7eafeb9..3ae7938 100644
--- a/src/main/org/apache/tools/ant/types/resources/comparators/FileSystem.java
+++ b/src/main/org/apache/tools/ant/types/resources/comparators/FileSystem.java
@@ -18,6 +18,9 @@
 package org.apache.tools.ant.types.resources.comparators;
 
 import java.io.File;
+import java.util.Comparator;
+import java.util.Objects;
+import java.util.function.Function;
 
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.types.resources.FileProvider;
@@ -36,25 +39,33 @@
      * @param bar the second Resource.
      * @return a negative integer, zero, or a positive integer as the first
      *         argument is less than, equal to, or greater than the second.
-     * @throws ClassCastException if either resource is not an instance of FileResource.
+     * @throws ClassCastException if either resource is not capable of
+     *         exposing a {@link FileProvider}
      */
     protected int resourceCompare(Resource foo, Resource bar) {
-        FileProvider fooFP = foo.as(FileProvider.class);
-        if (fooFP == null) {
-            throw new ClassCastException(foo.getClass()
-                                         + " doesn't provide files");
-        }
-        File foofile = fooFP.getFile();
-        FileProvider barFP = bar.as(FileProvider.class);
-        if (barFP == null) {
-            throw new ClassCastException(bar.getClass()
-                                         + " doesn't provide files");
-        }
-        File barfile = barFP.getFile();
-        return foofile.equals(barfile) ? 0
-            : FILE_UTILS.isLeadingPath(foofile, barfile) ? -1
-            : FILE_UTILS.normalize(foofile.getAbsolutePath()).compareTo(
-                FILE_UTILS.normalize(barfile.getAbsolutePath()));
+        return compare(file(foo), file(bar));
     }
 
+    private File file(Resource r) {
+        return r.asOptional(FileProvider.class)
+            .orElseThrow(() -> new ClassCastException(
+                r.getClass() + " doesn't provide files"))
+            .getFile();
+    }
+
+    private int compare(File f1, File f2) {
+        if (Objects.equals(f1, f2)) {
+            return 0;
+        }
+        if (FILE_UTILS.isLeadingPath(f1, f2)) {
+            return -1;
+        }
+        if (FILE_UTILS.isLeadingPath(f2, f1)) {
+            return 1;
+        }
+        return Comparator
+            .comparing(((Function<File, String>) File::getAbsolutePath)
+                .andThen(FILE_UTILS::normalize))
+            .compare(f1, f2);
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/comparators/ResourceComparator.java b/src/main/org/apache/tools/ant/types/resources/comparators/ResourceComparator.java
index 3bfc9c7..ee9c556 100644
--- a/src/main/org/apache/tools/ant/types/resources/comparators/ResourceComparator.java
+++ b/src/main/org/apache/tools/ant/types/resources/comparators/ResourceComparator.java
@@ -36,10 +36,10 @@
      *         argument is less than, equal to, or greater than the second.
      * @throws ClassCastException if either argument is null.
      */
+    @Override
     public final int compare(Resource foo, Resource bar) {
         dieOnCircularReference();
-        ResourceComparator c =
-            isReference() ? (ResourceComparator) getCheckedRef() : this;
+        ResourceComparator c = isReference() ? getCheckedRef() : this;
         return c.resourceCompare(foo, bar);
     }
 
@@ -48,6 +48,7 @@
      * @param o the Object to compare against.
      * @return true if the specified Object equals this one.
      */
+    @Override
     public boolean equals(Object o) {
         if (isReference()) {
             return getCheckedRef().equals(o);
@@ -62,6 +63,7 @@
      * Hashcode based on the rules for equality.
      * @return a hashcode.
      */
+    @Override
     public synchronized int hashCode() {
         if (isReference()) {
             return getCheckedRef().hashCode();
@@ -78,4 +80,8 @@
      */
     protected abstract int resourceCompare(Resource foo, Resource bar);
 
+    @Override
+    protected ResourceComparator getCheckedRef() {
+        return (ResourceComparator) super.getCheckedRef();
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/comparators/Reverse.java b/src/main/org/apache/tools/ant/types/resources/comparators/Reverse.java
index 5da3ebb..6bef0e7 100644
--- a/src/main/org/apache/tools/ant/types/resources/comparators/Reverse.java
+++ b/src/main/org/apache/tools/ant/types/resources/comparators/Reverse.java
@@ -17,6 +17,8 @@
  */
 package org.apache.tools.ant.types.resources.comparators;
 
+import java.util.Comparator;
+import java.util.Optional;
 import java.util.Stack;
 
 import org.apache.tools.ant.BuildException;
@@ -69,8 +71,8 @@
      *         argument is greater than, equal to, or less than the second.
      */
     protected int resourceCompare(Resource foo, Resource bar) {
-        return -1 * (nested == null
-            ? foo.compareTo(bar) : nested.compare(foo, bar));
+        return Optional.<Comparator<Resource>> ofNullable(nested)
+            .orElseGet(Comparator::naturalOrder).reversed().compare(foo, bar);
     }
 
     protected void dieOnCircularReference(Stack<Object> stk, Project p)
@@ -88,4 +90,5 @@
             setChecked(true);
         }
     }
+
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/comparators/Size.java b/src/main/org/apache/tools/ant/types/resources/comparators/Size.java
index b94f250..bf0fe35 100644
--- a/src/main/org/apache/tools/ant/types/resources/comparators/Size.java
+++ b/src/main/org/apache/tools/ant/types/resources/comparators/Size.java
@@ -17,6 +17,8 @@
  */
 package org.apache.tools.ant.types.resources.comparators;
 
+import java.util.Comparator;
+
 import org.apache.tools.ant.types.Resource;
 
 /**
@@ -32,8 +34,7 @@
      *         argument is less than, equal to, or greater than the second.
      */
     protected int resourceCompare(Resource foo, Resource bar) {
-        long diff = foo.getSize() - bar.getSize();
-        return diff > 0 ? 1 : (diff == 0 ? 0 : -1);
+        return Comparator.comparingLong(Resource::getSize).compare(foo, bar);
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/comparators/Type.java b/src/main/org/apache/tools/ant/types/resources/comparators/Type.java
index 6c082ef..2039735 100644
--- a/src/main/org/apache/tools/ant/types/resources/comparators/Type.java
+++ b/src/main/org/apache/tools/ant/types/resources/comparators/Type.java
@@ -17,6 +17,8 @@
  */
 package org.apache.tools.ant.types.resources.comparators;
 
+import java.util.Comparator;
+
 import org.apache.tools.ant.types.Resource;
 
 /**
@@ -34,11 +36,7 @@
      *         argument is less than, equal to, or greater than the second.
      */
     protected int resourceCompare(Resource foo, Resource bar) {
-        boolean f = foo.isDirectory();
-        if (f == bar.isDirectory()) {
-            return 0;
-        }
-        return f ? 1 : -1;
+        return Comparator.comparing(Resource::isDirectory).compare(foo, bar);
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/selectors/And.java b/src/main/org/apache/tools/ant/types/resources/selectors/And.java
index 409ed66..6925360 100644
--- a/src/main/org/apache/tools/ant/types/resources/selectors/And.java
+++ b/src/main/org/apache/tools/ant/types/resources/selectors/And.java
@@ -17,8 +17,6 @@
  */
 package org.apache.tools.ant.types.resources.selectors;
 
-import java.util.Iterator;
-
 import org.apache.tools.ant.types.Resource;
 
 /**
@@ -37,7 +35,7 @@
      * Convenience constructor.
      * @param r the ResourceSelector[] to add.
      */
-    public And(ResourceSelector[] r) {
+    public And(ResourceSelector... r) {
         super(r);
     }
 
@@ -47,12 +45,7 @@
      * @return whether the Resource was selected.
      */
     public boolean isSelected(Resource r) {
-        for (Iterator<ResourceSelector> i = getSelectors(); i.hasNext();) {
-            if (!i.next().isSelected(r)) {
-                return false;
-            }
-        }
-        return true;
+        return getResourceSelectors().stream().allMatch(s -> s.isSelected(r));
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/selectors/Date.java b/src/main/org/apache/tools/ant/types/resources/selectors/Date.java
index 0719a18..23698af 100644
--- a/src/main/org/apache/tools/ant/types/resources/selectors/Date.java
+++ b/src/main/org/apache/tools/ant/types/resources/selectors/Date.java
@@ -144,15 +144,15 @@
             try {
                 long m = df.parse(dateTime).getTime();
                 if (m < 0) {
-                    throw new BuildException("Date of " + dateTime
-                        + " results in negative milliseconds value"
-                        + " relative to epoch (January 1, 1970, 00:00:00 GMT).");
+                    throw new BuildException(
+                        "Date of %s results in negative milliseconds value relative to epoch (January 1, 1970, 00:00:00 GMT).",
+                        dateTime);
                 }
                 setMillis(m);
             } catch (ParseException pe) {
-                throw new BuildException("Date of " + dateTime
-                        + " Cannot be parsed correctly. It should be in '"
-                        + p + "' format.");
+                throw new BuildException(
+                    "Date of %s Cannot be parsed correctly. It should be in '%s' format.",
+                    dateTime, p);
             }
         }
         return when.evaluate(r.getLastModified(), millis.longValue(), granularity);
diff --git a/src/main/org/apache/tools/ant/types/resources/selectors/InstanceOf.java b/src/main/org/apache/tools/ant/types/resources/selectors/InstanceOf.java
index 39b3108..2b50514 100644
--- a/src/main/org/apache/tools/ant/types/resources/selectors/InstanceOf.java
+++ b/src/main/org/apache/tools/ant/types/resources/selectors/InstanceOf.java
@@ -110,13 +110,12 @@
         if (type != null) {
             if (project == null) {
                 throw new BuildException(
-                    "No project set for InstanceOf ResourceSelector; "
-                    + "the type attribute is invalid.");
+                    "No project set for InstanceOf ResourceSelector; the type attribute is invalid.");
             }
             AntTypeDefinition d = ComponentHelper.getComponentHelper(
                 project).getDefinition(ProjectHelper.genComponentName(uri, type));
             if (d == null) {
-                throw new BuildException("type " + type + " not found.");
+                throw new BuildException("type %s not found.",type);
             }
             try {
                 c = d.innerGetTypeClass();
diff --git a/src/main/org/apache/tools/ant/types/resources/selectors/Majority.java b/src/main/org/apache/tools/ant/types/resources/selectors/Majority.java
index 5a7a95c..e87e232 100644
--- a/src/main/org/apache/tools/ant/types/resources/selectors/Majority.java
+++ b/src/main/org/apache/tools/ant/types/resources/selectors/Majority.java
@@ -25,8 +25,8 @@
  * Majority ResourceSelector.
  * @since Ant 1.7
  */
-public class Majority
-    extends ResourceSelectorContainer implements ResourceSelector {
+public class Majority extends ResourceSelectorContainer
+    implements ResourceSelector {
 
     private boolean tie = true;
 
@@ -40,7 +40,7 @@
      * Convenience constructor.
      * @param r the ResourceSelector[] to add.
      */
-    public Majority(ResourceSelector[] r) {
+    public Majority(ResourceSelector... r) {
         super(r);
     }
 
diff --git a/src/main/org/apache/tools/ant/types/resources/selectors/Name.java b/src/main/org/apache/tools/ant/types/resources/selectors/Name.java
index baf9a3c..75d4f25 100644
--- a/src/main/org/apache/tools/ant/types/resources/selectors/Name.java
+++ b/src/main/org/apache/tools/ant/types/resources/selectors/Name.java
@@ -132,18 +132,17 @@
     private boolean matches(String name) {
         if (pattern != null) {
             return SelectorUtils.match(modify(pattern), modify(name), cs);
-        } else {
-            if (reg == null) {
-                reg = new RegularExpression();
-                reg.setPattern(regex);
-                expression = reg.getRegexp(project);
-            }
-            return expression.matches(modify(name), RegexpUtil.asOptions(cs));
         }
+        if (reg == null) {
+            reg = new RegularExpression();
+            reg.setPattern(regex);
+            expression = reg.getRegexp(project);
+        }
+        return expression.matches(modify(name), RegexpUtil.asOptions(cs));
     }
 
     private String modify(String s) {
-        if (s == null || !handleDirSep || s.indexOf("\\") == -1) {
+        if (s == null || !handleDirSep || s.indexOf('\\') < 0) {
             return s;
         }
         return s.replace('\\', '/');
diff --git a/src/main/org/apache/tools/ant/types/resources/selectors/None.java b/src/main/org/apache/tools/ant/types/resources/selectors/None.java
index 0de8623..204d9c2 100644
--- a/src/main/org/apache/tools/ant/types/resources/selectors/None.java
+++ b/src/main/org/apache/tools/ant/types/resources/selectors/None.java
@@ -17,8 +17,6 @@
  */
 package org.apache.tools.ant.types.resources.selectors;
 
-import java.util.Iterator;
-
 import org.apache.tools.ant.types.Resource;
 
 /**
@@ -38,7 +36,7 @@
      * Convenience constructor.
      * @param r the ResourceSelector[] to add.
      */
-    public None(ResourceSelector[] r) {
+    public None(ResourceSelector... r) {
         super(r);
     }
 
@@ -48,12 +46,7 @@
      * @return whether the Resource was selected.
      */
     public boolean isSelected(Resource r) {
-        for (Iterator<ResourceSelector> i = getSelectors(); i.hasNext();) {
-            if (i.next().isSelected(r)) {
-                return false;
-            }
-        }
-        return true;
+        return getResourceSelectors().stream().noneMatch(s -> s.isSelected(r));
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/selectors/Or.java b/src/main/org/apache/tools/ant/types/resources/selectors/Or.java
index b22303a..9a39b86 100644
--- a/src/main/org/apache/tools/ant/types/resources/selectors/Or.java
+++ b/src/main/org/apache/tools/ant/types/resources/selectors/Or.java
@@ -17,8 +17,6 @@
  */
 package org.apache.tools.ant.types.resources.selectors;
 
-import java.util.Iterator;
-
 import org.apache.tools.ant.types.Resource;
 
 /**
@@ -37,7 +35,7 @@
      * Convenience constructor.
      * @param r the ResourceSelector[] to add.
      */
-    public Or(ResourceSelector[] r) {
+    public Or(ResourceSelector... r) {
         super(r);
     }
 
@@ -47,12 +45,7 @@
      * @return whether the Resource was selected.
      */
     public boolean isSelected(Resource r) {
-        for (Iterator<ResourceSelector> i = getSelectors(); i.hasNext();) {
-            if (i.next().isSelected(r)) {
-                return true;
-            }
-        }
-        return false;
+        return getResourceSelectors().stream().anyMatch(s -> s.isSelected(r));
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/resources/selectors/ResourceSelectorContainer.java b/src/main/org/apache/tools/ant/types/resources/selectors/ResourceSelectorContainer.java
index 19e0140..9ac639c 100644
--- a/src/main/org/apache/tools/ant/types/resources/selectors/ResourceSelectorContainer.java
+++ b/src/main/org/apache/tools/ant/types/resources/selectors/ResourceSelectorContainer.java
@@ -33,7 +33,7 @@
  */
 public class ResourceSelectorContainer extends DataType {
 
-    private final List<ResourceSelector> resourceSelectors = new ArrayList<ResourceSelector>();
+    private final List<ResourceSelector> resourceSelectors = new ArrayList<>();
 
     /**
      * Default constructor.
@@ -43,11 +43,11 @@
 
     /**
      * Construct a new ResourceSelectorContainer with the specified array of selectors.
-     * @param rs the ResourceSelector[] to add.
+     * @param resourceSelectors the ResourceSelector[] to add.
      */
-    public ResourceSelectorContainer(ResourceSelector[] rs) {
-        for (int i = 0; i < rs.length; i++) {
-            add(rs[i]);
+    public ResourceSelectorContainer(ResourceSelector... resourceSelectors) {
+        for (ResourceSelector rsel : resourceSelectors) {
+            add(rsel);
         }
     }
 
@@ -72,7 +72,7 @@
      */
     public boolean hasSelectors() {
         if (isReference()) {
-            return ((ResourceSelectorContainer) getCheckedRef()).hasSelectors();
+            return getCheckedRef().hasSelectors();
         }
         dieOnCircularReference();
         return !resourceSelectors.isEmpty();
@@ -84,7 +84,7 @@
      */
     public int selectorCount() {
         if (isReference()) {
-            return ((ResourceSelectorContainer) getCheckedRef()).selectorCount();
+            return getCheckedRef().selectorCount();
         }
         dieOnCircularReference();
         return resourceSelectors.size();
@@ -96,10 +96,21 @@
      */
     public Iterator<ResourceSelector> getSelectors() {
         if (isReference()) {
-            return ((ResourceSelectorContainer) getCheckedRef()).getSelectors();
+            return getCheckedRef().getSelectors();
+        }
+        return getResourceSelectors().iterator();
+    }
+
+    /**
+     * Get the configured {@link ResourceSelector}s as a {@link List}.
+     * @return {@link List} of {@link ResourceSelector}
+     */
+    public List<ResourceSelector> getResourceSelectors() {
+        if (isReference()) {
+            return getCheckedRef().getResourceSelectors();
         }
         dieOnCircularReference();
-        return Collections.unmodifiableList(resourceSelectors).iterator();
+        return Collections.unmodifiableList(resourceSelectors);
     }
 
     /**
@@ -125,4 +136,8 @@
         }
     }
 
+    @Override
+    protected ResourceSelectorContainer getCheckedRef() {
+        return (ResourceSelectorContainer) super.getCheckedRef();
+    }
 }
diff --git a/src/main/org/apache/tools/ant/types/selectors/AbstractSelectorContainer.java b/src/main/org/apache/tools/ant/types/selectors/AbstractSelectorContainer.java
index b80816d..21fbdeb 100644
--- a/src/main/org/apache/tools/ant/types/selectors/AbstractSelectorContainer.java
+++ b/src/main/org/apache/tools/ant/types/selectors/AbstractSelectorContainer.java
@@ -18,9 +18,13 @@
 
 package org.apache.tools.ant.types.selectors;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.List;
 import java.util.Stack;
 import java.util.Vector;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -36,18 +40,20 @@
 public abstract class AbstractSelectorContainer extends DataType
     implements Cloneable, SelectorContainer {
 
-    private Vector<FileSelector> selectorsList = new Vector<FileSelector>();
+    private List<FileSelector> selectorsList =
+        Collections.synchronizedList(new ArrayList<>());
 
     /**
      * Indicates whether there are any selectors here.
      * @return true if there are selectors
      */
+    @Override
     public boolean hasSelectors() {
         if (isReference()) {
-            return ((AbstractSelectorContainer) getCheckedRef()).hasSelectors();
+            return getCheckedRef().hasSelectors();
         }
         dieOnCircularReference();
-        return !(selectorsList.isEmpty());
+        return !selectorsList.isEmpty();
     }
 
     /**
@@ -56,7 +62,7 @@
      */
     public int selectorCount() {
         if (isReference()) {
-            return ((AbstractSelectorContainer) getCheckedRef()).selectorCount();
+            return getCheckedRef().selectorCount();
         }
         dieOnCircularReference();
         return selectorsList.size();
@@ -69,13 +75,11 @@
      */
     public FileSelector[] getSelectors(Project p) {
         if (isReference()) {
-            return ((AbstractSelectorContainer) getCheckedRef(p))
-                .getSelectors(p);
+            return getCheckedRef(AbstractSelectorContainer.class,
+                getDataTypeName(), p).getSelectors(p);
         }
         dieOnCircularReference(p);
-        FileSelector[] result = new FileSelector[selectorsList.size()];
-        selectorsList.copyInto(result);
-        return result;
+        return selectorsList.toArray(new FileSelector[selectorsList.size()]);
     }
 
     /**
@@ -84,11 +88,10 @@
      */
     public Enumeration<FileSelector> selectorElements() {
         if (isReference()) {
-            return ((AbstractSelectorContainer) getCheckedRef())
-                .selectorElements();
+            return getCheckedRef().selectorElements();
         }
         dieOnCircularReference();
-        return selectorsList.elements();
+        return Collections.enumeration(selectorsList);
     }
 
     /**
@@ -99,18 +102,8 @@
      * @return comma separated list of Selectors contained in this one
      */
     public String toString() {
-        StringBuilder buf = new StringBuilder();
-        Enumeration<FileSelector> e = selectorElements();
-        if (e.hasMoreElements()) {
-            while (e.hasMoreElements()) {
-                buf.append(e.nextElement().toString());
-                if (e.hasMoreElements()) {
-                    buf.append(", ");
-                }
-            }
-        }
-
-        return buf.toString();
+        return selectorsList.stream().map(Object::toString)
+            .collect(Collectors.joining(", "));
     }
 
     /**
@@ -122,7 +115,7 @@
         if (isReference()) {
             throw noChildrenAllowed();
         }
-        selectorsList.addElement(selector);
+        selectorsList.add(selector);
         setChecked(false);
     }
 
@@ -144,16 +137,11 @@
      */
     public void validate() {
         if (isReference()) {
-            ((AbstractSelectorContainer) getCheckedRef()).validate();
+            getCheckedRef().validate();
         }
         dieOnCircularReference();
-        Enumeration<FileSelector> e = selectorElements();
-        while (e.hasMoreElements()) {
-            Object o = e.nextElement();
-            if (o instanceof BaseSelector) {
-                ((BaseSelector) o).validate();
-            }
-        }
+        selectorsList.stream().filter(BaseSelector.class::isInstance)
+            .map(BaseSelector.class::cast).forEach(BaseSelector::validate);
     }
 
 
@@ -313,6 +301,30 @@
     }
 
     /**
+     * @param e ExecutableSelector
+     * @since 1.10.0
+     */
+    public void addExecutable(ExecutableSelector e) {
+        appendSelector(e);
+    }
+
+    /**
+     * @param e SymlinkSelector
+     * @since 1.10.0
+     */
+    public void addSymlink(SymlinkSelector e) {
+        appendSelector(e);
+    }
+
+    /**
+     * @param o OwnedBySelector
+     * @since 1.10.0
+     */
+    public void addOwnedBy(OwnedBySelector o) {
+        appendSelector(o);
+    }
+
+    /**
      * add an arbitrary selector
      * @param selector the selector to add
      * @since Ant 1.6
@@ -337,17 +349,23 @@
         }
     }
 
-    public synchronized Object clone() {
+    public synchronized AbstractSelectorContainer clone() {
         if (isReference()) {
-            return ((AbstractSelectorContainer) getCheckedRef()).clone();
+            return getCheckedRef().clone();
         }
         try {
             AbstractSelectorContainer sc =
                 (AbstractSelectorContainer) super.clone();
-            sc.selectorsList = new Vector<FileSelector>(selectorsList);
+            sc.selectorsList = new Vector<>(selectorsList);
             return sc;
         } catch (CloneNotSupportedException e) {
             throw new BuildException(e);
         }
     }
+
+    @Override
+    protected AbstractSelectorContainer getCheckedRef() {
+        return (AbstractSelectorContainer) super.getCheckedRef();
+    }
+
 }
diff --git a/src/main/org/apache/tools/ant/types/selectors/AndSelector.java b/src/main/org/apache/tools/ant/types/selectors/AndSelector.java
index c8e96a0..5487d41 100644
--- a/src/main/org/apache/tools/ant/types/selectors/AndSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/AndSelector.java
@@ -19,7 +19,7 @@
 package org.apache.tools.ant.types.selectors;
 
 import java.io.File;
-import java.util.Enumeration;
+import java.util.stream.Stream;
 
 /**
  * This selector has a collection of other selectors, all of which have to
@@ -30,12 +30,6 @@
 public class AndSelector extends BaseSelectorContainer {
 
     /**
-     * Default constructor.
-     */
-    public AndSelector() {
-    }
-
-    /**
      * @return a string representation of the selector
      */
     public String toString() {
@@ -60,14 +54,8 @@
      */
     public boolean isSelected(File basedir, String filename, File file) {
         validate();
-        Enumeration<FileSelector> e = selectorElements();
-
-        while (e.hasMoreElements()) {
-            if (!e.nextElement().isSelected(basedir, filename, file)) {
-                return false;
-            }
-        }
-        return true;
+        return Stream.of(getSelectors(getProject()))
+            .allMatch(s -> s.isSelected(basedir, filename, file));
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java b/src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java
index f17ca02..f65eb3f 100644
--- a/src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java
@@ -30,9 +30,8 @@
  *
  * @since 1.5
  */
-public abstract class BaseExtendSelector
-        extends BaseSelector
-        implements ExtendFileSelector {
+public abstract class BaseExtendSelector extends BaseSelector
+    implements ExtendFileSelector {
 
     // CheckStyle:VisibilityModifier OFF - bc
 
@@ -42,18 +41,13 @@
     // CheckStyle:VisibilityModifier ON
 
     /**
-     * Default constructor.
-     */
-    public BaseExtendSelector() {
-    }
-
-    /**
      * Set all the Parameters for this custom selector, collected by
      * the ExtendSelector class.
      *
      * @param parameters the complete set of parameters for this selector
      */
-    public void setParameters(Parameter[] parameters) {
+    @Override
+    public void setParameters(Parameter... parameters) {
         this.parameters = parameters;
     }
 
diff --git a/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java b/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java
index 28e0556..7ae6d80 100644
--- a/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java
@@ -37,12 +37,6 @@
     private Throwable cause;
 
     /**
-     * Do nothing constructor.
-     */
-    public BaseSelector() {
-    }
-
-    /**
      * Allows all selectors to indicate a setup error. Note that only
      * the first error message is recorded.
      *
@@ -77,7 +71,6 @@
         return errmsg;
     }
 
-
     /**
      * <p>Subclasses can override this method to provide checking of their
      * state. So long as they call validate() from isSelected(), this will
@@ -87,11 +80,10 @@
      */
     public void verifySettings() {
         if (isReference()) {
-            ((BaseSelector) getCheckedRef()).verifySettings();
+            getCheckedRef().verifySettings();
         }
     }
 
-
     /**
      * Subclasses can use this to throw the requisite exception
      * in isSelected() in the case of an error condition.
@@ -122,6 +114,10 @@
     public abstract boolean isSelected(File basedir, String filename,
                                        File file);
 
+    @Override
+    protected BaseSelector getCheckedRef() {
+        return (BaseSelector) super.getCheckedRef();
+    }
 }
 
 
diff --git a/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java b/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java
index 1edf085..fe90b38 100644
--- a/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java
+++ b/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java
@@ -19,9 +19,12 @@
 package org.apache.tools.ant.types.selectors;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.List;
 import java.util.Stack;
-import java.util.Vector;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -36,13 +39,7 @@
 public abstract class BaseSelectorContainer extends BaseSelector
         implements SelectorContainer {
 
-    private Vector<FileSelector> selectorsList = new Vector<FileSelector>();
-
-    /**
-     * Default constructor.
-     */
-    public BaseSelectorContainer() {
-    }
+    private List<FileSelector> selectorsList = Collections.synchronizedList(new ArrayList<>());
 
     /**
      * Indicates whether there are any selectors here.
@@ -50,7 +47,7 @@
      */
     public boolean hasSelectors() {
         dieOnCircularReference();
-        return !(selectorsList.isEmpty());
+        return !selectorsList.isEmpty();
     }
 
     /**
@@ -69,9 +66,7 @@
      */
     public FileSelector[] getSelectors(Project p) {
         dieOnCircularReference();
-        FileSelector[] result = new FileSelector[selectorsList.size()];
-        selectorsList.copyInto(result);
-        return result;
+        return selectorsList.toArray(new FileSelector[selectorsList.size()]);
     }
 
     /**
@@ -80,7 +75,7 @@
      */
     public Enumeration<FileSelector> selectorElements() {
         dieOnCircularReference();
-        return selectorsList.elements();
+        return Collections.enumeration(selectorsList);
     }
 
     /**
@@ -92,15 +87,8 @@
      */
     public String toString() {
         dieOnCircularReference();
-        StringBuilder buf = new StringBuilder();
-        Enumeration<FileSelector> e = selectorElements();
-        while (e.hasMoreElements()) {
-            buf.append(e.nextElement().toString());
-            if (e.hasMoreElements()) {
-                buf.append(", ");
-            }
-        }
-        return buf.toString();
+        return selectorsList.stream().map(Object::toString)
+            .collect(Collectors.joining(", "));
     }
 
     /**
@@ -109,7 +97,7 @@
      * @param selector the new selector to add
      */
     public void appendSelector(FileSelector selector) {
-        selectorsList.addElement(selector);
+        selectorsList.add(selector);
         setChecked(false);
     }
 
@@ -136,16 +124,10 @@
         if (errmsg != null) {
             throw new BuildException(errmsg);
         }
-        Enumeration<FileSelector> e = selectorElements();
-        while (e.hasMoreElements()) {
-            Object o = e.nextElement();
-            if (o instanceof BaseSelector) {
-                ((BaseSelector) o).validate();
-            }
-        }
+        selectorsList.stream().filter(BaseSelector.class::isInstance)
+            .map(BaseSelector.class::cast).forEach(BaseSelector::validate);
     }
 
-
     /**
      * Method that each selector will implement to create their selection
      * behaviour. This is what makes SelectorContainer abstract.
@@ -157,8 +139,7 @@
      * @return whether the file should be selected or not
      */
     public abstract boolean isSelected(File basedir, String filename,
-                                       File file);
-
+        File file);
 
     /* Methods below all add specific selectors */
 
@@ -316,6 +297,30 @@
     }
 
     /**
+     * @param e ExecutableSelector
+     * @since 1.10.0
+     */
+    public void addExecutable(ExecutableSelector e) {
+        appendSelector(e);
+    }
+
+    /**
+     * @param e SymlinkSelector
+     * @since 1.10.0
+     */
+    public void addSymlink(SymlinkSelector e) {
+        appendSelector(e);
+    }
+
+    /**
+     * @param o OwnedBySelector
+     * @since 1.10.0
+     */
+    public void addOwnedBy(OwnedBySelector o) {
+        appendSelector(o);
+    }
+
+    /**
      * add an arbitrary selector
      * @param selector the selector to add
      * @since Ant 1.6
diff --git a/src/main/org/apache/tools/ant/types/selectors/ContainsRegexpSelector.java b/src/main/org/apache/tools/ant/types/selectors/ContainsRegexpSelector.java
index 7140b97..b139b62 100644
--- a/src/main/org/apache/tools/ant/types/selectors/ContainsRegexpSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/ContainsRegexpSelector.java
@@ -41,12 +41,6 @@
 public class ContainsRegexpSelector extends BaseExtendSelector
         implements ResourceSelector {
 
-    private String userProvidedExpression = null;
-    private RegularExpression myRegExp = null;
-    private Regexp myExpression = null;
-    private boolean caseSensitive = true;
-    private boolean multiLine = false;
-    private boolean singleLine = false;
     /** Key to used for parameterized custom selector */
     public static final String EXPRESSION_KEY = "expression";
     /** Parameter name for the casesensitive attribute. */
@@ -56,21 +50,19 @@
     /** Parameter name for the singleline attribute. */
     private static final String SL_KEY = "singleline";
 
-    /**
-     * Creates a new <code>ContainsRegexpSelector</code> instance.
-     */
-    public ContainsRegexpSelector() {
-    }
+    private String userProvidedExpression = null;
+    private RegularExpression myRegExp = null;
+    private Regexp myExpression = null;
+    private boolean caseSensitive = true;
+    private boolean multiLine = false;
+    private boolean singleLine = false;
 
     /**
      * @return a string describing this object
      */
     public String toString() {
-        StringBuilder buf = new StringBuilder(
-                "{containsregexpselector expression: ");
-        buf.append(userProvidedExpression);
-        buf.append("}");
-        return buf.toString();
+        return String.format("{containsregexpselector expression: %s}",
+            userProvidedExpression);
     }
 
     /**
@@ -116,7 +108,7 @@
      *
      * @param parameters the complete set of parameters for this selector
      */
-    public void setParameters(Parameter[] parameters) {
+    public void setParameters(Parameter... parameters) {
         super.setParameters(parameters);
         if (parameters != null) {
             for (int i = 0; i < parameters.length; i++) {
@@ -166,11 +158,7 @@
      * @return whether the Resource is selected or not
      */
     public boolean isSelected(Resource r) {
-        String teststr = null;
-        BufferedReader in = null;
-
         // throw BuildException on error
-
         validate();
 
         if (r.isDirectory()) {
@@ -183,40 +171,25 @@
             myExpression = myRegExp.getRegexp(getProject());
         }
 
-        try {
-            in = new BufferedReader(new InputStreamReader(r.getInputStream())); //NOSONAR
-        } catch (Exception e) {
-            throw new BuildException("Could not get InputStream from "
-                    + r.toLongString(), e);
-        }
-        boolean success = false;
-        try {
-            teststr = in.readLine();
-
-            while (teststr != null) {
-
-                if (myExpression.matches(teststr,
-                                         RegexpUtil.asOptions(caseSensitive,
-                                                              multiLine,
-                                                              singleLine))) {
-                    return true;
-                }
-                teststr = in.readLine();
-            }
-            success = true;
-            return false;
-        } catch (IOException ioe) {
-            throw new BuildException("Could not read " + r.toLongString());
-        } finally {
+        try (BufferedReader in =
+            new BufferedReader(new InputStreamReader(r.getInputStream()))) {
             try {
-                in.close();
-            } catch (Exception e) {
-                if (success) {
-                    throw new BuildException("Could not close " //NOSONAR
-                                             + r.toLongString());
+                String teststr = in.readLine();
+
+                while (teststr != null) {
+                    if (myExpression.matches(teststr, RegexpUtil
+                        .asOptions(caseSensitive, multiLine, singleLine))) {
+                        return true;
+                    }
+                    teststr = in.readLine();
                 }
+                return false;
+            } catch (IOException ioe) {
+                throw new BuildException("Could not read " + r.toLongString());
             }
+        } catch (IOException e) {
+            throw new BuildException(
+                "Could not get InputStream from " + r.toLongString(), e);
         }
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java b/src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java
index a1004a8..f75367e 100644
--- a/src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java
@@ -22,6 +22,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.nio.charset.Charset;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -29,7 +30,6 @@
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.types.resources.FileResource;
 import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
-import org.apache.tools.ant.util.FileUtils;
 
 /**
  * Selector that filters files/resources based on whether they contain a
@@ -39,10 +39,6 @@
  */
 public class ContainsSelector extends BaseExtendSelector implements ResourceSelector {
 
-    private String contains = null;
-    private boolean casesensitive = true;
-    private boolean ignorewhitespace = false;
-    private String encoding = null;
     /** Key to used for parameterized custom selector */
     public static final String EXPRESSION_KEY = "expression";
     /** Used for parameterized custom selector */
@@ -52,13 +48,10 @@
     /** Used for parameterized custom selector */
     public static final String WHITESPACE_KEY = "ignorewhitespace";
 
-
-    /**
-     * Creates a new <code>ContainsSelector</code> instance.
-     *
-     */
-    public ContainsSelector() {
-    }
+    private String contains = null;
+    private boolean casesensitive = true;
+    private boolean ignorewhitespace = false;
+    private String encoding = null;
 
     /**
      * @return a string describing this object
@@ -66,10 +59,8 @@
     public String toString() {
         StringBuilder buf = new StringBuilder("{containsselector text: ");
         buf.append('"').append(contains).append('"');
-        buf.append(" casesensitive: ");
-        buf.append(casesensitive ? "true" : "false");
-        buf.append(" ignorewhitespace: ");
-        buf.append(ignorewhitespace ? "true" : "false");
+        buf.append(" casesensitive: ").append(casesensitive);
+        buf.append(" ignorewhitespace: ").append(ignorewhitespace);
         buf.append("}");
         return buf.toString();
     }
@@ -117,7 +108,7 @@
      *
      * @param parameters the complete set of parameters for this selector
      */
-    public void setParameters(Parameter[] parameters) {
+    public void setParameters(Parameter... parameters) {
         super.setParameters(parameters);
         if (parameters != null) {
             for (int i = 0; i < parameters.length; i++) {
@@ -169,11 +160,10 @@
      * @return whether the Resource is selected.
      */
     public boolean isSelected(Resource r) {
-
         // throw BuildException on error
         validate();
 
-        if (r.isDirectory() || contains.length() == 0) {
+        if (r.isDirectory() || contains.isEmpty()) {
             return true;
         }
 
@@ -184,38 +174,30 @@
         if (ignorewhitespace) {
             userstr = SelectorUtils.removeWhitespace(userstr);
         }
-        BufferedReader in = null;
-        try {
-            if (encoding != null) {
-                in = new BufferedReader(new InputStreamReader(r.getInputStream(), encoding)); //NOSONAR
-            }   else {
-                in = new BufferedReader(new InputStreamReader(r.getInputStream())); //NOSONAR
+        try (BufferedReader in = new BufferedReader(
+            new InputStreamReader(r.getInputStream(), encoding == null
+                ? Charset.defaultCharset() : Charset.forName(encoding)))) {
+            try {
+                String teststr = in.readLine();
+                while (teststr != null) {
+                    if (!casesensitive) {
+                        teststr = teststr.toLowerCase();
+                    }
+                    if (ignorewhitespace) {
+                        teststr = SelectorUtils.removeWhitespace(teststr);
+                    }
+                    if (teststr.indexOf(userstr) > -1) {
+                        return true;
+                    }
+                    teststr = in.readLine();
+                }
+                return false;
+            } catch (IOException ioe) {
+                throw new BuildException("Could not read " + r.toLongString());
             }
-        } catch (Exception e) {
-            throw new BuildException("Could not get InputStream from "
-                    + r.toLongString(), e);
-        }
-        try {
-            String teststr = in.readLine();
-            while (teststr != null) {
-                if (!casesensitive) {
-                    teststr = teststr.toLowerCase();
-                }
-                if (ignorewhitespace) {
-                    teststr = SelectorUtils.removeWhitespace(teststr);
-                }
-                if (teststr.indexOf(userstr) > -1) {
-                    return true;
-                }
-                teststr = in.readLine();
-            }
-            return false;
-        } catch (IOException ioe) {
-            throw new BuildException("Could not read " + r.toLongString());
-        } finally {
-            FileUtils.close(in);
+        } catch (IOException e) {
+            throw new BuildException(
+                "Could not get InputStream from " + r.toLongString(), e);
         }
     }
-
 }
-
diff --git a/src/main/org/apache/tools/ant/types/selectors/DateSelector.java b/src/main/org/apache/tools/ant/types/selectors/DateSelector.java
index c5ff5d5..d05a752 100644
--- a/src/main/org/apache/tools/ant/types/selectors/DateSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/DateSelector.java
@@ -36,16 +36,6 @@
  */
 public class DateSelector extends BaseExtendSelector {
 
-    /** Utilities used for file operations */
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-
-    private long millis = -1;
-    private String dateTime = null;
-    private boolean includeDirs = false;
-    private long granularity = 0;
-    private String pattern;
-    private TimeComparison when = TimeComparison.EQUAL;
-
     /** Key to used for parameterized custom selector */
     public static final String MILLIS_KEY = "millis";
     /** Key to used for parameterized custom selector */
@@ -59,13 +49,15 @@
     /** Key to used for parameterized custom selector */
     public static final String PATTERN_KEY = "pattern";
 
-    /**
-     * Creates a new <code>DateSelector</code> instance.
-     *
-     */
-    public DateSelector() {
-        granularity = FILE_UTILS.getFileTimestampGranularity();
-    }
+    /** Utilities used for file operations */
+    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+    private long millis = -1;
+    private String dateTime = null;
+    private boolean includeDirs = false;
+    private long granularity = FILE_UTILS.getFileTimestampGranularity();
+    private String pattern;
+    private TimeComparison when = TimeComparison.EQUAL;
 
     /**
      * @return a string describing this object
@@ -74,8 +66,7 @@
         StringBuilder buf = new StringBuilder("{dateselector date: ");
         buf.append(dateTime);
         buf.append(" compare: ").append(when.getValue());
-        buf.append(" granularity: ");
-        buf.append(granularity);
+        buf.append(" granularity: ").append(granularity);
         if (pattern != null) {
             buf.append(" pattern: ").append(pattern);
         }
@@ -166,7 +157,7 @@
      *
      * @param parameters the complete set of parameters for this selector.
      */
-    public void setParameters(Parameter[] parameters) {
+    public void setParameters(Parameter... parameters) {
         super.setParameters(parameters);
         if (parameters != null) {
             for (int i = 0; i < parameters.length; i++) {
@@ -239,9 +230,7 @@
      * @return whether the file is selected.
      */
     public boolean isSelected(File basedir, String filename, File file) {
-
         validate();
-
         return (file.isDirectory() && !includeDirs)
             || when.evaluate(file.lastModified(), millis, granularity);
     }
diff --git a/src/main/org/apache/tools/ant/types/selectors/DependSelector.java b/src/main/org/apache/tools/ant/types/selectors/DependSelector.java
index 01ac237..24d4eab 100644
--- a/src/main/org/apache/tools/ant/types/selectors/DependSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/DependSelector.java
@@ -31,14 +31,6 @@
 public class DependSelector extends MappingSelector {
 
     /**
-     * Creates a new <code>DependSelector</code> instance.
-     *
-     */
-    public DependSelector() {
-
-    }
-
-    /**
      * @return a string describing this object
      */
     public String toString() {
@@ -48,8 +40,7 @@
         } else {
             buf.append(targetdir.getName());
         }
-        buf.append(" granularity: ");
-        buf.append(granularity);
+        buf.append(" granularity: ").append(granularity);
         if (map != null) {
             buf.append(" mapper: ");
             buf.append(map.toString());
@@ -61,7 +52,6 @@
         return buf.toString();
     }
 
-
     /**
      * this test is our selection test that compared the file with the destfile
      * @param srcfile the source file
@@ -69,9 +59,7 @@
      * @return true if destination is out of date
      */
     public boolean selectionTest(File srcfile, File destfile) {
-        boolean selected = SelectorUtils.isOutOfDate(srcfile, destfile,
-                granularity);
-        return selected;
+        return SelectorUtils.isOutOfDate(srcfile, destfile, granularity);
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/selectors/DepthSelector.java b/src/main/org/apache/tools/ant/types/selectors/DepthSelector.java
index a80f9aa..e313983 100644
--- a/src/main/org/apache/tools/ant/types/selectors/DepthSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/DepthSelector.java
@@ -32,6 +32,11 @@
  */
 public class DepthSelector extends BaseExtendSelector {
 
+    /** Used for parameterized custom selector */
+    public static final String MIN_KEY = "min";
+    /** Used for parameterized custom selector */
+    public static final String MAX_KEY = "max";
+
     // CheckStyle:VisibilityModifier OFF - bc
 
     /** min attribute */
@@ -41,26 +46,13 @@
 
     // CheckStyle:VisibilityModifier ON
 
-    /** Used for parameterized custom selector */
-    public static final String MIN_KEY = "min";
-    /** Used for parameterized custom selector */
-    public static final String MAX_KEY = "max";
-
-    /**
-     * Creates a new <code>DepthSelector</code> instance.
-     *
-     */
-    public DepthSelector() {
-    }
-
     /**
      * @return a string describing this object
      */
     public String toString() {
-        StringBuilder buf = new StringBuilder("{depthselector min: ");
-        buf.append(min);
-        buf.append(" max: ");
-        buf.append(max);
+        StringBuilder buf = new StringBuilder("{depthselector");
+        buf.append(" min: ").append(min);
+        buf.append(" max: ").append(max);
         buf.append("}");
         return buf.toString();
     }
@@ -89,7 +81,7 @@
      *
      * @param parameters the complete set of parameters for this selector
      */
-    public void setParameters(Parameter[] parameters) {
+    public void setParameters(Parameter... parameters) {
         super.setParameters(parameters);
         if (parameters != null) {
             for (int i = 0; i < parameters.length; i++) {
@@ -121,8 +113,7 @@
      */
     public void verifySettings() {
         if (min < 0 && max < 0) {
-            setError("You must set at least one of the min or the "
-                    + "max levels.");
+            setError("You must set at least one of the min or the max levels.");
         }
         if (max < min && max > -1) {
             setError("The maximum depth is lower than the minimum.");
@@ -150,19 +141,17 @@
         // If you felt daring, you could cache the basedir absolute path
         String absBase = basedir.getAbsolutePath();
         String absFile = file.getAbsolutePath();
-        StringTokenizer tokBase = new StringTokenizer(absBase,
-                File.separator);
-        StringTokenizer tokFile = new StringTokenizer(absFile,
-                File.separator);
+        StringTokenizer tokBase = new StringTokenizer(absBase, File.separator);
+        StringTokenizer tokFile = new StringTokenizer(absFile, File.separator);
         while (tokFile.hasMoreTokens()) {
             String filetoken = tokFile.nextToken();
             if (tokBase.hasMoreTokens()) {
                 String basetoken = tokBase.nextToken();
                 // Sanity check. Ditch it if you want faster performance
                 if (!basetoken.equals(filetoken)) {
-                    throw new BuildException("File " + filename
-                            + " does not appear within " + absBase
-                            + "directory");
+                    throw new BuildException(
+                        "File %s does not appear within %s directory", filename,
+                        absBase);
                 }
             } else {
                 depth += 1;
@@ -172,14 +161,12 @@
             }
         }
         if (tokBase.hasMoreTokens()) {
-            throw new BuildException("File " + filename
-                + " is outside of " + absBase + "directory tree");
+            throw new BuildException("File %s is outside of %s directory tree",
+                filename, absBase);
         }
         if (min > -1 && depth < min) {
             return false;
         }
         return true;
     }
-
 }
-
diff --git a/src/main/org/apache/tools/ant/types/selectors/DifferentSelector.java b/src/main/org/apache/tools/ant/types/selectors/DifferentSelector.java
index 9c076fa..c987053 100644
--- a/src/main/org/apache/tools/ant/types/selectors/DifferentSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/DifferentSelector.java
@@ -55,7 +55,6 @@
     private boolean ignoreFileTimes = true;
     private boolean ignoreContents = false;
 
-
     /**
      * This flag tells the selector to ignore file times in the comparison
      * @param ignoreFileTimes if true ignore file times
@@ -63,6 +62,7 @@
     public void setIgnoreFileTimes(boolean ignoreFileTimes) {
         this.ignoreFileTimes = ignoreFileTimes;
     }
+
     /**
      * This flag tells the selector to ignore contents
      * @param ignoreContents if true ignore contents
@@ -71,6 +71,7 @@
     public void setIgnoreContents(boolean ignoreContents) {
         this.ignoreContents = ignoreContents;
     }
+
     /**
      * this test is our selection test that compared the file with the destfile
      * @param srcfile the source file
@@ -100,16 +101,15 @@
                 return true;
             }
         }
-        if (!ignoreContents) {
-            //here do a bulk comparison
-            try {
-                return !FILE_UTILS.contentEquals(srcfile, destfile);
-            } catch (IOException e) {
-                throw new BuildException("while comparing " + srcfile + " and "
-                        + destfile, e);
-            }
-        } else {
+        if (ignoreContents) {
             return false;
         }
+        //here do a bulk comparison
+        try {
+            return !FILE_UTILS.contentEquals(srcfile, destfile);
+        } catch (IOException e) {
+            throw new BuildException(
+                "while comparing " + srcfile + " and " + destfile, e);
+        }
     }
 }
diff --git a/src/main/org/apache/tools/ant/types/selectors/ExecutableSelector.java b/src/main/org/apache/tools/ant/types/selectors/ExecutableSelector.java
new file mode 100644
index 0000000..214b98f
--- /dev/null
+++ b/src/main/org/apache/tools/ant/types/selectors/ExecutableSelector.java
@@ -0,0 +1,40 @@
+/*
+ *  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.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.nio.file.Files;
+
+/**
+ * A selector that selects executable files.
+ *
+ * <p>Executable is defined in terms of {@link
+ * java.nio.file.Files#isExecutable}, this means the selector will
+ * accept any file that exists and is executable by the
+ * application.</p>
+ *
+ * @since Ant 1.10.0
+ */
+public class ExecutableSelector implements FileSelector {
+
+    public boolean isSelected(File basedir, String filename, File file) {
+        return file != null && Files.isExecutable(file.toPath());
+    }
+
+}
diff --git a/src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java b/src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java
index af8c920..c9ee75d 100644
--- a/src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java
@@ -19,7 +19,9 @@
 package org.apache.tools.ant.types.selectors;
 
 import java.io.File;
-import java.util.Vector;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 import org.apache.tools.ant.AntClassLoader;
 import org.apache.tools.ant.BuildException;
@@ -37,16 +39,11 @@
 
     private String classname = null;
     private FileSelector dynselector = null;
-    private Vector<Parameter> paramVec = new Vector<Parameter>();
+    private List<Parameter> parameters =
+        Collections.synchronizedList(new ArrayList<>());
     private Path classpath = null;
 
     /**
-     * Default constructor.
-     */
-    public ExtendSelector() {
-    }
-
-    /**
      * Sets the classname of the custom selector.
      *
      * @param classname is the class which implements this selector
@@ -61,7 +58,7 @@
     public void selectorCreate() {
         if (classname != null && classname.length() > 0) {
             try {
-                Class<?> c = null;
+                Class<?> c;
                 if (classpath == null) {
                     c = Class.forName(classname);
                 } else {
@@ -96,10 +93,9 @@
      * @param p The new Parameter object
      */
     public void addParam(Parameter p) {
-        paramVec.addElement(p);
+        parameters.add(p);
     }
 
-
     /**
      * Set the classpath to load the classname specified using an attribute.
      * @param classpath the classpath to use
@@ -166,13 +162,12 @@
         } else if (dynselector == null) {
             setError("Internal Error: The custom selector was not created");
         } else if (!(dynselector instanceof ExtendFileSelector)
-                    && (paramVec.size() > 0)) {
-            setError("Cannot set parameters on custom selector that does not "
-                    + "implement ExtendFileSelector");
+                    && !parameters.isEmpty()) {
+            setError(
+                "Cannot set parameters on custom selector that does not implement ExtendFileSelector");
         }
     }
 
-
     /**
      * Allows the custom selector to choose whether to select a file. This
      * is also where the Parameters are passed to the custom selector,
@@ -188,14 +183,12 @@
     public boolean isSelected(File basedir, String filename, File file)
             throws BuildException {
         validate();
-        if (paramVec.size() > 0 && dynselector instanceof ExtendFileSelector) {
-            Parameter[] paramArray = new Parameter[paramVec.size()];
-            paramVec.copyInto(paramArray);
+        if (!parameters.isEmpty() && dynselector instanceof ExtendFileSelector) {
             // We know that dynselector must be non-null if no error message
-            ((ExtendFileSelector) dynselector).setParameters(paramArray);
+            ((ExtendFileSelector) dynselector).setParameters(
+                parameters.toArray(new Parameter[parameters.size()]));
         }
         return dynselector.isSelected(basedir, filename, file);
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/types/selectors/FileSelector.java b/src/main/org/apache/tools/ant/types/selectors/FileSelector.java
index 614a970..f583bdf 100644
--- a/src/main/org/apache/tools/ant/types/selectors/FileSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/FileSelector.java
@@ -21,13 +21,16 @@
 import java.io.File;
 
 import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
 
 /**
  * This is the interface to be used by all selectors.
  *
  * @since 1.5
  */
-public interface FileSelector {
+public interface FileSelector extends ResourceSelector {
 
     /**
      * Method that each selector will implement to create their
@@ -44,5 +47,15 @@
     boolean isSelected(File basedir, String filename, File file)
             throws BuildException;
 
+    /**
+     * Implement a basic {@link Resource} selection that delegates to this
+     * {@link FileSelector}.
+     * @param r resource
+     * @return whether the resource is selected
+     */
+    default boolean isSelected(Resource r) {
+        return r.asOptional(FileProvider.class).map(FileProvider::getFile)
+                .map(f -> isSelected(null, null, f)).orElse(false);
+    }
 }
 
diff --git a/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java b/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java
index 1b998f9..21cc901 100644
--- a/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java
@@ -32,12 +32,6 @@
  * @since 1.5
  */
 public class FilenameSelector extends BaseExtendSelector {
-
-    private String pattern = null;
-    private String regex = null;
-    private boolean casesensitive = true;
-
-    private boolean negated = false;
     /** Used for parameterized custom selector */
     public static final String NAME_KEY = "name";
     /** Used for parameterized custom selector */
@@ -47,18 +41,17 @@
     /** Used for parameterized custom selector */
     public static final String REGEX_KEY = "regex";
 
+    private String pattern = null;
+    private String regex = null;
+    private boolean casesensitive = true;
+
+    private boolean negated = false;
+
     // caches for performance reasons
     private RegularExpression reg;
     private Regexp expression;
 
     /**
-     * Creates a new <code>FilenameSelector</code> instance.
-     *
-     */
-    public FilenameSelector() {
-    }
-
-    /**
      * @return a string describing this object
      */
     public String toString() {
@@ -129,7 +122,7 @@
      *
      * @param parameters the complete set of parameters for this selector
      */
-    public void setParameters(Parameter[] parameters) {
+    public void setParameters(Parameter... parameters) {
         super.setParameters(parameters);
         if (parameters != null) {
             for (int i = 0; i < parameters.length; i++) {
@@ -178,18 +171,16 @@
     public boolean isSelected(File basedir, String filename, File file) {
         validate();
         if (pattern != null) {
-            return (SelectorUtils.matchPath(pattern, filename,
-                                            casesensitive) == !(negated));
-        } else {
-            if (reg == null) {
-                reg = new RegularExpression();
-                reg.setPattern(regex);
-                expression = reg.getRegexp(getProject());
-            }
-            int options = RegexpUtil.asOptions(casesensitive);
-            return expression.matches(filename, options) == !negated;
+            return SelectorUtils.matchPath(pattern, filename,
+                casesensitive) == !(negated);
         }
+        if (reg == null) {
+            reg = new RegularExpression();
+            reg.setPattern(regex);
+            expression = reg.getRegexp(getProject());
+        }
+        int options = RegexpUtil.asOptions(casesensitive);
+        return expression.matches(filename, options) == !negated;
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/types/selectors/MajoritySelector.java b/src/main/org/apache/tools/ant/types/selectors/MajoritySelector.java
index 842258f..444d1c1 100644
--- a/src/main/org/apache/tools/ant/types/selectors/MajoritySelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/MajoritySelector.java
@@ -37,12 +37,6 @@
     private boolean allowtie = true;
 
     /**
-     * Default constructor.
-     */
-    public MajoritySelector() {
-    }
-
-    /**
      * @return a string describing this object
      */
     public String toString() {
@@ -93,7 +87,8 @@
         }
         if (yesvotes > novotes) {
             return true;
-        } else if (novotes > yesvotes) {
+        }
+        if (novotes > yesvotes) {
             return false;
         }
         // At this point, we know we have a tie.
diff --git a/src/main/org/apache/tools/ant/types/selectors/MappingSelector.java b/src/main/org/apache/tools/ant/types/selectors/MappingSelector.java
index 1a27494..3d94937 100644
--- a/src/main/org/apache/tools/ant/types/selectors/MappingSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/MappingSelector.java
@@ -40,20 +40,11 @@
     protected File targetdir = null;
     protected Mapper mapperElement = null;
     protected FileNameMapper map = null;
-    protected int granularity = 0;
+    protected int granularity = (int) FILE_UTILS.getFileTimestampGranularity();
 
     // CheckStyle:VisibilityModifier ON
 
     /**
-     * Creates a new <code>MappingSelector</code> instance.
-     *
-     */
-    public MappingSelector() {
-        granularity = (int) FILE_UTILS.getFileTimestampGranularity();
-    }
-
-
-    /**
      * The name of the file or directory which is checked for out-of-date
      * files.
      *
@@ -140,8 +131,7 @@
         String destname = destfiles[0];
         File destfile = FILE_UTILS.resolveFile(targetdir, destname);
 
-        boolean selected = selectionTest(file, destfile);
-        return selected;
+        return selectionTest(file, destfile);
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/types/selectors/NoneSelector.java b/src/main/org/apache/tools/ant/types/selectors/NoneSelector.java
index 536b5b5..5691514 100644
--- a/src/main/org/apache/tools/ant/types/selectors/NoneSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/NoneSelector.java
@@ -19,7 +19,7 @@
 package org.apache.tools.ant.types.selectors;
 
 import java.io.File;
-import java.util.Enumeration;
+import java.util.stream.Stream;
 
 /**
  * This selector has a collection of other selectors. All of those selectors
@@ -31,12 +31,6 @@
 public class NoneSelector extends BaseSelectorContainer {
 
     /**
-     * Default constructor.
-     */
-    public NoneSelector() {
-    }
-
-    /**
      * @return a string representation of the selector
      */
     public String toString() {
@@ -61,15 +55,8 @@
      */
     public boolean isSelected(File basedir, String filename, File file) {
         validate();
-        Enumeration<FileSelector> e = selectorElements();
-
-        while (e.hasMoreElements()) {
-            if (e.nextElement().isSelected(basedir, filename, file)) {
-                return false;
-            }
-        }
-        return true;
+        return Stream.of(getSelectors(getProject()))
+            .noneMatch(s -> s.isSelected(basedir, filename, file));
     }
 
 }
-
diff --git a/src/main/org/apache/tools/ant/types/selectors/NotSelector.java b/src/main/org/apache/tools/ant/types/selectors/NotSelector.java
index 71c3940..5ce4079 100644
--- a/src/main/org/apache/tools/ant/types/selectors/NotSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/NotSelector.java
@@ -64,8 +64,8 @@
      */
     public void verifySettings() {
         if (selectorCount() != 1) {
-            setError("One and only one selector is allowed within the "
-                + "<not> tag");
+            setError(
+                "One and only one selector is allowed within the <not> tag");
         }
     }
 
diff --git a/src/main/org/apache/tools/ant/types/selectors/OrSelector.java b/src/main/org/apache/tools/ant/types/selectors/OrSelector.java
index b077744..f98a327 100644
--- a/src/main/org/apache/tools/ant/types/selectors/OrSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/OrSelector.java
@@ -19,7 +19,7 @@
 package org.apache.tools.ant.types.selectors;
 
 import java.io.File;
-import java.util.Enumeration;
+import java.util.stream.Stream;
 
 /**
  * This selector has a collection of other selectors, any of which have to
@@ -30,12 +30,6 @@
 public class OrSelector extends BaseSelectorContainer {
 
     /**
-     * Default constructor.
-     */
-    public OrSelector() {
-    }
-
-    /**
      * @return a string representation of the selector
      */
     public String toString() {
@@ -60,15 +54,8 @@
      */
     public boolean isSelected(File basedir, String filename, File file) {
         validate();
-        Enumeration<FileSelector> e = selectorElements();
-
-        // First, check that all elements are correctly configured
-        while (e.hasMoreElements()) {
-            if (e.nextElement().isSelected(basedir, filename, file)) {
-                return true;
-            }
-        }
-        return false;
+        return Stream.of(getSelectors(getProject()))
+            .anyMatch(s -> s.isSelected(basedir, filename, file));
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/selectors/OwnedBySelector.java b/src/main/org/apache/tools/ant/types/selectors/OwnedBySelector.java
new file mode 100644
index 0000000..d37fd2f
--- /dev/null
+++ b/src/main/org/apache/tools/ant/types/selectors/OwnedBySelector.java
@@ -0,0 +1,67 @@
+/*
+ *  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.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.attribute.UserPrincipal;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * A selector that selects files based on their owner.
+ *
+ * <p>Owner is defined in terms of {@link
+ * java.nio.file.Files#getOwner}, this means the selector will accept
+ * any file that exists and is owned by the given user. If the {@code
+ * getOwner} method throws an {@code UnsupportedOperationException}
+ * the file in question is not included.</p>
+ *
+ * @since Ant 1.10.0
+ */
+public class OwnedBySelector implements FileSelector {
+
+    private String owner;
+
+    /**
+     * Sets the User-Name to look for.
+     * @param owner the user name
+     */
+    public void setOwner(String owner) {
+        this.owner = owner;
+    }
+
+    @Override
+    public boolean isSelected(File basedir, String filename, File file) {
+        if (owner == null) {
+            throw new BuildException("the owner attribute is required");
+        }
+        if (file != null) {
+            try {
+                UserPrincipal user = Files.getOwner(file.toPath());
+                return user != null && owner.equals(user.getName());
+            } catch (UnsupportedOperationException | IOException ex) {
+                // => not the expected owner
+            }
+        }
+        return false;
+    }
+
+}
diff --git a/src/main/org/apache/tools/ant/types/selectors/PresentSelector.java b/src/main/org/apache/tools/ant/types/selectors/PresentSelector.java
index 725b31e..a45c1cc 100644
--- a/src/main/org/apache/tools/ant/types/selectors/PresentSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/PresentSelector.java
@@ -42,13 +42,6 @@
     private boolean destmustexist = true;
 
     /**
-     * Creates a new <code>PresentSelector</code> instance.
-     *
-     */
-    public PresentSelector() {
-    }
-
-    /**
      * @return a string describing this object
      */
     @Override
diff --git a/src/main/org/apache/tools/ant/types/selectors/ReadableSelector.java b/src/main/org/apache/tools/ant/types/selectors/ReadableSelector.java
index b0c527c..cd03ebf 100644
--- a/src/main/org/apache/tools/ant/types/selectors/ReadableSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/ReadableSelector.java
@@ -20,10 +20,6 @@
 
 import java.io.File;
 
-import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.resources.FileProvider;
-import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
-
 /**
  * A selector that selects readable files.
  *
@@ -33,17 +29,11 @@
  *
  * @since Ant 1.8.0
  */
-public class ReadableSelector implements FileSelector, ResourceSelector {
+public class ReadableSelector implements FileSelector {
 
+    @Override
     public boolean isSelected(File basedir, String filename, File file) {
         return file != null && file.canRead();
     }
 
-    public boolean isSelected(Resource r) {
-        FileProvider fp = r.as(FileProvider.class);
-        if (fp != null) {
-            return isSelected(null, null, fp.getFile());
-        }
-        return false;
-    }
 }
\ No newline at end of file
diff --git a/src/main/org/apache/tools/ant/types/selectors/SelectSelector.java b/src/main/org/apache/tools/ant/types/selectors/SelectSelector.java
index 2089012..2a00ce5 100644
--- a/src/main/org/apache/tools/ant/types/selectors/SelectSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/SelectSelector.java
@@ -40,16 +40,10 @@
     private Object unlessCondition;
 
     /**
-     * Default constructor.
-     */
-    public SelectSelector() {
-    }
-
-    /**
      * @return a string describing this object
      */
     public String toString() {
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         if (hasSelectors()) {
             buf.append("{select");
             if (ifCondition != null) {
@@ -80,6 +74,7 @@
      * Indicates whether there are any selectors here.
      * @return whether any selectors are in this container
      */
+    @Override
     public boolean hasSelectors() {
         if (isReference()) {
             return getRef().hasSelectors();
@@ -91,6 +86,7 @@
      * Gives the count of the number of selectors in this container
      * @return the number of selectors in this container
      */
+    @Override
     public int selectorCount() {
         if (isReference()) {
             return getRef().selectorCount();
@@ -103,6 +99,7 @@
      * @param p the current project
      * @return an array of selectors in this container
      */
+    @Override
     public FileSelector[] getSelectors(Project p) {
         if (isReference()) {
             return getRef().getSelectors(p);
@@ -114,6 +111,7 @@
      * Returns an enumerator for accessing the set of selectors.
      * @return an enumerator that goes through each of the selectors
      */
+    @Override
     public Enumeration<FileSelector> selectorElements() {
         if (isReference()) {
             return getRef().selectorElements();
@@ -126,6 +124,7 @@
      *
      * @param selector the new selector to add
      */
+    @Override
     public void appendSelector(FileSelector selector) {
         if (isReference()) {
             throw noChildrenAllowed();
@@ -138,11 +137,11 @@
      * Makes sure that there is only one entry, sets an error message if
      * not.
      */
+    @Override
     public void verifySettings() {
         int cnt = selectorCount();
         if (cnt < 0 || cnt > 1) {
-            setError("Only one selector is allowed within the "
-                + "<selector> tag");
+            setError("Only one selector is allowed within the <selector> tag");
         }
     }
 
@@ -212,6 +211,7 @@
      * can use
      * @return whether the file should be selected or not
      */
+    @Override
     public boolean isSelected(File basedir, String filename, File file) {
         validate();
 
diff --git a/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java b/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java
index 277470b..baa79bd 100644
--- a/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java
+++ b/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java
@@ -159,14 +159,14 @@
         if (strIdxStart > strIdxEnd) {
             // String is exhausted
             return true;
-        } else if (patIdxStart > patIdxEnd) {
+        }
+        if (patIdxStart > patIdxEnd) {
             // String not exhausted, but pattern is. Failure.
             return false;
-        } else {
-            // pattern now holds ** while string is not exhausted
-            // this will generate false positives but we can live with that.
-            return true;
         }
+        // pattern now holds ** while string is not exhausted
+        // this will generate false positives but we can live with that.
+        return true;
     }
 
     /**
@@ -245,11 +245,10 @@
                 }
             }
             return true;
-        } else {
-            if (patIdxStart > patIdxEnd) {
-                // String not exhausted, but pattern is. Failure.
-                return false;
-            }
+        }
+        if (patIdxStart > patIdxEnd) {
+            // String not exhausted, but pattern is. Failure.
+            return false;
         }
 
         // up to last '**'
@@ -293,19 +292,17 @@
             int strLength = (strIdxEnd - strIdxStart + 1);
             int foundIdx = -1;
             strLoop:
-                        for (int i = 0; i <= strLength - patLength; i++) {
-                            for (int j = 0; j < patLength; j++) {
-                                String subPat = tokenizedPattern[patIdxStart + j + 1];
-                                String subStr = strDirs[strIdxStart + i + j];
-                                if (!match(subPat, subStr, isCaseSensitive)) {
-                                    continue strLoop;
-                                }
-                            }
-
-                            foundIdx = strIdxStart + i;
-                            break;
-                        }
-
+            for (int i = 0; i <= strLength - patLength; i++) {
+                for (int j = 0; j < patLength; j++) {
+                    String subPat = tokenizedPattern[patIdxStart + j + 1];
+                    String subStr = strDirs[strIdxStart + i + j];
+                    if (!match(subPat, subStr, isCaseSensitive)) {
+                        continue strLoop;
+                    }
+                }
+                foundIdx = strIdxStart + i;
+                break;
+            }
             if (foundIdx == -1) {
                 return false;
             }
@@ -315,11 +312,10 @@
         }
 
         for (int i = patIdxStart; i <= patIdxEnd; i++) {
-            if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
+            if (!DEEP_TREE_MATCH.equals(tokenizedPattern[i])) {
                 return false;
             }
         }
-
         return true;
     }
 
@@ -366,7 +362,6 @@
         int patIdxEnd = patArr.length - 1;
         int strIdxStart = 0;
         int strIdxEnd = strArr.length - 1;
-        char ch;
 
         boolean containsStar = false;
         for (int i = 0; i < patArr.length; i++) {
@@ -382,11 +377,9 @@
                 return false; // Pattern and string do not have the same size
             }
             for (int i = 0; i <= patIdxEnd; i++) {
-                ch = patArr[i];
-                if (ch != '?') {
-                    if (different(caseSensitive, ch, strArr[i])) {
-                        return false; // Character mismatch
-                    }
+                char ch = patArr[i];
+                if (ch != '?' && different(caseSensitive, ch, strArr[i])) {
+                    return false; // Character mismatch
                 }
             }
             return true; // String matches against pattern
@@ -398,14 +391,13 @@
 
         // Process characters before first star
         while (true) {
-            ch = patArr[patIdxStart];
+            char ch = patArr[patIdxStart];
             if (ch == '*' || strIdxStart > strIdxEnd) {
                 break;
             }
-            if (ch != '?') {
-                if (different(caseSensitive, ch, strArr[strIdxStart])) {
-                    return false; // Character mismatch
-                }
+            if (ch != '?'
+                && different(caseSensitive, ch, strArr[strIdxStart])) {
+                return false; // Character mismatch
             }
             patIdxStart++;
             strIdxStart++;
@@ -418,14 +410,12 @@
 
         // Process characters after last star
         while (true) {
-            ch = patArr[patIdxEnd];
+            char ch = patArr[patIdxEnd];
             if (ch == '*' || strIdxStart > strIdxEnd) {
                 break;
             }
-            if (ch != '?') {
-                if (different(caseSensitive, ch, strArr[strIdxEnd])) {
-                    return false; // Character mismatch
-                }
+            if (ch != '?' && different(caseSensitive, ch, strArr[strIdxEnd])) {
+                return false; // Character mismatch
             }
             patIdxEnd--;
             strIdxEnd--;
@@ -459,15 +449,12 @@
             strLoop:
             for (int i = 0; i <= strLength - patLength; i++) {
                 for (int j = 0; j < patLength; j++) {
-                    ch = patArr[patIdxStart + j + 1];
-                    if (ch != '?') {
-                        if (different(caseSensitive, ch,
-                                      strArr[strIdxStart + i + j])) {
-                            continue strLoop;
-                        }
+                    char ch = patArr[patIdxStart + j + 1];
+                    if (ch != '?' && different(caseSensitive, ch,
+                        strArr[strIdxStart + i + j])) {
+                        continue strLoop;
                     }
                 }
-
                 foundIdx = strIdxStart + i;
                 break;
             }
@@ -475,7 +462,6 @@
             if (foundIdx == -1) {
                 return false;
             }
-
             patIdxStart = patIdxTmp;
             strIdxStart = foundIdx + patLength;
         }
@@ -523,7 +509,7 @@
      * @since Ant 1.6
      */
     public static Vector<String> tokenizePath(String path, String separator) {
-        Vector<String> ret = new Vector<String>();
+        Vector<String> ret = new Vector<>();
         if (FileUtils.isAbsolutePath(path)) {
             String[] s = FILE_UTILS.dissect(path);
             ret.add(s[0]);
@@ -664,7 +650,7 @@
      * @return a String that has had all whitespace removed.
      */
     public static String removeWhitespace(String input) {
-        StringBuffer result = new StringBuffer();
+        StringBuilder result = new StringBuilder();
         if (input != null) {
             StringTokenizer st = new StringTokenizer(input);
             while (st.hasMoreTokens()) {
@@ -680,7 +666,7 @@
      * @return true if the string contains at least a star or a question mark
      */
     public static boolean hasWildcards(String input) {
-        return (input.indexOf('*') != -1 || input.indexOf('?') != -1);
+        return input.indexOf('*') != -1 || input.indexOf('?') != -1;
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/types/selectors/SignedSelector.java b/src/main/org/apache/tools/ant/types/selectors/SignedSelector.java
index cd51502..36d8785 100644
--- a/src/main/org/apache/tools/ant/types/selectors/SignedSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/SignedSelector.java
@@ -48,6 +48,7 @@
      * @param file     path to file to be selected
      * @return whether the file should be selected or not
      */
+    @Override
     public boolean isSelected(File basedir, String filename, File file) {
         if (file.isDirectory()) {
             return false; // Quick return: directories cannot be signed
diff --git a/src/main/org/apache/tools/ant/types/selectors/SizeSelector.java b/src/main/org/apache/tools/ant/types/selectors/SizeSelector.java
index 3157ee5..8022fa6 100644
--- a/src/main/org/apache/tools/ant/types/selectors/SizeSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/SizeSelector.java
@@ -62,13 +62,6 @@
     private Comparison when = Comparison.EQUAL;
 
     /**
-     * Creates a new <code>SizeSelector</code> instance.
-     *
-     */
-    public SizeSelector() {
-    }
-
-    /**
      * Returns a <code>String</code> object representing the specified
      * SizeSelector. This is "{sizeselector value: " + &lt;"compare",
      * "less", "more", "equal"&gt; + "}".
@@ -164,7 +157,8 @@
      *
      * @param parameters the complete set of parameters for this selector.
      */
-    public void setParameters(Parameter[] parameters) {
+    @Override
+    public void setParameters(Parameter... parameters) {
         super.setParameters(parameters);
         if (parameters != null) {
             for (int i = 0; i < parameters.length; i++) {
@@ -220,6 +214,7 @@
      * @param file A File object for this filename.
      * @return whether the file should be selected or not.
      */
+    @Override
     public boolean isSelected(File basedir, String filename, File file) {
 
         // throw BuildException on error
diff --git a/src/main/org/apache/tools/ant/types/selectors/SymlinkSelector.java b/src/main/org/apache/tools/ant/types/selectors/SymlinkSelector.java
new file mode 100644
index 0000000..d5df1ce
--- /dev/null
+++ b/src/main/org/apache/tools/ant/types/selectors/SymlinkSelector.java
@@ -0,0 +1,39 @@
+/*
+ *  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.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.nio.file.Files;
+
+/**
+ * A selector that selects symbolic links.
+ *
+ * <p>Executable is defined in terms of {@link
+ * java.nio.file.Files#isSymbolicLink}, this means the selector will
+ * accept any file that exists and is a symbolic link.</p>
+ *
+ * @since Ant 1.10.0
+ */
+public class SymlinkSelector implements FileSelector {
+
+    public boolean isSelected(File basedir, String filename, File file) {
+        return file != null && Files.isSymbolicLink(file.toPath());
+    }
+
+}
diff --git a/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java b/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java
index cc87786..5a63fb7 100644
--- a/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java
+++ b/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java
@@ -19,10 +19,12 @@
 package org.apache.tools.ant.types.selectors;
 
 import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.util.FileUtils;
-import org.apache.tools.ant.util.SymbolicLinkUtils;
 
 /**
  * Container for a path that has been split into its components.
@@ -38,9 +40,6 @@
 
     /** Helper. */
     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-    /** Helper. */
-    private static final SymbolicLinkUtils SYMLINK_UTILS =
-        SymbolicLinkUtils.getSymbolicLinkUtils();
     /** iterations for case-sensitive scanning. */
     private static final boolean[] CS_SCAN_ONLY = new boolean[] {true};
     /** iterations for non-case-sensitive scanning. */
@@ -141,22 +140,16 @@
      */
     public boolean isSymlink(File base) {
         for (int i = 0; i < tokenizedPath.length; i++) {
-            try {
-                if ((base != null
-                     && SYMLINK_UTILS.isSymbolicLink(base, tokenizedPath[i]))
-                    ||
-                    (base == null
-                     && SYMLINK_UTILS.isSymbolicLink(tokenizedPath[i]))
-                    ) {
-                    return true;
-                }
-                base = new File(base, tokenizedPath[i]);
-            } catch (java.io.IOException ioe) {
-                String msg = "IOException caught while checking "
-                    + "for links, couldn't get canonical path!";
-                // will be caught and redirected to Ant's logging system
-                System.err.println(msg);
+            final Path pathToTraverse;
+            if (base == null) {
+                pathToTraverse = Paths.get(tokenizedPath[i]);
+            } else {
+                pathToTraverse = Paths.get(base.toPath().toString(), tokenizedPath[i]);
             }
+            if (Files.isSymbolicLink(pathToTraverse)) {
+                return true;
+            }
+            base = new File(base, tokenizedPath[i]);
         }
         return false;
     }
@@ -193,8 +186,8 @@
             }
             String[] files = base.list();
             if (files == null) {
-                throw new BuildException("IO error scanning directory "
-                                         + base.getAbsolutePath());
+                throw new BuildException("IO error scanning directory %s",
+                    base.getAbsolutePath());
             }
             boolean found = false;
             boolean[] matchCase = cs ? CS_SCAN_ONLY : CS_THEN_NON_CS;
diff --git a/src/main/org/apache/tools/ant/types/selectors/TokenizedPattern.java b/src/main/org/apache/tools/ant/types/selectors/TokenizedPattern.java
index 2f1be2f..03d5e3b 100644
--- a/src/main/org/apache/tools/ant/types/selectors/TokenizedPattern.java
+++ b/src/main/org/apache/tools/ant/types/selectors/TokenizedPattern.java
@@ -19,6 +19,8 @@
 package org.apache.tools.ant.types.selectors;
 
 import java.io.File;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 /**
  * Provides reusable path pattern matching.  PathPattern is preferable
@@ -125,12 +127,7 @@
      * @return boolean
      */
     public boolean containsPattern(String pat) {
-        for (int i = 0; i < tokenizedPattern.length; i++) {
-            if (tokenizedPattern[i].equals(pat)) {
-                return true;
-            }
-        }
-        return false;
+        return Stream.of(tokenizedPattern).anyMatch(Predicate.isEqual(pat));
     }
 
     /**
@@ -179,16 +176,16 @@
     public TokenizedPattern withoutLastToken() {
         if (tokenizedPattern.length == 0) {
             throw new IllegalStateException("can't strip a token from nothing");
-        } else if (tokenizedPattern.length == 1) {
-            return EMPTY_PATTERN;
-        } else {
-            String toStrip = tokenizedPattern[tokenizedPattern.length - 1];
-            int index = pattern.lastIndexOf(toStrip);
-            String[] tokens = new String[tokenizedPattern.length - 1];
-            System.arraycopy(tokenizedPattern, 0, tokens, 0,
-                             tokenizedPattern.length - 1);
-            return new TokenizedPattern(pattern.substring(0, index), tokens);
         }
+        if (tokenizedPattern.length == 1) {
+            return EMPTY_PATTERN;
+        }
+        String toStrip = tokenizedPattern[tokenizedPattern.length - 1];
+        int index = pattern.lastIndexOf(toStrip);
+        String[] tokens = new String[tokenizedPattern.length - 1];
+        System.arraycopy(tokenizedPattern, 0, tokens, 0,
+                         tokenizedPattern.length - 1);
+        return new TokenizedPattern(pattern.substring(0, index), tokens);
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/types/selectors/TypeSelector.java b/src/main/org/apache/tools/ant/types/selectors/TypeSelector.java
index fd3684d..5d09c17 100644
--- a/src/main/org/apache/tools/ant/types/selectors/TypeSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/TypeSelector.java
@@ -30,17 +30,10 @@
  */
 public class TypeSelector extends BaseExtendSelector {
 
-    private String type = null;
-
     /** Key to used for parameterized custom selector */
     public static final String TYPE_KEY = "type";
 
-    /**
-     * Creates a new <code>TypeSelector</code> instance.
-     *
-     */
-    public TypeSelector() {
-    }
+    private String type = null;
 
     /**
      * @return a string describing this object
@@ -66,7 +59,8 @@
      *
      * @param parameters the complete set of parameters for this selector
      */
-    public void setParameters(Parameter[] parameters) {
+    @Override
+    public void setParameters(Parameter... parameters) {
         super.setParameters(parameters);
         if (parameters != null) {
             for (int i = 0; i < parameters.length; i++) {
@@ -87,6 +81,7 @@
      * means that the pattern attribute has been set.
      *
      */
+    @Override
     public void verifySettings() {
         if (type == null) {
             setError("The type attribute is required");
@@ -102,6 +97,7 @@
      * @param file is a java.io.File object the selector can use
      * @return whether the file should be selected or not
      */
+    @Override
     public boolean isSelected(File basedir, String filename, File file) {
 
         // throw BuildException on error
@@ -109,9 +105,8 @@
 
         if (file.isDirectory()) {
             return type.equals(FileType.DIR);
-        } else {
-            return type.equals(FileType.FILE);
         }
+        return type.equals(FileType.FILE);
     }
 
     /**
@@ -126,10 +121,10 @@
         /**
          * @return the values as an array of strings
          */
+        @Override
         public String[] getValues() {
             return new String[]{FILE, DIR};
         }
     }
 
-
 }
diff --git a/src/main/org/apache/tools/ant/types/selectors/WritableSelector.java b/src/main/org/apache/tools/ant/types/selectors/WritableSelector.java
index 6ffd571..e7870a7 100644
--- a/src/main/org/apache/tools/ant/types/selectors/WritableSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/WritableSelector.java
@@ -20,10 +20,6 @@
 
 import java.io.File;
 
-import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.resources.FileProvider;
-import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
-
 /**
  * A selector that selects writable files.
  *
@@ -33,14 +29,11 @@
  *
  * @since Ant 1.8.0
  */
-public class WritableSelector implements FileSelector, ResourceSelector {
+public class WritableSelector implements FileSelector {
 
+    @Override
     public boolean isSelected(File basedir, String filename, File file) {
         return file != null && file.canWrite();
     }
 
-    public boolean isSelected(Resource r) {
-        FileProvider fp = r.as(FileProvider.class);
-        return fp != null && isSelected(null, null, fp.getFile());
-    }
 }
\ No newline at end of file
diff --git a/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ChecksumAlgorithm.java b/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ChecksumAlgorithm.java
index d497f14..9d9e158 100644
--- a/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ChecksumAlgorithm.java
+++ b/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ChecksumAlgorithm.java
@@ -20,7 +20,7 @@
 
 import java.io.BufferedInputStream;
 import java.io.File;
-import java.io.FileInputStream;
+import java.nio.file.Files;
 import java.security.NoSuchAlgorithmException;
 import java.util.Locale;
 import java.util.zip.Adler32;
@@ -105,6 +105,7 @@
      * This algorithm supports only CRC and Adler.
      * @return <i>true</i> if all is ok, otherwise <i>false</i>.
      */
+    @Override
     public boolean isValid() {
         return "CRC".equals(algorithm) || "ADLER".equals(algorithm);
     }
@@ -115,26 +116,22 @@
      * @param file    File object for which the value should be evaluated.
      * @return        The value for that file
      */
+    @Override
     public String getValue(File file) {
         initChecksum();
-        String rval = null;
 
-        try {
-            if (file.canRead()) {
-                 checksum.reset();
-                 FileInputStream fis = new FileInputStream(file);
-                 CheckedInputStream check = new CheckedInputStream(fis, checksum);
-                 BufferedInputStream in = new BufferedInputStream(check);
-                 while (in.read() != -1) {
-                     // Read the file
-                 }
-                 rval = Long.toString(check.getChecksum().getValue());
-                 in.close();
+        if (file.canRead()) {
+            checksum.reset();
+            try (CheckedInputStream check = new CheckedInputStream(
+                new BufferedInputStream(Files.newInputStream(file.toPath())), checksum)) {
+                // Read the file
+                while (check.read() != -1) {
+                }
+                return Long.toString(check.getChecksum().getValue());
+            } catch (Exception ignored) {
             }
-        } catch (Exception e) {
-            rval = null;
         }
-        return rval;
+        return null;
     }
 
 
@@ -142,11 +139,8 @@
      * Override Object.toString().
      * @return some information about this algorithm.
      */
+    @Override
     public String toString() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<ChecksumAlgorithm:");
-        buf.append("algorithm=").append(algorithm);
-        buf.append(">");
-        return buf.toString();
+        return String.format("<ChecksumAlgorithm:algorithm=%s>", algorithm);
     }
 }
diff --git a/src/main/org/apache/tools/ant/types/selectors/modifiedselector/DigestAlgorithm.java b/src/main/org/apache/tools/ant/types/selectors/modifiedselector/DigestAlgorithm.java
index a4b2ffd..d8f7cc9 100644
--- a/src/main/org/apache/tools/ant/types/selectors/modifiedselector/DigestAlgorithm.java
+++ b/src/main/org/apache/tools/ant/types/selectors/modifiedselector/DigestAlgorithm.java
@@ -20,7 +20,7 @@
 
 
 import java.io.File;
-import java.io.FileInputStream;
+import java.nio.file.Files;
 import java.security.DigestInputStream;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -119,10 +119,8 @@
         if ((provider != null) && !"".equals(provider) && !"null".equals(provider)) {
             try {
                 messageDigest = MessageDigest.getInstance(algorithm, provider);
-            } catch (NoSuchAlgorithmException noalgo) {
-                throw new BuildException(noalgo);
-            } catch (NoSuchProviderException noprovider) {
-                throw new BuildException(noprovider);
+            } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
+                throw new BuildException(e);
             }
         } else {
             try {
@@ -141,69 +139,55 @@
      * This algorithm supports only MD5 and SHA.
      * @return <i>true</i> if all is ok, otherwise <i>false</i>.
      */
+    @Override
     public boolean isValid() {
         return "SHA".equals(algorithm) || "MD5".equals(algorithm);
     }
 
-
     /**
      * Computes a value for a file content with the specified digest algorithm.
      * @param file    File object for which the value should be evaluated.
      * @return        The value for that file
      */
     // implementation adapted from ...taskdefs.Checksum, thanks to Magesh for hint
+    @Override
     public String getValue(File file) {
         initMessageDigest();
-        String checksum = null;
         try {
-            if (!file.canRead()) {
-                return null;
-            }
-            FileInputStream fis = null;
-
-            byte[] buf = new byte[readBufferSize];
-            try {
+            if (file.canRead()) {
+                byte[] buf = new byte[readBufferSize];
                 messageDigest.reset();
-                fis = new FileInputStream(file);
-                DigestInputStream dis = new DigestInputStream(fis,
-                                                              messageDigest);
-                while (dis.read(buf, 0, readBufferSize) != -1) {
-                    // do nothing
-                }
-                dis.close();
-                fis.close();
-                fis = null;
-                byte[] fileDigest = messageDigest.digest();
-                StringBuffer checksumSb = new StringBuffer();
-                for (int i = 0; i < fileDigest.length; i++) {
-                    String hexStr
-                        = Integer.toHexString(BYTE_MASK & fileDigest[i]);
-                    if (hexStr.length() < 2) {
-                        checksumSb.append("0");
+                try (DigestInputStream dis = new DigestInputStream(
+                    Files.newInputStream(file.toPath()), messageDigest)) {
+                    // read the whole stream
+                    while (dis.read(buf, 0, readBufferSize) != -1) {
                     }
-                    checksumSb.append(hexStr);
+                    byte[] fileDigest = messageDigest.digest();
+                    StringBuilder checksumSb = new StringBuilder();
+                    for (int i = 0; i < fileDigest.length; i++) {
+                        String hexStr =
+                            Integer.toHexString(BYTE_MASK & fileDigest[i]);
+                        if (hexStr.length() < 2) {
+                            checksumSb.append('0');
+                        }
+                        checksumSb.append(hexStr);
+                    }
+                    return checksumSb.toString();
+                } catch (Exception ignored) {
                 }
-                checksum = checksumSb.toString();
-            } catch (Exception e) {
-                return null;
             }
-        } catch (Exception e) {
-            return null;
+        } catch (Exception ignored) {
         }
-        return checksum;
+        return null;
     }
 
-
     /**
      * Override Object.toString().
      * @return some information about this algorithm.
      */
+    @Override
     public String toString() {
-        StringBuilder buf = new StringBuilder();
-        buf.append("<DigestAlgorithm:");
-        buf.append("algorithm=").append(algorithm);
-        buf.append(";provider=").append(provider);
-        buf.append(">");
-        return buf.toString();
+        return String.format("<DigestAlgorithm:algorithm=%s;provider=%s>",
+            algorithm, provider);
     }
 }
diff --git a/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java b/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java
index 0899f91..3592041 100644
--- a/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java
@@ -21,9 +21,10 @@
 
 // Java
 import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Comparator;
-import java.util.Iterator;
-import java.util.Vector;
+import java.util.List;
 
 import org.apache.tools.ant.BuildEvent;
 import org.apache.tools.ant.BuildException;
@@ -209,7 +210,8 @@
      * Parameter vector with parameters for later initialization.
      * @see #configure
      */
-    private Vector<Parameter> configParameter = new Vector<Parameter>();
+    private List<Parameter> configParameter =
+        Collections.synchronizedList(new ArrayList<>());
 
     /**
      * Parameter vector with special parameters for later initialization.
@@ -217,7 +219,8 @@
      * These parameters are used <b>after</b> the parameters with the pattern '*'.
      * @see #configure
      */
-    private Vector<Parameter> specialParameter = new Vector<Parameter>();
+    private List<Parameter> specialParameter =
+        Collections.synchronizedList(new ArrayList<>());
 
     /** The classloader of this class. */
     private ClassLoader myClassLoader = null;
@@ -238,6 +241,7 @@
 
 
     /** Overrides BaseSelector.verifySettings(). */
+    @Override
     public void verifySettings() {
         configure();
         if (cache == null) {
@@ -283,7 +287,7 @@
         //
         Project p = getProject();
         String filename = "cache.properties";
-        File cachefile = null;
+        File cachefile;
         if (p != null) {
             // normal use inside Ant
             cachefile = new File(p.getBaseDir(), filename);
@@ -303,14 +307,14 @@
         // -----  Set the main attributes, pattern '*'  -----
         //
         for (Parameter parameter : configParameter) {
-            if (parameter.getName().indexOf(".") > 0) {
+            if (parameter.getName().indexOf('.') > 0) {
                 // this is a *.* parameter for later use
                 specialParameter.add(parameter);
             } else {
                 useParameter(parameter);
             }
         }
-        configParameter = new Vector<Parameter>();
+        configParameter.clear();
 
         // specify the algorithm classname
         if (algoName != null) {
@@ -322,17 +326,15 @@
             } else if ("checksum".equals(algoName.getValue())) {
                 algorithm = new ChecksumAlgorithm();
             }
+        } else if (algorithmClass != null) {
+            // use Algorithm specified by classname
+            algorithm = loadClass(
+                algorithmClass,
+                "is not an Algorithm.",
+                Algorithm.class);
         } else {
-            if (algorithmClass != null) {
-                // use Algorithm specified by classname
-                algorithm = loadClass(
-                    algorithmClass,
-                    "is not an Algorithm.",
-                    Algorithm.class);
-            } else {
-                // nothing specified - use default
-                algorithm = defaultAlgorithm;
-            }
+            // nothing specified - use default
+            algorithm = defaultAlgorithm;
         }
 
         // specify the cache classname
@@ -341,14 +343,12 @@
             if ("propertyfile".equals(cacheName.getValue())) {
                 cache = new PropertiesfileCache();
             }
+        } else if (cacheClass != null) {
+            // use Cache specified by classname
+            cache = loadClass(cacheClass, "is not a Cache.", Cache.class);
         } else {
-            if (cacheClass != null) {
-                // use Cache specified by classname
-                cache = loadClass(cacheClass, "is not a Cache.", Cache.class);
-            } else {
-                // nothing specified - use default
-                cache = defaultCache;
-            }
+            // nothing specified - use default
+            cache = defaultCache;
         }
 
         // specify the comparator classname
@@ -364,26 +364,22 @@
                 // Have to think about lazy initialization here...  JHM
                 // comparator = new java.text.RuleBasedCollator();
             }
+        } else if (comparatorClass != null) {
+            // use Algorithm specified by classname
+            @SuppressWarnings("unchecked")
+            Comparator<? super String> localComparator = loadClass(
+                comparatorClass, "is not a Comparator.", Comparator.class);
+            comparator = localComparator;
         } else {
-            if (comparatorClass != null) {
-                // use Algorithm specified by classname
-                @SuppressWarnings("unchecked")
-                Comparator<? super String> localComparator = loadClass(comparatorClass, "is not a Comparator.", Comparator.class);
-                comparator = localComparator;
-            } else {
-                // nothing specified - use default
-                comparator = defaultComparator;
-            }
+            // nothing specified - use default
+            comparator = defaultComparator;
         }
 
         //
         // -----  Set the special attributes, pattern '*.*'  -----
         //
-        for (Iterator<Parameter> itSpecial = specialParameter.iterator(); itSpecial.hasNext();) {
-            Parameter par = itSpecial.next();
-            useParameter(par);
-        }
-        specialParameter = new Vector<Parameter>();
+        specialParameter.forEach(this::useParameter);
+        specialParameter.clear();
     }
 
 
@@ -401,21 +397,22 @@
         try {
             // load the specified class
             ClassLoader cl = getClassLoader();
-            Class<?> clazz = null;
+            Class<?> clazz;
             if (cl != null) {
                 clazz = cl.loadClass(classname);
             } else {
                 clazz = Class.forName(classname);
             }
 
-            Object rv = clazz.newInstance();
+            @SuppressWarnings("unchecked")
+            T rv = (T) clazz.newInstance();
 
             if (!type.isInstance(rv)) {
-                throw new BuildException("Specified class (" + classname + ") " + msg);
+                throw new BuildException("Specified class (%s) %s", classname, msg);
             }
-            return (T) rv;
+            return rv;
         } catch (ClassNotFoundException e) {
-            throw new BuildException("Specified class (" + classname + ") not found.");
+            throw new BuildException("Specified class (%s) not found.", classname);
         } catch (Exception e) {
             throw new BuildException(e);
         }
@@ -432,6 +429,7 @@
      * @return whether the resource is selected
      * @see ResourceSelector#isSelected(Resource)
      */
+    @Override
     public boolean isSelected(Resource resource) {
         if (resource.isFilesystemOnly()) {
             // We have a 'resourced' file, so reconvert it and use
@@ -441,30 +439,29 @@
             String filename = fileResource.getName();
             File basedir = fileResource.getBaseDir();
             return isSelected(basedir, filename, file);
-        } else {
-            try {
-                // How to handle non-file-Resources? I copy temporarily the
-                // resource to a file and use the file-implementation.
-                FileUtils fu = FileUtils.getFileUtils();
-                File tmpFile = fu.createTempFile("modified-", ".tmp", null, true, false);
-                Resource tmpResource = new FileResource(tmpFile);
-                ResourceUtils.copyResource(resource, tmpResource);
-                boolean isSelected = isSelected(tmpFile.getParentFile(),
-                                                tmpFile.getName(),
-                                                resource.toLongString());
-                tmpFile.delete();
-                return isSelected;
-            } catch (UnsupportedOperationException uoe) {
-                log("The resource '"
-                  + resource.getName()
-                  + "' does not provide an InputStream, so it is not checked. "
-                  + "According to 'selres' attribute value it is "
-                  + ((selectResourcesWithoutInputStream) ? "" : " not")
-                  + "selected.", Project.MSG_INFO);
-                return selectResourcesWithoutInputStream;
-            } catch (Exception e) {
-                throw new BuildException(e);
-            }
+        }
+        try {
+            // How to handle non-file-Resources? I copy temporarily the
+            // resource to a file and use the file-implementation.
+            FileUtils fu = FileUtils.getFileUtils();
+            File tmpFile = fu.createTempFile("modified-", ".tmp", null, true, false);
+            Resource tmpResource = new FileResource(tmpFile);
+            ResourceUtils.copyResource(resource, tmpResource);
+            boolean isSelected = isSelected(tmpFile.getParentFile(),
+                                            tmpFile.getName(),
+                                            resource.toLongString());
+            tmpFile.delete();
+            return isSelected;
+        } catch (UnsupportedOperationException uoe) {
+            log("The resource '"
+              + resource.getName()
+              + "' does not provide an InputStream, so it is not checked. "
+              + "According to 'selres' attribute value it is "
+              + ((selectResourcesWithoutInputStream) ? "" : " not")
+              + "selected.", Project.MSG_INFO);
+            return selectResourcesWithoutInputStream;
+        } catch (Exception e) {
+            throw new BuildException(e);
         }
     }
 
@@ -477,11 +474,11 @@
      * @param file as described in BaseExtendSelector
      * @return as described in BaseExtendSelector
      */
+    @Override
     public boolean isSelected(File basedir, String filename, File file) {
         return isSelected(basedir, filename, file.getAbsolutePath());
     }
 
-
     /**
      * The business logic of this selector for use as ResourceSelector of
      * FileSelector.
@@ -504,7 +501,7 @@
         String cachedValue = String.valueOf(cache.get(f.getAbsolutePath()));
         String newValue = algorithm.getValue(f);
 
-        boolean rv = (comparator.compare(cachedValue, newValue) != 0);
+        boolean rv = comparator.compare(cachedValue, newValue) != 0;
 
         // Maybe update the cache
         if (update && rv) {
@@ -514,7 +511,6 @@
                 saveCache();
             }
         }
-
         return rv;
     }
 
@@ -694,10 +690,11 @@
      * @see #addParam(String,Object)
      * @param parameters the parameters to set.
      */
-    public void setParameters(Parameter[] parameters) {
+    @Override
+    public void setParameters(Parameter... parameters) {
         if (parameters != null) {
-            for (int i = 0; i < parameters.length; i++) {
-                configParameter.add(parameters[i]);
+            for (Parameter p : parameters) {
+                configParameter.add(p);
             }
         }
     }
@@ -732,23 +729,11 @@
             cn.setValue(value);
             setComparator(cn);
         } else if ("update".equals(key)) {
-            boolean updateValue =
-                ("true".equalsIgnoreCase(value))
-                ? true
-                : false;
-            setUpdate(updateValue);
+            setUpdate("true".equalsIgnoreCase(value));
         } else if ("delayupdate".equals(key)) {
-            boolean updateValue =
-                ("true".equalsIgnoreCase(value))
-                ? true
-                : false;
-            setDelayUpdate(updateValue);
+            setDelayUpdate("true".equalsIgnoreCase(value));
         } else if ("seldirs".equals(key)) {
-            boolean sdValue =
-                ("true".equalsIgnoreCase(value))
-                ? true
-                : false;
-            setSeldirs(sdValue);
+            setSeldirs("true".equalsIgnoreCase(value));
         } else if (key.startsWith(CACHE_PREFIX)) {
             String name = key.substring(CACHE_PREFIX.length());
             tryToSetAParameter(cache, name, value);
@@ -777,7 +762,7 @@
             = IntrospectionHelper.getHelper(prj, obj.getClass());
         try {
             iHelper.setAttribute(prj, obj, name, value);
-        } catch (org.apache.tools.ant.BuildException e) {
+        } catch (BuildException e) {
             // no-op
         }
     }
@@ -790,8 +775,9 @@
      * Override Object.toString().
      * @return information about this selector
      */
+    @Override
     public String toString() {
-        StringBuffer buf = new StringBuffer("{modifiedselector");
+        StringBuilder buf = new StringBuilder("{modifiedselector");
         buf.append(" update=").append(update);
         buf.append(" seldirs=").append(selectDirectories);
         buf.append(" cache=").append(cache);
@@ -808,7 +794,8 @@
     /**
      * Signals that the last target has finished.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void buildFinished(BuildEvent event) {
         if (getDelayUpdate()) {
             saveCache();
@@ -819,7 +806,8 @@
     /**
      * Signals that a target has finished.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void targetFinished(BuildEvent event) {
         if (getDelayUpdate()) {
             saveCache();
@@ -830,7 +818,8 @@
     /**
      * Signals that a task has finished.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void taskFinished(BuildEvent event) {
         if (getDelayUpdate()) {
             saveCache();
@@ -841,7 +830,8 @@
     /**
      * Signals that a build has started.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void buildStarted(BuildEvent event) {
         // no-op
     }
@@ -850,7 +840,8 @@
     /**
      * Signals that a target is starting.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void targetStarted(BuildEvent event) {
         // no-op
     }
@@ -860,7 +851,8 @@
     /**
      * Signals that a task is starting.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void taskStarted(BuildEvent event) {
         // no-op
     }
@@ -869,7 +861,8 @@
     /**
      * Signals a message logging event.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void messageLogged(BuildEvent event) {
         // no-op
     }
@@ -904,6 +897,7 @@
          * {@inheritDoc}
          * @see EnumeratedAttribute#getValues()
          */
+        @Override
         public String[] getValues() {
             return new String[] {"propertyfile"};
         }
@@ -934,6 +928,7 @@
          * {@inheritDoc}
          * @see EnumeratedAttribute#getValues()
          */
+        @Override
         public String[] getValues() {
             return new String[] {"hashvalue", "digest", "checksum"};
         }
@@ -964,6 +959,7 @@
          * {@inheritDoc}
          * @see EnumeratedAttribute#getValues()
          */
+        @Override
         public String[] getValues() {
             return new String[] {"equal", "rule"};
         }
diff --git a/src/main/org/apache/tools/ant/types/selectors/modifiedselector/PropertiesfileCache.java b/src/main/org/apache/tools/ant/types/selectors/modifiedselector/PropertiesfileCache.java
index c856d56..f7392d2 100644
--- a/src/main/org/apache/tools/ant/types/selectors/modifiedselector/PropertiesfileCache.java
+++ b/src/main/org/apache/tools/ant/types/selectors/modifiedselector/PropertiesfileCache.java
@@ -22,12 +22,9 @@
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.util.Enumeration;
+import java.nio.file.Files;
 import java.util.Iterator;
 import java.util.Properties;
-import java.util.Vector;
 
 
 /**
@@ -119,6 +116,7 @@
      * This cache is valid if the cachefile is set.
      * @return true if all is ok false otherwise
      */
+    @Override
     public boolean isValid() {
         return (cachefile != null);
     }
@@ -130,13 +128,12 @@
     /**
      * Load the cache from underlying properties file.
      */
+    @Override
     public void load() {
         if ((cachefile != null) && cachefile.isFile() && cachefile.canRead()) {
-            try {
-                BufferedInputStream bis = new BufferedInputStream(
-                    new FileInputStream(cachefile));
+            try (BufferedInputStream bis = new BufferedInputStream(
+                Files.newInputStream(cachefile.toPath()))) {
                 cache.load(bis);
-                bis.close();
             } catch (Exception e) {
                 e.printStackTrace(); //NOSONAR
             }
@@ -153,17 +150,16 @@
      * implementation checks the existence of entries before creating the file
      * for performance optimisation.
      */
+    @Override
     public void save() {
         if (!cacheDirty) {
             return;
         }
         if ((cachefile != null) && cache.propertyNames().hasMoreElements()) {
-            try {
-                BufferedOutputStream bos = new BufferedOutputStream(
-                      new FileOutputStream(cachefile));
+            try (BufferedOutputStream bos = new BufferedOutputStream(
+                Files.newOutputStream(cachefile.toPath()))) {
                 cache.store(bos, null);
                 bos.flush();
-                bos.close();
             } catch (Exception e) {
                 e.printStackTrace(); //NOSONAR
             }
@@ -172,6 +168,7 @@
     }
 
     /** Deletes the cache and its underlying file. */
+    @Override
     public void delete() {
         cache = new Properties();
         cachefile.delete();
@@ -184,6 +181,7 @@
      * @param key the key
      * @return the stored value
      */
+    @Override
     public Object get(Object key) {
         if (!cacheLoaded) {
             load();
@@ -200,6 +198,7 @@
      * @param key the key
      * @param value the value
      */
+    @Override
     public void put(Object key, Object value) {
         cache.put(String.valueOf(key), String.valueOf(value));
         cacheDirty = true;
@@ -209,13 +208,9 @@
      * Returns an iterator over the keys in the cache.
      * @return An iterator over the keys.
      */
+    @Override
     public Iterator<String> iterator() {
-        Vector<String> v = new Vector<String>();
-        Enumeration<?> en = cache.propertyNames();
-        while (en.hasMoreElements()) {
-            v.add(en.nextElement().toString());
-        }
-        return v.iterator();
+        return cache.stringPropertyNames().iterator();
     }
 
 
@@ -226,8 +221,9 @@
      * Override Object.toString().
      * @return information about this cache
      */
+    @Override
     public String toString() {
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         buf.append("<PropertiesfileCache:");
         buf.append("cachefile=").append(cachefile);
         buf.append(";noOfEntries=").append(cache.size());
diff --git a/src/main/org/apache/tools/ant/types/spi/Provider.java b/src/main/org/apache/tools/ant/types/spi/Provider.java
index f73b019..bf9f13d 100644
--- a/src/main/org/apache/tools/ant/types/spi/Provider.java
+++ b/src/main/org/apache/tools/ant/types/spi/Provider.java
@@ -55,7 +55,7 @@
                 "classname attribute must be set for provider element",
                 getLocation());
         }
-        if (type.length() == 0) {
+        if (type.isEmpty()) {
             throw new BuildException(
                 "Invalid empty classname", getLocation());
         }
diff --git a/src/main/org/apache/tools/ant/types/spi/Service.java b/src/main/org/apache/tools/ant/types/spi/Service.java
index 96c8e4e..064bd08 100644
--- a/src/main/org/apache/tools/ant/types/spi/Service.java
+++ b/src/main/org/apache/tools/ant/types/spi/Service.java
@@ -18,13 +18,11 @@
 package org.apache.tools.ant.types.spi;
 
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.ProjectComponent;
@@ -36,7 +34,7 @@
  * http://issues.apache.org/bugzilla/show_bug.cgi?id=31520</a>
  */
 public class Service extends ProjectComponent {
-    private List<Provider> providerList = new ArrayList<Provider>();
+    private List<Provider> providerList = new ArrayList<>();
     private String type;
 
     /**
@@ -83,14 +81,9 @@
      * @throws IOException if there is an error.
      */
     public InputStream getAsStream() throws IOException {
-        ByteArrayOutputStream arrayOut = new ByteArrayOutputStream();
-        Writer writer = new OutputStreamWriter(arrayOut, "UTF-8");
-        for (Provider provider : providerList) {
-            writer.write(provider.getClassName());
-            writer.write("\n");
-        }
-        writer.close();
-        return new ByteArrayInputStream(arrayOut.toByteArray());
+        return new ByteArrayInputStream(
+            providerList.stream().map(Provider::getClassName)
+                .collect(Collectors.joining("\n")).getBytes("UTF-8"));
     }
 
     /**
@@ -107,7 +100,7 @@
             throw new BuildException(
                 "Invalid empty type classname", getLocation());
         }
-        if (providerList.size() == 0) {
+        if (providerList.isEmpty()) {
             throw new BuildException(
                 "provider attribute or nested provider element must be set!",
                 getLocation());
diff --git a/src/main/org/apache/tools/ant/util/ChainedMapper.java b/src/main/org/apache/tools/ant/util/ChainedMapper.java
index 635a053..e47043a 100644
--- a/src/main/org/apache/tools/ant/util/ChainedMapper.java
+++ b/src/main/org/apache/tools/ant/util/ChainedMapper.java
@@ -18,10 +18,7 @@
 
 package org.apache.tools.ant.util;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
+import java.util.stream.Stream;
 
 /**
  * A <code>ContainerMapper</code> that chains the results of the first
@@ -32,29 +29,13 @@
 public class ChainedMapper extends ContainerMapper {
 
     /** {@inheritDoc}. */
+    @Override
     public String[] mapFileName(String sourceFileName) {
-        List inputs = new ArrayList();
-        List results = new ArrayList();
-        results.add(sourceFileName);
-        FileNameMapper mapper = null;
-
-        for (Iterator mIter = getMappers().iterator(); mIter.hasNext();) {
-            mapper = (FileNameMapper) (mIter.next());
-            if (mapper != null) {
-                inputs.clear();
-                inputs.addAll(results);
-                results.clear();
-
-                for (Iterator it = inputs.iterator(); it.hasNext();) {
-                    String[] mapped = mapper.mapFileName((String) (it.next()));
-                    if (mapped != null) {
-                        results.addAll(Arrays.asList(mapped));
-                    }
-                }
-            }
-        }
-        return (results.size() == 0) ? null
-            : (String[]) results.toArray(new String[results.size()]);
+        String[] result = getMappers().stream()
+            .reduce(new String[] { sourceFileName }, (i, m) -> Stream.of(i)
+                .map(m::mapFileName).flatMap(Stream::of).toArray(String[]::new),
+                (i, o) -> o);
+        return result == null || result.length == 0 ? null : result;
     }
 }
 
diff --git a/src/main/org/apache/tools/ant/util/ClasspathUtils.java b/src/main/org/apache/tools/ant/util/ClasspathUtils.java
index 8b24610..acfd2b0 100644
--- a/src/main/org/apache/tools/ant/util/ClasspathUtils.java
+++ b/src/main/org/apache/tools/ant/util/ClasspathUtils.java
@@ -107,8 +107,9 @@
         String pathId = ref.getRefId();
         Object path = p.getReference(pathId);
         if (!(path instanceof Path)) {
-            throw new BuildException("The specified classpathref " + pathId
-                    + " does not reference a Path.");
+            throw new BuildException(
+                "The specified classpathref %s does not reference a Path.",
+                pathId);
         }
         String loaderId = MagicNames.REFID_CLASSPATH_LOADER_PREFIX + pathId;
         return getClassLoaderForPath(p, (Path) path, loaderId, reverseLoader);
@@ -174,8 +175,9 @@
         if (loaderId != null && reuseLoader) {
             Object reusedLoader = p.getReference(loaderId);
             if (reusedLoader != null && !(reusedLoader instanceof ClassLoader)) {
-                throw new BuildException("The specified loader id " + loaderId
-                        + " does not reference a class loader");
+                throw new BuildException(
+                    "The specified loader id %s does not reference a class loader",
+                    loaderId);
             }
             cl = (ClassLoader) reusedLoader;
         }
@@ -232,6 +234,7 @@
      * <p>This uses the userDefinedLoader to load the specified class,
      * and then makes an instance using the default no-argument constructor.</p>
      *
+     * @param <T> desired type
      * @param className the full qualified class name to load.
      * @param userDefinedLoader the classloader to use.
      * @param expectedType the Class that the result should be assignment
@@ -241,14 +244,16 @@
      * @throws BuildException when loading or instantiation failed.
      * @since Ant 1.7
      */
-    public static Object newInstance(String className, ClassLoader userDefinedLoader,
-            Class expectedType) {
+    public static <T> T newInstance(String className, ClassLoader userDefinedLoader,
+            Class<T> expectedType) {
         try {
-            Class clazz = Class.forName(className, true, userDefinedLoader);
-            Object o = clazz.newInstance();
+            @SuppressWarnings("unchecked")
+            Class<T> clazz = (Class<T>) Class.forName(className, true, userDefinedLoader);
+            T o = clazz.newInstance();
             if (!expectedType.isInstance(o)) {
-                throw new BuildException("Class of unexpected Type: " + className + " expected :"
-                        + expectedType);
+                throw new BuildException(
+                    "Class of unexpected Type: %s expected : %s", className,
+                    expectedType);
             }
             return o;
         } catch (ClassNotFoundException e) {
@@ -284,6 +289,9 @@
         return p.getProperty(REUSE_LOADER_REF) != null;
     }
 
+    private ClasspathUtils() {
+    }
+
     /**
      * Delegate that helps out any specific ProjectComponent that needs
      * dynamic classloading.
@@ -455,7 +463,5 @@
             return reverseLoader;
         }
 
-        //TODO no methods yet for getClassname
-        //TODO no method for newInstance using a reverse-classloader
     }
 }
diff --git a/src/main/org/apache/tools/ant/util/CollectionUtils.java b/src/main/org/apache/tools/ant/util/CollectionUtils.java
index 23f67a4..70b2810 100644
--- a/src/main/org/apache/tools/ant/util/CollectionUtils.java
+++ b/src/main/org/apache/tools/ant/util/CollectionUtils.java
@@ -25,7 +25,9 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.Vector;
+import java.util.stream.Collectors;
 
 // CheckStyle:HideUtilityClassConstructorCheck OFF - bc
 
@@ -49,15 +51,7 @@
      * @deprecated since 1.6.x.
      */
     public static boolean equals(Vector<?> v1, Vector<?> v2) {
-        if (v1 == v2) {
-            return true;
-        }
-
-        if (v1 == null || v2 == null) {
-            return false;
-        }
-
-        return v1.equals(v2);
+        return Objects.equals(v1, v2);
     }
 
     /**
@@ -109,14 +103,7 @@
      * @since Ant 1.8.0
      */
     public static String flattenToString(Collection<?> c) {
-        final StringBuilder sb = new StringBuilder();
-        for (Object o : c) {
-            if (sb.length() != 0) {
-                sb.append(",");
-            }
-            sb.append(o);
-        }
-        return sb.toString();
+        return c.stream().map(String::valueOf).collect(Collectors.joining(","));
     }
 
     /**
@@ -128,7 +115,8 @@
      * @since Ant 1.6
      * @deprecated since 1.6.x.
      */
-    public static <K, V> void putAll(Dictionary<? super K, ? super V> m1, Dictionary<? extends K, ? extends V> m2) {
+    public static <K, V> void putAll(Dictionary<? super K, ? super V> m1,
+        Dictionary<? extends K, ? extends V> m2) {
         for (Enumeration<? extends K> it = m2.keys(); it.hasMoreElements();) {
             K key = it.nextElement();
             m1.put(key, m2.get(key));
@@ -139,14 +127,13 @@
      * An empty enumeration.
      * @since Ant 1.6
      */
+    @Deprecated
     public static final class EmptyEnumeration<E> implements Enumeration<E> {
-        /** Constructor for the EmptyEnumeration */
-        public EmptyEnumeration() {
-        }
 
         /**
          * @return false always.
          */
+        @Override
         public boolean hasMoreElements() {
             return false;
         }
@@ -155,6 +142,7 @@
          * @return nothing.
          * @throws NoSuchElementException always.
          */
+        @Override
         public E nextElement() throws NoSuchElementException {
             throw new NoSuchElementException();
         }
@@ -170,7 +158,7 @@
      * @since Ant 1.6.3
      */
     public static <E> Enumeration<E> append(Enumeration<E> e1, Enumeration<E> e2) {
-        return new CompoundEnumeration<E>(e1, e2);
+        return new CompoundEnumeration<>(e1, e2);
     }
 
     /**
@@ -181,9 +169,11 @@
      */
     public static <E> Enumeration<E> asEnumeration(final Iterator<E> iter) {
         return new Enumeration<E>() {
+            @Override
             public boolean hasMoreElements() {
                 return iter.hasNext();
             }
+            @Override
             public E nextElement() {
                 return iter.next();
             }
@@ -198,12 +188,15 @@
      */
     public static <E> Iterator<E> asIterator(final Enumeration<E> e) {
         return new Iterator<E>() {
+            @Override
             public boolean hasNext() {
                 return e.hasMoreElements();
             }
+            @Override
             public E next() {
                 return e.nextElement();
             }
+            @Override
             public void remove() {
                 throw new UnsupportedOperationException();
             }
@@ -219,10 +212,8 @@
      * @since Ant 1.8.0
      */
     public static <T> Collection<T> asCollection(final Iterator<? extends T> iter) {
-        List<T> l = new ArrayList<T>();
-        while (iter.hasNext()) {
-            l.add(iter.next());
-        }
+        List<T> l = new ArrayList<>();
+        iter.forEachRemaining(l::add);
         return l;
     }
 
@@ -235,16 +226,17 @@
             this.e2 = e2;
         }
 
+        @Override
         public boolean hasMoreElements() {
             return e1.hasMoreElements() || e2.hasMoreElements();
         }
 
+        @Override
         public E nextElement() throws NoSuchElementException {
             if (e1.hasMoreElements()) {
                 return e1.nextElement();
-            } else {
-                return e2.nextElement();
             }
+            return e2.nextElement();
         }
 
     }
@@ -258,18 +250,11 @@
      * @return frequency
      * @since Ant 1.8.0
      */
+    @Deprecated
     public static int frequency(Collection<?> c, Object o) {
-        // same as Collections.frequency introduced with JDK 1.5
-        int freq = 0;
-        if (c != null) {
-            for (Iterator<?> i = c.iterator(); i.hasNext();) {
-                Object test = i.next();
-                if (o == null ? test == null : o.equals(test)) {
-                    freq++;
-                }
-            }
-        }
-        return freq;
+        return Collections.frequency(c, o);
     }
 
+    private CollectionUtils() {
+    }
 }
diff --git a/src/main/org/apache/tools/ant/util/CompositeMapper.java b/src/main/org/apache/tools/ant/util/CompositeMapper.java
index d04a5fc..4ef9a76 100644
--- a/src/main/org/apache/tools/ant/util/CompositeMapper.java
+++ b/src/main/org/apache/tools/ant/util/CompositeMapper.java
@@ -17,8 +17,8 @@
  */
 package org.apache.tools.ant.util;
 
-import java.util.Iterator;
-import java.util.LinkedHashSet;
+import java.util.Objects;
+import java.util.stream.Stream;
 
 /**
  * A <code>ContainerMapper</code> that unites the results of its constituent
@@ -28,23 +28,9 @@
 
     /** {@inheritDoc}. */
     public String[] mapFileName(String sourceFileName) {
-        LinkedHashSet results = new LinkedHashSet();
-
-        FileNameMapper mapper = null;
-        for (Iterator mIter = getMappers().iterator(); mIter.hasNext();) {
-            mapper = (FileNameMapper) (mIter.next());
-            if (mapper != null) {
-                String[] mapped = mapper.mapFileName(sourceFileName);
-                if (mapped != null) {
-                    for (int i = 0; i < mapped.length; i++) {
-                        results.add(mapped[i]);
-                    }
-                }
-            }
-        }
-        return (results.size() == 0) ? null
-            : (String[]) results.toArray(new String[results.size()]);
+        String[] result = getMappers().stream().filter(Objects::nonNull)
+            .map(m -> m.mapFileName(sourceFileName)).filter(Objects::nonNull)
+            .flatMap(Stream::of).toArray(String[]::new);
+        return result.length == 0 ? null : result;
     }
-
 }
-
diff --git a/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java b/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java
index 22dcb7f..e39f09e 100644
--- a/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java
+++ b/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java
@@ -20,9 +20,9 @@
 
 import java.io.BufferedInputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
 
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.ProjectComponent;
@@ -55,6 +55,7 @@
      * Close the stream.
      * @throws IOException if there is an error.
      */
+    @Override
     public void close() throws IOException {
         closeCurrent();
         eof = true;
@@ -65,6 +66,7 @@
      * @return the byte (0 - 255) or -1 if this is the end of the stream.
      * @throws IOException if there is an error.
      */
+    @Override
     public int read() throws IOException {
         int result = readCurrent();
         if (result == EOF && !eof) {
@@ -119,7 +121,7 @@
             log("Opening " + file[index], Project.MSG_VERBOSE);
             try {
                 currentStream = new BufferedInputStream(
-                    new FileInputStream(file[index]));
+                    Files.newInputStream(file[index].toPath()));
             } catch (IOException eyeOhEx) {
                 log("Failed to open " + file[index], Project.MSG_ERR);
                 throw eyeOhEx;
diff --git a/src/main/org/apache/tools/ant/util/ConcatResourceInputStream.java b/src/main/org/apache/tools/ant/util/ConcatResourceInputStream.java
index 6c68747..d695f12 100644
--- a/src/main/org/apache/tools/ant/util/ConcatResourceInputStream.java
+++ b/src/main/org/apache/tools/ant/util/ConcatResourceInputStream.java
@@ -71,6 +71,7 @@
      * Close the stream.
      * @throws IOException if there is an error.
      */
+    @Override
      public void close() throws IOException {
         closeCurrent();
         eof = true;
@@ -81,6 +82,7 @@
      * @return the byte (0 - 255) or -1 if this is the end of the stream.
      * @throws IOException if there is an error.
      */
+    @Override
     public int read() throws IOException {
         if (eof) {
             return EOF;
@@ -122,7 +124,7 @@
     private void nextResource() throws IOException {
         closeCurrent();
         while (iter.hasNext()) {
-            Resource r = (Resource) iter.next();
+            Resource r = iter.next();
             if (!r.isExists()) {
                 continue;
             }
diff --git a/src/main/org/apache/tools/ant/util/ContainerMapper.java b/src/main/org/apache/tools/ant/util/ContainerMapper.java
index 990ee14..2b5ee39 100644
--- a/src/main/org/apache/tools/ant/util/ContainerMapper.java
+++ b/src/main/org/apache/tools/ant/util/ContainerMapper.java
@@ -20,7 +20,6 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.List;
 
 import org.apache.tools.ant.types.Mapper;
@@ -32,7 +31,7 @@
  */
 public abstract class ContainerMapper implements FileNameMapper {
 
-    private List mappers = new ArrayList();
+    private List<FileNameMapper> mappers = new ArrayList<>();
 
     /**
      * Add a <code>Mapper</code>.
@@ -69,9 +68,8 @@
             && ((ContainerMapper) fileNameMapper).contains(this))) {
             throw new IllegalArgumentException(
                 "Circular mapper containment condition detected");
-        } else {
-            mappers.add(fileNameMapper);
         }
+        mappers.add(fileNameMapper);
     }
 
     /**
@@ -81,21 +79,23 @@
      * @return <code>boolean</code>.
      */
     protected synchronized boolean contains(FileNameMapper fileNameMapper) {
-        boolean foundit = false;
-        for (Iterator iter = mappers.iterator(); iter.hasNext() && !foundit;) {
-            FileNameMapper next = (FileNameMapper) (iter.next());
-            foundit = (next == fileNameMapper
-                || (next instanceof ContainerMapper
-                && ((ContainerMapper) next).contains(fileNameMapper)));
+        for (FileNameMapper m : mappers) {
+            if (m == fileNameMapper) {
+                return true;
+            }
+            if (m instanceof ContainerMapper
+                && ((ContainerMapper) m).contains(fileNameMapper)) {
+                return true;
+            }
         }
-        return foundit;
+        return false;
     }
 
     /**
      * Get the <code>List</code> of <code>FileNameMapper</code>s.
      * @return <code>List</code>.
      */
-    public synchronized List getMappers() {
+    public synchronized List<FileNameMapper> getMappers() {
         return Collections.unmodifiableList(mappers);
     }
 
@@ -103,6 +103,7 @@
      * Empty implementation.
      * @param ignore ignored.
      */
+    @Override
     public void setFrom(String ignore) {
         //Empty
     }
@@ -111,6 +112,7 @@
      * Empty implementation.
      * @param ignore ignored.
      */
+    @Override
     public void setTo(String ignore) {
         //Empty
     }
diff --git a/src/main/org/apache/tools/ant/util/DOMElementWriter.java b/src/main/org/apache/tools/ant/util/DOMElementWriter.java
index 2dad80f..2f2edc3 100644
--- a/src/main/org/apache/tools/ant/util/DOMElementWriter.java
+++ b/src/main/org/apache/tools/ant/util/DOMElementWriter.java
@@ -25,7 +25,8 @@
 import java.io.Writer;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 import org.w3c.dom.Attr;
 import org.w3c.dom.Element;
@@ -68,7 +69,7 @@
     /**
      * Map (URI to prefix) of known namespaces.
      */
-    private HashMap nsPrefixMap = new HashMap();
+    private Map<String, String> nsPrefixMap = new HashMap<>();
 
     /**
      * Number of generated prefix to use next.
@@ -78,7 +79,7 @@
     /**
      * Map (Element to URI) of namespaces defined on a given element.
      */
-    private HashMap nsURIByElement = new HashMap();
+    private Map<Element, List<String>> nsURIByElement = new HashMap<>();
 
     /**
      * Whether namespaces should be ignored for elements and attributes.
@@ -346,12 +347,10 @@
         }
 
         // write namespace declarations
-        ArrayList al = (ArrayList) nsURIByElement.get(element);
-        if (al != null) {
-            Iterator iter = al.iterator();
-            while (iter.hasNext()) {
-                String uri = (String) iter.next();
-                String prefix = (String) nsPrefixMap.get(uri);
+        List<String> uris = nsURIByElement.get(element);
+        if (uris != null) {
+            for (String uri : uris) {
+                String prefix = nsPrefixMap.get(uri);
                 out.write(" xmlns");
                 if (!"".equals(prefix)) {
                     out.write(":");
@@ -436,7 +435,7 @@
 
     private String encode(final String value, final boolean encodeWhitespace) {
         final int len = value.length();
-        final StringBuffer sb = new StringBuffer(len);
+        final StringBuilder sb = new StringBuilder(len);
         for (int i = 0; i < len; i++) {
             final char c = value.charAt(i);
             switch (c) {
@@ -598,13 +597,17 @@
         // CheckStyle:MagicNumber OFF
         if (c == 0x9 || c == 0xA || c == 0xD) {
             return true;
-        } else if (c < 0x20) {
+        }
+        if (c < 0x20) {
             return false;
-        } else if (c <= 0xD7FF) {
+        }
+        if (c <= 0xD7FF) {
             return true;
-        } else if (c < 0xE000) {
+        }
+        if (c < 0xE000) {
             return false;
-        } else if (c <= 0xFFFD) {
+        }
+        if (c <= 0xFFFD) {
             return true;
         }
         // CheckStyle:MagicNumber ON
@@ -612,31 +615,20 @@
     }
 
     private void removeNSDefinitions(Element element) {
-        ArrayList al = (ArrayList) nsURIByElement.get(element);
-        if (al != null) {
-            Iterator iter = al.iterator();
-            while (iter.hasNext()) {
-                nsPrefixMap.remove(iter.next());
-            }
+        List<String> uris = nsURIByElement.get(element);
+        if (uris != null) {
+            uris.forEach(nsPrefixMap::remove);
             nsURIByElement.remove(element);
         }
     }
 
     private void addNSDefinition(Element element, String uri) {
-        ArrayList al = (ArrayList) nsURIByElement.get(element);
-        if (al == null) {
-            al = new ArrayList();
-            nsURIByElement.put(element, al);
-        }
-        al.add(uri);
+        nsURIByElement.computeIfAbsent(element, e -> new ArrayList<>())
+            .add(uri);
     }
 
     private static String getNamespaceURI(Node n) {
         String uri = n.getNamespaceURI();
-        if (uri == null) {
-            // FIXME: Is "No Namespace is Empty Namespace" really OK?
-            uri = "";
-        }
-        return uri;
+        return uri == null ? "" : uri;
     }
 }
diff --git a/src/main/org/apache/tools/ant/util/DOMUtils.java b/src/main/org/apache/tools/ant/util/DOMUtils.java
index db00213..0e2cfce 100644
--- a/src/main/org/apache/tools/ant/util/DOMUtils.java
+++ b/src/main/org/apache/tools/ant/util/DOMUtils.java
@@ -160,4 +160,7 @@
         Element e = createChildElement(parent, name);
         appendCDATA(e, content);
     }
+
+    private DOMUtils() {
+    }
 }
diff --git a/src/main/org/apache/tools/ant/util/DateUtils.java b/src/main/org/apache/tools/ant/util/DateUtils.java
index b63e098..f7c94f3 100644
--- a/src/main/org/apache/tools/ant/util/DateUtils.java
+++ b/src/main/org/apache/tools/ant/util/DateUtils.java
@@ -68,12 +68,12 @@
      * some other code is using the format in parallel.
      * Deprecated since ant 1.8
      */
+    @Deprecated
     public static final DateFormat DATE_HEADER_FORMAT
         = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ", Locale.US);
 
-    private static final DateFormat DATE_HEADER_FORMAT_INT
-    = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ", Locale.US);
-
+    private static final DateFormat DATE_HEADER_FORMAT_INT =
+        new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ", Locale.US);
 
 // code from Magesh moved from DefaultLogger and slightly modified
     private static final MessageFormat MINUTE_SECONDS
@@ -95,7 +95,7 @@
      * Provides a thread-local US-style date format. Exactly as used by
      * {@code <touch>}, to minute precision:
      * {@code SimpleDateFormat("MM/dd/yyyy hh:mm a", Locale.US)}
-     * @since Ant 1.9.10
+     * @since Ant 1.10.2
      */
     public static final ThreadLocal<DateFormat> EN_US_DATE_FORMAT_MIN =
         new ThreadLocal<DateFormat>() {
@@ -109,7 +109,7 @@
      * Provides a thread-local US-style date format. Exactly as used by
      * {@code <touch>}, to second precision:
      * {@code SimpleDateFormat("MM/dd/yyyy hh:mm:ss a", Locale.US)}
-     * @since Ant 1.9.10
+     * @since Ant 1.10.2
      */
     public static final ThreadLocal<DateFormat> EN_US_DATE_FORMAT_SEC =
         new ThreadLocal<DateFormat>() {
@@ -245,7 +245,7 @@
                                   cal.get(Calendar.DAY_OF_MONTH),
                                   cal.get(Calendar.DAY_OF_WEEK),
                                   cal.get(Calendar.MILLISECOND));
-        StringBuffer tzMarker = new StringBuffer(offset < 0 ? "-" : "+");
+        StringBuilder tzMarker = new StringBuilder(offset < 0 ? "-" : "+");
         offset = Math.abs(offset);
         int hours = offset / (ONE_HOUR * ONE_MINUTE * ONE_SECOND);
         int minutes = offset / (ONE_MINUTE * ONE_SECOND) - ONE_HOUR * hours;
@@ -355,7 +355,7 @@
      * @param dateStr String
      * @return Date
      * @throws ParseException if date string does not match ISO 8601
-     * @since Ant 1.9.10
+     * @since Ant 1.10.2
      */
     public static Date parseLenientDateTime(String dateStr) throws ParseException {
         try {
diff --git a/src/main/org/apache/tools/ant/util/DeweyDecimal.java b/src/main/org/apache/tools/ant/util/DeweyDecimal.java
index 003f140..32564fd 100644
--- a/src/main/org/apache/tools/ant/util/DeweyDecimal.java
+++ b/src/main/org/apache/tools/ant/util/DeweyDecimal.java
@@ -18,6 +18,8 @@
 package org.apache.tools.ant.util;
 
 import java.util.StringTokenizer;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 /**
  * Utility class to contain version numbers in "Dewey Decimal"
@@ -195,16 +197,8 @@
      * @return the string representation of DeweyDecimal.
      */
     @Override public String toString() {
-        final StringBuffer sb = new StringBuffer();
-
-        for (int i = 0; i < components.length; i++) {
-            if (i != 0) {
-                sb.append('.');
-            }
-            sb.append(components[ i ]);
-        }
-
-        return sb.toString();
+        return IntStream.of(components).mapToObj(Integer::toString)
+            .collect(Collectors.joining("."));
     }
 
     /**
@@ -214,6 +208,7 @@
      * @return result
      * @see java.lang.Comparable#compareTo(Object)
      */
+    @Override
     public int compareTo(DeweyDecimal other) {
         final int max = Math.max(other.components.length, components.length);
         for (int i = 0; i < max; i++) {
diff --git a/src/main/org/apache/tools/ant/util/FileTokenizer.java b/src/main/org/apache/tools/ant/util/FileTokenizer.java
index 2807aa4..93f5480 100644
--- a/src/main/org/apache/tools/ant/util/FileTokenizer.java
+++ b/src/main/org/apache/tools/ant/util/FileTokenizer.java
@@ -34,6 +34,7 @@
      * @return the complete input
      * @throws IOException if error reading
      */
+    @Override
     public String getToken(Reader in) throws IOException {
         return FileUtils.readFully(in);
     }
@@ -42,6 +43,7 @@
      * Return the intra-token string
      * @return an empty string always
      */
+    @Override
     public String getPostToken() {
         return "";
     }
diff --git a/src/main/org/apache/tools/ant/util/FileUtils.java b/src/main/org/apache/tools/ant/util/FileUtils.java
index c36eae7..ce75d34 100644
--- a/src/main/org/apache/tools/ant/util/FileUtils.java
+++ b/src/main/org/apache/tools/ant/util/FileUtils.java
@@ -31,22 +31,27 @@
 import java.net.URL;
 import java.net.URLConnection;
 import java.nio.channels.Channel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
 import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Random;
 import java.util.Stack;
 import java.util.StringTokenizer;
 import java.util.Vector;
 import java.util.jar.JarFile;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.PathTokenizer;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.launch.Locator;
 import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.FilterChain;
 import org.apache.tools.ant.types.FilterSetCollection;
 import org.apache.tools.ant.types.resources.FileResource;
 
@@ -109,6 +114,7 @@
      *             Use getFileUtils instead,
      * FileUtils do not have state.
      */
+    @Deprecated
     public static FileUtils newFileUtils() {
         return new FileUtils();
     }
@@ -272,7 +278,7 @@
      * @since Ant 1.5
      */
     public void copyFile(String sourceFile, String destFile,
-                         FilterSetCollection filters, Vector filterChains,
+                         FilterSetCollection filters, Vector<FilterChain> filterChains,
                          boolean overwrite, boolean preserveLastModified,
                          String encoding, Project project) throws IOException {
         copyFile(new File(sourceFile), new File(destFile), filters, filterChains, overwrite,
@@ -302,7 +308,7 @@
      * @since Ant 1.6
      */
     public void copyFile(String sourceFile, String destFile,
-                         FilterSetCollection filters, Vector filterChains,
+                         FilterSetCollection filters, Vector<FilterChain> filterChains,
                          boolean overwrite, boolean preserveLastModified,
                          String inputEncoding, String outputEncoding,
                          Project project) throws IOException {
@@ -437,7 +443,7 @@
      * @since Ant 1.5
      */
     public void copyFile(File sourceFile, File destFile,
-                         FilterSetCollection filters, Vector filterChains,
+                         FilterSetCollection filters, Vector<FilterChain> filterChains,
                          boolean overwrite, boolean preserveLastModified,
                          String encoding, Project project) throws IOException {
         copyFile(sourceFile, destFile, filters, filterChains,
@@ -473,7 +479,7 @@
      * @since Ant 1.6
      */
     public void copyFile(File sourceFile, File destFile,
-            FilterSetCollection filters, Vector filterChains,
+            FilterSetCollection filters, Vector<FilterChain> filterChains,
             boolean overwrite, boolean preserveLastModified,
             String inputEncoding, String outputEncoding,
             Project project) throws IOException {
@@ -511,7 +517,7 @@
      * @since Ant 1.8
      */
     public void copyFile(File sourceFile, File destFile,
-                         FilterSetCollection filters, Vector filterChains,
+                         FilterSetCollection filters, Vector<FilterChain> filterChains,
                          boolean overwrite, boolean preserveLastModified,
                          boolean append,
                          String inputEncoding, String outputEncoding,
@@ -551,7 +557,7 @@
      * @since Ant 1.8.2
      */
     public void copyFile(File sourceFile, File destFile,
-                         FilterSetCollection filters, Vector filterChains,
+                         FilterSetCollection filters, Vector<FilterChain> filterChains,
                          boolean overwrite, boolean preserveLastModified,
                          boolean append,
                          String inputEncoding, String outputEncoding,
@@ -695,10 +701,10 @@
      * @see PathTokenizer
      */
     public static String translatePath(String toProcess) {
-        if (toProcess == null || toProcess.length() == 0) {
+        if (toProcess == null || toProcess.isEmpty()) {
             return "";
         }
-        StringBuffer path = new StringBuffer(toProcess.length() + EXPAND_SPACE);
+        StringBuilder path = new StringBuilder(toProcess.length() + EXPAND_SPACE);
         PathTokenizer tokenizer = new PathTokenizer(toProcess);
         while (tokenizer.hasMoreTokens()) {
             String pathComponent = tokenizer.nextToken();
@@ -732,7 +738,7 @@
      * @throws java.lang.NullPointerException if path is null.
      */
     public File normalize(final String path) {
-        Stack s = new Stack();
+        Stack<String> s = new Stack<>();
         String[] dissect = dissect(path);
         s.push(dissect[0]);
 
@@ -752,7 +758,7 @@
                 s.push(thisToken);
             }
         }
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         final int size = s.size();
         for (int i = 0; i < size; i++) {
             if (i > 1) {
@@ -780,7 +786,7 @@
         if (!isAbsolutePath(path)) {
             throw new BuildException(path + " is not an absolute path");
         }
-        String root = null;
+        String root;
         int colon = path.indexOf(':');
         if (colon > 0 && (ON_DOS || ON_NETWARE)) {
 
@@ -833,7 +839,7 @@
                 && !name.regionMatches(true, name.length() - 4, ".DIR", 0, 4);
         // CheckStyle:MagicNumber ON
         String device = null;
-        StringBuffer directory = null;
+        StringBuilder directory = null;
         String file = null;
 
         int index = 0;
@@ -846,13 +852,13 @@
             device = path.substring(1, index++);
         }
         if (isDirectory) {
-            directory = new StringBuffer(path.substring(index).replace(File.separatorChar, '.'));
+            directory = new StringBuilder(path.substring(index).replace(File.separatorChar, '.'));
         } else {
             int dirEnd = path.lastIndexOf(File.separatorChar, path.length());
             if (dirEnd == -1 || dirEnd < index) {
                 file = path.substring(index);
             } else {
-                directory = new StringBuffer(path.substring(index, dirEnd).
+                directory = new StringBuilder(path.substring(index, dirEnd).
                                              replace(File.separatorChar, '.'));
                 index = dirEnd + 1;
                 if (path.length() > index) {
@@ -894,6 +900,7 @@
      * boolean, boolean) instead.
      * @return a File reference to the new, nonexistent temporary file.
      */
+    @Deprecated
     public File createTempFile(String prefix, String suffix, File parentDir) {
         return createTempFile(prefix, suffix, parentDir, false, false);
     }
@@ -923,7 +930,7 @@
      */
     public File createTempFile(String prefix, String suffix, File parentDir,
             boolean deleteOnExit, boolean createFile) {
-        File result = null;
+        File result;
         String parent = (parentDir == null)
                 ? System.getProperty("java.io.tmpdir")
                 : parentDir.getPath();
@@ -984,6 +991,7 @@
      * boolean, boolean) instead.
      * @return a File reference to the new, nonexistent temporary file.
      */
+    @Deprecated
     public File createTempFile(String prefix, String suffix,
             File parentDir, boolean deleteOnExit) {
         return createTempFile(prefix, suffix, parentDir, deleteOnExit, false);
@@ -1029,8 +1037,9 @@
      * @since 1.10
      * @deprecated since 1.7. Just use {@link File#getParentFile} directly.
      */
+    @Deprecated
     public File getParentFile(File f) {
-        return (f == null) ? null : f.getParentFile();
+        return f == null ? null : f.getParentFile();
     }
 
     /**
@@ -1059,17 +1068,17 @@
     public static String readFully(Reader rdr, int bufferSize)
         throws IOException {
         if (bufferSize <= 0) {
-            throw new IllegalArgumentException("Buffer size must be greater "
-                                               + "than 0");
+            throw new IllegalArgumentException(
+                "Buffer size must be greater than 0");
         }
         final char[] buffer = new char[bufferSize];
         int bufferLength = 0;
-        StringBuffer textBuffer = null;
+        StringBuilder textBuffer = null;
         while (bufferLength != -1) {
             bufferLength = rdr.read(buffer);
             if (bufferLength > 0) {
-                textBuffer = (textBuffer == null) ? new StringBuffer() : textBuffer;
-                textBuffer.append(new String(buffer, 0, bufferLength));
+                textBuffer = (textBuffer == null) ? new StringBuilder() : textBuffer;
+                textBuffer.append(buffer, 0, bufferLength);
             }
         }
         return (textBuffer == null) ? null : textBuffer.toString();
@@ -1133,15 +1142,15 @@
      * @return true if the file is a symbolic link.
      * @throws IOException on error.
      * @since Ant 1.5
-     * @deprecated use SymbolicLinkUtils instead
+     * @deprecated use {@link Files#isSymbolicLink(Path)} instead
      */
-    public boolean isSymbolicLink(File parent, String name)
+    @Deprecated
+    public boolean isSymbolicLink(final File parent, final String name)
         throws IOException {
-        SymbolicLinkUtils u = SymbolicLinkUtils.getSymbolicLinkUtils();
         if (parent == null) {
-            return u.isSymbolicLink(name);
+            return Files.isSymbolicLink(Paths.get(name));
         }
-        return u.isSymbolicLink(parent, name);
+        return Files.isSymbolicLink(Paths.get(parent.toPath().toString(), name));
     }
 
     /**
@@ -1377,11 +1386,8 @@
             return false;
         }
         final String localFileName = localFile.getName();
-        FilenameFilter ff = new FilenameFilter () {
-            public boolean accept(File dir, String name) {
-                return name.equalsIgnoreCase(localFileName) && (!name.equals(localFileName));
-            }
-        };
+        FilenameFilter ff = (dir, name) -> name.equalsIgnoreCase(localFileName)
+            && (!name.equals(localFileName));
         String[] names = localFile.getParentFile().list(ff);
         return names != null && names.length == 1;
     }
@@ -1450,13 +1456,7 @@
      * @param device output writer, can be null.
      */
     public static void close(Writer device) {
-        if (null != device) {
-            try {
-                device.close();
-            } catch (IOException e) {
-                //ignore
-            }
-        }
+        close((AutoCloseable) device);
     }
 
     /**
@@ -1466,13 +1466,7 @@
      * @param device Reader, can be null.
      */
     public static void close(Reader device) {
-        if (null != device) {
-            try {
-                device.close();
-            } catch (IOException e) {
-                //ignore
-            }
-        }
+        close((AutoCloseable) device);
     }
 
     /**
@@ -1482,13 +1476,7 @@
      * @param device stream, can be null.
      */
     public static void close(OutputStream device) {
-        if (null != device) {
-            try {
-                device.close();
-            } catch (IOException e) {
-                //ignore
-            }
-        }
+        close((AutoCloseable) device);
     }
 
     /**
@@ -1498,13 +1486,7 @@
      * @param device stream, can be null.
      */
     public static void close(InputStream device) {
-        if (null != device) {
-            try {
-                device.close();
-            } catch (IOException e) {
-                //ignore
-            }
-        }
+        close((AutoCloseable) device);
     }
 
     /**
@@ -1515,13 +1497,7 @@
      * @since Ant 1.8.0
      */
     public static void close(Channel device) {
-        if (null != device) {
-            try {
-                device.close();
-            } catch (IOException e) {
-                //ignore
-            }
-        }
+        close((AutoCloseable) device);
     }
 
     /**
@@ -1538,7 +1514,6 @@
                     JarURLConnection juc = (JarURLConnection) conn;
                     JarFile jf = juc.getJarFile();
                     jf.close();
-                    jf = null;
                 } else if (conn instanceof HttpURLConnection) {
                     ((HttpURLConnection) conn).disconnect();
                 }
@@ -1549,6 +1524,24 @@
     }
 
     /**
+     * Close an {@link AutoCloseable} without throwing any exception
+     * if something went wrong.  Do not attempt to close it if the
+     * argument is null.
+     *
+     * @param ac AutoCloseable, can be null.
+     * @since Ant 1.10.0
+     */
+    public static void close(AutoCloseable ac) {
+        if (null != ac) {
+            try {
+                ac.close();
+            } catch (Exception e) {
+                //ignore
+            }
+        }
+    }
+
+    /**
      * Delete the file with {@link File#delete()} if the argument is not null.
      * Do nothing on a null argument.
      * @param file file to delete.
@@ -1640,7 +1633,7 @@
             // Do nothing
         }
 
-        List relativePathStack = new ArrayList();
+        List<String> relativePathStack = new ArrayList<>();
 
         // if "from" part is longer, fill it up with ".."
         // to reach path which is equal to both paths
@@ -1678,7 +1671,7 @@
      *
      * @since Ant 1.7
      */
-    public static String getPath(List pathStack) {
+    public static String getPath(List<String> pathStack) {
         // can safely use '/' because Windows understands '/' as separator
         return getPath(pathStack, '/');
     }
@@ -1692,18 +1685,8 @@
      *
      * @since Ant 1.7
      */
-    public static String getPath(final List pathStack, final char separatorChar) {
-        final StringBuffer buffer = new StringBuffer();
-
-        final Iterator iter = pathStack.iterator();
-        if (iter.hasNext()) {
-            buffer.append(iter.next());
-        }
-        while (iter.hasNext()) {
-            buffer.append(separatorChar);
-            buffer.append(iter.next());
-        }
-        return buffer.toString();
+    public static String getPath(final List<String> pathStack, final char separatorChar) {
+        return pathStack.stream().collect(Collectors.joining(Character.toString(separatorChar)));
     }
 
     /**
@@ -1717,6 +1700,7 @@
     public String getDefaultEncoding() {
         InputStreamReader is = new InputStreamReader(
             new InputStream() { //NOSONAR
+                @Override
                 public int read() {
                     return -1;
                 }
@@ -1727,4 +1711,21 @@
             close(is);
         }
     }
+
+    /**
+     * Opens a new OutputStream for the given Path.
+     * @param path the path of the file
+     * @param append whether to append to or a replace an existing file
+     * @return a stream ready to write to the file
+     * @throws IOException if stream creation fails
+     * @since Ant 1.10.2
+     */
+    public static OutputStream newOutputStream(Path path, boolean append) throws IOException {
+        if (append) {
+            return Files.newOutputStream(path, StandardOpenOption.CREATE, StandardOpenOption.APPEND,
+                StandardOpenOption.WRITE);
+        } else {
+            return Files.newOutputStream(path);
+        }
+    }
 }
diff --git a/src/main/org/apache/tools/ant/util/FirstMatchMapper.java b/src/main/org/apache/tools/ant/util/FirstMatchMapper.java
index b0e47f2..0b5a53de 100644
--- a/src/main/org/apache/tools/ant/util/FirstMatchMapper.java
+++ b/src/main/org/apache/tools/ant/util/FirstMatchMapper.java
@@ -17,7 +17,7 @@
  */
 package org.apache.tools.ant.util;
 
-import java.util.Iterator;
+import java.util.Objects;
 
 /**
  * A <code>ContainerMapper</code> that returns the results of its
@@ -28,17 +28,11 @@
 public class FirstMatchMapper extends ContainerMapper {
 
     /** {@inheritDoc}. */
+    @Override
     public String[] mapFileName(String sourceFileName) {
-        for (Iterator iter = getMappers().iterator(); iter.hasNext();) {
-            FileNameMapper mapper = (FileNameMapper) iter.next();
-            if (mapper != null) {
-                String[] mapped = mapper.mapFileName(sourceFileName);
-                if (mapped != null) {
-                    return mapped;
-                }
-            }
-        }
-        return null;
+        return getMappers().stream().filter(Objects::nonNull)
+            .map(m -> m.mapFileName(sourceFileName)).filter(Objects::nonNull)
+            .findFirst().orElse(null);
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/util/FlatFileNameMapper.java b/src/main/org/apache/tools/ant/util/FlatFileNameMapper.java
index 420ccc6..8465c78 100644
--- a/src/main/org/apache/tools/ant/util/FlatFileNameMapper.java
+++ b/src/main/org/apache/tools/ant/util/FlatFileNameMapper.java
@@ -32,6 +32,7 @@
      * Ignored.
      * @param from ignored.
      */
+    @Override
     public void setFrom(String from) {
     }
 
@@ -39,6 +40,7 @@
      * Ignored.
      * @param to ignored.
      */
+    @Override
     public void setTo(String to) {
     }
 
@@ -48,7 +50,8 @@
      * @param sourceFileName the name to map.
      * @return the file name in a one-element array.
      */
+    @Override
     public String[] mapFileName(String sourceFileName) {
-        return new String[] {new java.io.File(sourceFileName).getName()};
+        return new String[] { new java.io.File(sourceFileName).getName() };
     }
 }
diff --git a/src/main/org/apache/tools/ant/util/GlobPatternMapper.java b/src/main/org/apache/tools/ant/util/GlobPatternMapper.java
index ebba54e..8e470ac 100644
--- a/src/main/org/apache/tools/ant/util/GlobPatternMapper.java
+++ b/src/main/org/apache/tools/ant/util/GlobPatternMapper.java
@@ -108,42 +108,42 @@
      * Sets the &quot;from&quot; pattern. Required.
      * @param from a string
      */
+    @Override
     public void setFrom(String from) {
-        if (from != null) {
-            int index = from.lastIndexOf("*");
-            if (index == -1) {
-                fromPrefix = from;
-                fromPostfix = "";
-            } else {
-                fromPrefix = from.substring(0, index);
-                fromPostfix = from.substring(index + 1);
-                fromContainsStar = true;
-            }
-            prefixLength = fromPrefix.length();
-            postfixLength = fromPostfix.length();
-        } else {
+        if (from == null) {
             throw new BuildException("this mapper requires a 'from' attribute");
         }
+        int index = from.lastIndexOf('*');
+        if (index < 0) {
+            fromPrefix = from;
+            fromPostfix = "";
+        } else {
+            fromPrefix = from.substring(0, index);
+            fromPostfix = from.substring(index + 1);
+            fromContainsStar = true;
+        }
+        prefixLength = fromPrefix.length();
+        postfixLength = fromPostfix.length();
     }
 
     /**
      * Sets the &quot;to&quot; pattern. Required.
      * @param to a string
      */
+    @Override
     public void setTo(String to) {
-        if (to != null) {
-            int index = to.lastIndexOf("*");
-            if (index == -1) {
-                toPrefix = to;
-                toPostfix = "";
-            } else {
-                toPrefix = to.substring(0, index);
-                toPostfix = to.substring(index + 1);
-                toContainsStar = true;
-            }
-        } else {
+        if (to == null) {
             throw new BuildException("this mapper requires a 'to' attribute");
         }
+        int index = to.lastIndexOf('*');
+        if (index < 0) {
+            toPrefix = to;
+            toPostfix = "";
+        } else {
+            toPrefix = to.substring(0, index);
+            toPostfix = to.substring(index + 1);
+            toContainsStar = true;
+        }
     }
 
     /**
@@ -153,6 +153,7 @@
      * @param sourceFileName the filename to map
      * @return a list of converted filenames
      */
+    @Override
     public String[] mapFileName(String sourceFileName) {
         String modName = modifyName(sourceFileName);
         if (fromPrefix == null
diff --git a/src/main/org/apache/tools/ant/util/IdentityMapper.java b/src/main/org/apache/tools/ant/util/IdentityMapper.java
index 22c6c7e..548803d 100644
--- a/src/main/org/apache/tools/ant/util/IdentityMapper.java
+++ b/src/main/org/apache/tools/ant/util/IdentityMapper.java
@@ -31,6 +31,7 @@
      * Ignored.
      * @param from ignored.
      */
+    @Override
     public void setFrom(String from) {
     }
 
@@ -38,6 +39,7 @@
      * Ignored.
      * @param to ignored.
      */
+    @Override
     public void setTo(String to) {
     }
 
@@ -46,7 +48,8 @@
      * @param sourceFileName the name to map.
      * @return the source filename in a one-element array.
      */
+    @Override
     public String[] mapFileName(String sourceFileName) {
-        return new String[] {sourceFileName};
+        return new String[] { sourceFileName };
     }
 }
diff --git a/src/main/org/apache/tools/ant/util/IdentityStack.java b/src/main/org/apache/tools/ant/util/IdentityStack.java
index ba435b1..caf2fe9 100644
--- a/src/main/org/apache/tools/ant/util/IdentityStack.java
+++ b/src/main/org/apache/tools/ant/util/IdentityStack.java
@@ -41,7 +41,7 @@
         if (s instanceof IdentityStack) {
             return (IdentityStack<E>) s;
         }
-        IdentityStack<E> result = new IdentityStack<E>();
+        IdentityStack<E> result = new IdentityStack<>();
         if (s != null) {
             result.addAll(s);
         }
@@ -70,6 +70,7 @@
      * @return true if the stack contains the object.
      * @see java.util.Vector#contains(Object)
      */
+    @Override
     public synchronized boolean contains(Object o) {
         return indexOf(o) >= 0;
     }
@@ -81,6 +82,7 @@
      * @return the position of the object, -1 if not found.
      * @see java.util.Vector#indexOf(Object, int)
      */
+    @Override
     public synchronized int indexOf(Object o, int pos) {
         final int size = size();
         for (int i = pos; i < size; i++) {
@@ -98,6 +100,7 @@
      * @return the position of the object, -1 if not found.
      * @see java.util.Vector#indexOf(Object, int)
      */
+    @Override
     public synchronized int lastIndexOf(Object o, int pos) {
         for (int i = pos; i >= 0; i--) {
             if (get(i) == o) {
@@ -107,22 +110,25 @@
         return -1;
     }
 
+    @Override
     public synchronized boolean removeAll(Collection<?> c) {
-        if (!(c instanceof Set)) {
-            c = new HashSet(c);
+        if (!(c instanceof Set<?>)) {
+            c = new HashSet<>(c);
         }
         return super.removeAll(c);
     }
 
-    public synchronized boolean retainAll(Collection c) {
-        if (!(c instanceof Set)) {
-            c = new HashSet(c);
+    @Override
+    public synchronized boolean retainAll(Collection<?> c) {
+        if (!(c instanceof Set<?>)) {
+            c = new HashSet<>(c);
         }
         return super.retainAll(c);
     }
 
+    @Override
     public synchronized boolean containsAll(Collection<?> c) {
-        IdentityHashMap map = new IdentityHashMap();
+        IdentityHashMap<Object, Boolean> map = new IdentityHashMap<>();
         for (Object e : this) {
             map.put(e, Boolean.TRUE);
         }
diff --git a/src/main/org/apache/tools/ant/util/JAXPUtils.java b/src/main/org/apache/tools/ant/util/JAXPUtils.java
index 76460ae..2af9f8e 100644
--- a/src/main/org/apache/tools/ant/util/JAXPUtils.java
+++ b/src/main/org/apache/tools/ant/util/JAXPUtils.java
@@ -232,9 +232,8 @@
         Exception nested = e.getException();
         if (nested != null) {
             return new BuildException(nested);
-        } else {
-            return new BuildException(e);
         }
+        return new BuildException(e);
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/util/JavaEnvUtils.java b/src/main/org/apache/tools/ant/util/JavaEnvUtils.java
index 7206d77..e8cd4ef 100644
--- a/src/main/org/apache/tools/ant/util/JavaEnvUtils.java
+++ b/src/main/org/apache/tools/ant/util/JavaEnvUtils.java
@@ -270,8 +270,8 @@
      * Compares the current Java version to the passed in String -
      * assumes the argument is one of the constants defined in this
      * class.
-     * Note that Ant now requires JDK 1.5+ so {@link #JAVA_1_0} through
-     * {@link #JAVA_1_4} need no longer be tested for.
+     * Note that Ant now requires JDK 1.8+ so {@link #JAVA_1_0} through
+     * {@link #JAVA_1_7} need no longer be tested for.
      * @param version the version to check against the current version.
      * @return true if the version of Java is the same as the given version.
      * @since Ant 1.5
@@ -285,8 +285,8 @@
      * Compares the current Java version to the passed in String -
      * assumes the argument is one of the constants defined in this
      * class.
-     * Note that Ant now requires JDK 1.5+ so {@link #JAVA_1_0} through
-     * {@link #JAVA_1_4} need no longer be tested for.
+     * Note that Ant now requires JDK 1.8+ so {@link #JAVA_1_0} through
+     * {@link #JAVA_1_7} need no longer be tested for.
      * @param version the version to check against the current version.
      * @return true if the version of Java is the same or higher than the
      * given version.
@@ -508,7 +508,7 @@
      * @return a list of test classes depending on the java version.
      */
     public static Vector<String> getJrePackageTestCases() {
-        Vector<String> tests = new Vector<String>();
+        Vector<String> tests = new Vector<>();
         tests.addElement("java.lang.Object");
         if (isAtLeastJavaVersion(JAVA_1_1)) {
             //things like sun.reflection, sun.misc, sun.net
@@ -575,15 +575,11 @@
     public static File createVmsJavaOptionFile(String[] cmds)
             throws IOException {
         File script = FILE_UTILS.createTempFile("ANT", ".JAVA_OPTS", null, false, true);
-        BufferedWriter out = null;
-        try {
-            out = new BufferedWriter(new FileWriter(script));
+        try (BufferedWriter out = new BufferedWriter(new FileWriter(script))) {
             for (int i = 0; i < cmds.length; i++) {
                 out.write(cmds[i]);
                 out.newLine();
             }
-        } finally {
-            FileUtils.close(out);
         }
         return script;
     }
diff --git a/src/main/org/apache/tools/ant/util/LayoutPreservingProperties.java b/src/main/org/apache/tools/ant/util/LayoutPreservingProperties.java
index e4b2675..f2edb07 100644
--- a/src/main/org/apache/tools/ant/util/LayoutPreservingProperties.java
+++ b/src/main/org/apache/tools/ant/util/LayoutPreservingProperties.java
@@ -20,7 +20,6 @@
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -28,9 +27,12 @@
 import java.io.OutputStreamWriter;
 import java.io.PrintStream;
 import java.io.PushbackReader;
+import java.io.Serializable;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 /**
@@ -78,6 +80,8 @@
  * although the key-value pair <code>beta=two</code> is removed.</p>
  */
 public class LayoutPreservingProperties extends Properties {
+    private static final long serialVersionUID = 1L;
+
     private String LS = StringUtils.LINE_SEP;
 
     /**
@@ -85,12 +89,12 @@
      * of. Comments and blank lines are logical lines; they are not
      * removed.
      */
-    private ArrayList logicalLines = new ArrayList();
+    private List<LogicalLine> logicalLines = new ArrayList<>();
 
     /**
      * Position in the <code>logicalLines</code> list, keyed by property name.
      */
-    private HashMap keyedPairLines = new HashMap();
+    private Map<String, Integer> keyedPairLines = new HashMap<>();
 
     /**
      * Flag to indicate that, when we remove a property from the file, we
@@ -175,14 +179,14 @@
         value = escapeValue(value);
 
         if (keyedPairLines.containsKey(key)) {
-            final Integer i = (Integer) keyedPairLines.get(key);
+            final Integer i = keyedPairLines.get(key);
             final Pair p = (Pair) logicalLines.get(i.intValue());
             p.setValue(value);
         } else {
             key = escapeName(key);
             final Pair p = new Pair(key, value);
             p.setNew(true);
-            keyedPairLines.put(key, new Integer(logicalLines.size()));
+            keyedPairLines.put(key, Integer.valueOf(logicalLines.size()));
             logicalLines.add(p);
         }
     }
@@ -197,7 +201,7 @@
     @Override
     public Object remove(final Object key) {
         final Object obj = super.remove(key);
-        final Integer i = (Integer) keyedPairLines.remove(key);
+        final Integer i = keyedPairLines.remove(key);
         if (null != i) {
             if (removeComments) {
                 removeCommentsEndingAt(i.intValue());
@@ -208,14 +212,14 @@
     }
 
     @Override
-    public Object clone() {
+    public LayoutPreservingProperties clone() {
         final LayoutPreservingProperties dolly =
             (LayoutPreservingProperties) super.clone();
-        dolly.keyedPairLines = (HashMap) this.keyedPairLines.clone();
-        dolly.logicalLines = (ArrayList) this.logicalLines.clone();
+        dolly.keyedPairLines = new HashMap<>(this.keyedPairLines);
+        dolly.logicalLines = new ArrayList<>(this.logicalLines);
         final int size = dolly.logicalLines.size();
         for (int j = 0; j < size; j++) {
-            final LogicalLine line = (LogicalLine) dolly.logicalLines.get(j);
+            final LogicalLine line = dolly.logicalLines.get(j);
             if (line instanceof Pair) {
                 final Pair p = (Pair) line;
                 dolly.logicalLines.set(j, p.clone());
@@ -232,9 +236,7 @@
      */
     public void listLines(final PrintStream out) {
         out.println("-- logical lines --");
-        final Iterator i = logicalLines.iterator();
-        while (i.hasNext()) {
-            final LogicalLine line = (LogicalLine) i.next();
+        for (LogicalLine line : logicalLines) {
             if (line instanceof Blank) {
                 out.println("blank:   \"" + line + "\"");
             } else if (line instanceof Comment) {
@@ -251,7 +253,7 @@
      * @throws IOException if save fails
      */
     public void saveAs(final File dest) throws IOException {
-        final FileOutputStream fos = new FileOutputStream(dest);
+        final OutputStream fos = Files.newOutputStream(dest.toPath());
         store(fos, null);
         fos.close();
     }
@@ -289,11 +291,9 @@
         osw.write("#" + DateUtils.getDateForHeader() + LS);
 
         boolean writtenSep = false;
-        for (final Iterator i = logicalLines.subList(skipLines, totalLines).iterator();
-             i.hasNext();) {
-            final LogicalLine line = (LogicalLine) i.next();
+        for (LogicalLine line : logicalLines.subList(skipLines, totalLines)) {
             if (line instanceof Pair) {
-                if (((Pair)line).isNew()) {
+                if (((Pair) line).isNew()) {
                     if (!writtenSep) {
                         osw.write(LS);
                         writtenSep = true;
@@ -318,7 +318,7 @@
         final InputStreamReader isr = new InputStreamReader(is, ResourceUtils.ISO_8859_1);
         final PushbackReader pbr = new PushbackReader(isr, 1);
 
-        if (logicalLines.size() > 0) {
+        if (!logicalLines.isEmpty()) {
             // we add a blank line for spacing
             logicalLines.add(new Blank());
         }
@@ -328,8 +328,8 @@
 
         boolean continuation = false;
         boolean comment = false;
-        final StringBuffer fileBuffer = new StringBuffer();
-        final StringBuffer logicalLineBuffer = new StringBuffer();
+        final StringBuilder fileBuffer = new StringBuilder();
+        final StringBuilder logicalLineBuffer = new StringBuilder();
         while (s != null) {
             fileBuffer.append(s).append(LS);
 
@@ -350,7 +350,7 @@
             logicalLineBuffer.append(s);
 
             if (!continuation) {
-                LogicalLine line = null;
+                LogicalLine line;
                 if (comment) {
                     line = new Comment(logicalLineBuffer.toString());
                 } else if (logicalLineBuffer.toString().trim().length() == 0) {
@@ -385,7 +385,7 @@
      * @since Ant 1.8.2
      */
     private String readFirstLine(final PushbackReader r) throws IOException {
-        final StringBuffer sb = new StringBuffer(80);
+        final StringBuilder sb = new StringBuilder(80);
         int ch = r.read();
         boolean hasCR = false;
         // when reaching EOF before the first EOL, assume native line
@@ -455,13 +455,14 @@
         final char[] ch = new char[s.length() + 1];
         s.getChars(0, s.length(), ch, 0);
         ch[s.length()] = '\n';
-        final StringBuffer buffy = new StringBuffer(s.length());
+        final StringBuilder buffy = new StringBuilder(s.length());
         for (int i = 0; i < ch.length; i++) {
             char c = ch[i];
             if (c == '\n') {
                 // we have hit out end-of-string marker
                 break;
-            } else if (c == '\\') {
+            }
+            if (c == '\\') {
                 // possibly an escape sequence
                 c = ch[++i];
                 if (c == 'n') {
@@ -541,7 +542,7 @@
         s.getChars(0, s.length(), ch, 0);
         final String forEscaping = "\t\f\r\n\\:=#!";
         final String escaped = "tfrn\\:=#!";
-        final StringBuffer buffy = new StringBuffer(s.length());
+        final StringBuilder buffy = new StringBuilder(s.length());
         boolean leadingSpace = true;
         for (int i = 0; i < ch.length; i++) {
             final char c = ch[i];
@@ -572,7 +573,7 @@
      */
     private String escapeUnicode(final char ch) {
         return "\\" + UnicodeUtil.EscapeUnicode(ch);
-        }
+    }
 
     /**
      * Remove the comments in the leading up the {@link #logicalLines}
@@ -619,7 +620,9 @@
     /**
      * A logical line of the properties input stream.
      */
-    private abstract static class LogicalLine {
+    private abstract static class LogicalLine implements Serializable {
+        private static final long serialVersionUID = 1L;
+
         private String text;
 
         public LogicalLine(final String text) {
@@ -640,6 +643,8 @@
      * A blank line of the input stream.
      */
     private static class Blank extends LogicalLine {
+        private static final long serialVersionUID = 1L;
+
         public Blank() {
             super("");
         }
@@ -649,6 +654,8 @@
      * A comment line of the input stream.
      */
     private class Comment extends LogicalLine {
+        private static final long serialVersionUID = 1L;
+
         public Comment(final String text) {
             super(text);
         }
@@ -660,6 +667,8 @@
      * line.
      */
     private static class Pair extends LogicalLine implements Cloneable {
+        private static final long serialVersionUID = 1L;
+
         private String name;
         private String value;
         private boolean added;
@@ -677,6 +686,7 @@
             return name;
         }
 
+        @SuppressWarnings("unused")
         public String getValue() {
             return value;
         }
@@ -695,10 +705,10 @@
         }
 
         @Override
-        public Object clone() {
-            Object dolly = null;
+        public Pair clone() {
+            Pair dolly = null;
             try {
-                dolly = super.clone();
+                dolly = (Pair) super.clone();
             } catch (final CloneNotSupportedException e) {
                 // should be fine
                 e.printStackTrace(); //NOSONAR
@@ -712,10 +722,10 @@
             if (pos == -1) {
                 // trim leading whitespace only
                 name = text;
-                value = null;
+                setValue(null);
             } else {
                 name = text.substring(0, pos);
-                value = text.substring(pos + 1, text.length());
+                setValue(text.substring(pos + 1, text.length()));
             }
             // trim leading whitespace only
             name = stripStart(name, " \t\f");
diff --git a/src/main/org/apache/tools/ant/util/LazyFileOutputStream.java b/src/main/org/apache/tools/ant/util/LazyFileOutputStream.java
index 7e5bf78..cd7801d 100644
--- a/src/main/org/apache/tools/ant/util/LazyFileOutputStream.java
+++ b/src/main/org/apache/tools/ant/util/LazyFileOutputStream.java
@@ -18,9 +18,9 @@
 package org.apache.tools.ant.util;
 
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import org.apache.tools.ant.util.FileUtils;
 
 /**
  * Class that delays opening the output file until the first bytes
@@ -31,7 +31,7 @@
  */
 public class LazyFileOutputStream extends OutputStream {
 
-    private FileOutputStream fos;
+    private OutputStream fos;
     private File file;
     private boolean append;
     private boolean alwaysCreate;
@@ -107,6 +107,7 @@
      * Close the file.
      * @throws IOException if there is an error.
      */
+    @Override
     public synchronized void close() throws IOException {
         if (alwaysCreate && !closed) {
             ensureOpened();
@@ -122,6 +123,7 @@
      * @param b the bytearray to write.
      * @throws IOException if there is a problem.
      */
+    @Override
     public void write(byte[] b) throws IOException {
         write(b, 0, b.length);
     }
@@ -133,6 +135,7 @@
      * @param len    the number of bytes to write.
      * @throws IOException if there is a problem.
      */
+    @Override
     public synchronized void write(byte[] b, int offset, int len)
         throws IOException {
         ensureOpened();
@@ -144,6 +147,7 @@
      * @param b the byte to write.
      * @throws IOException if there is a problem.
      */
+    @Override
     public synchronized void write(int b) throws IOException {
         ensureOpened();
         fos.write(b);
@@ -155,7 +159,7 @@
         }
 
         if (!opened) {
-            fos = new FileOutputStream(file.getAbsolutePath(), append);
+            fos = FileUtils.newOutputStream(file.toPath(), append);
             opened = true;
         }
     }
diff --git a/src/main/org/apache/tools/ant/util/LazyHashtable.java b/src/main/org/apache/tools/ant/util/LazyHashtable.java
index 1df953c..9ef9091 100644
--- a/src/main/org/apache/tools/ant/util/LazyHashtable.java
+++ b/src/main/org/apache/tools/ant/util/LazyHashtable.java
@@ -28,6 +28,7 @@
  *
  * @since Ant 1.6
  */
+@Deprecated
 public class LazyHashtable extends Hashtable {
     // CheckStyle:VisibilityModifier OFF - bc
     protected boolean initAllDone = false;
diff --git a/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java b/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java
index 0081912..fa82a00 100644
--- a/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java
+++ b/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java
@@ -81,6 +81,7 @@
      * @return the byte (0 to 255) or -1 if there are no more.
      * @throws IOException if there is an error.
      */
+    @Override
     public synchronized int read() throws IOException {
         int result = -1;
         try {
diff --git a/src/main/org/apache/tools/ant/util/LineTokenizer.java b/src/main/org/apache/tools/ant/util/LineTokenizer.java
index 778606d..89d0b97 100644
--- a/src/main/org/apache/tools/ant/util/LineTokenizer.java
+++ b/src/main/org/apache/tools/ant/util/LineTokenizer.java
@@ -54,19 +54,19 @@
      * @exception IOException if an error occurs reading
      */
     public String getToken(Reader in) throws IOException {
-        int ch = -1;
-        if (pushed != NOT_A_CHAR) {
+        int ch;
+        if (pushed == NOT_A_CHAR) {
+            ch = in.read();
+        } else {
             ch = pushed;
             pushed = NOT_A_CHAR;
-        } else {
-            ch = in.read();
         }
         if (ch == -1) {
             return null;
         }
 
         lineEnd = "";
-        StringBuffer line = new StringBuffer();
+        StringBuilder line = new StringBuilder();
 
         int state = 0;
         while (ch != -1) {
@@ -104,11 +104,9 @@
     /**
      * @return the line ending character(s) for the current line
      */
+    @Override
     public String getPostToken() {
-        if (includeDelims) {
-            return "";
-        }
-        return lineEnd;
+        return includeDelims ? "" : lineEnd;
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/util/LinkedHashtable.java b/src/main/org/apache/tools/ant/util/LinkedHashtable.java
index 73fc83c..4f73273 100644
--- a/src/main/org/apache/tools/ant/util/LinkedHashtable.java
+++ b/src/main/org/apache/tools/ant/util/LinkedHashtable.java
@@ -43,89 +43,106 @@
     private final LinkedHashMap<K, V> map;
 
     public LinkedHashtable() {
-        map = new LinkedHashMap<K, V>();
+        map = new LinkedHashMap<>();
     }
 
     public LinkedHashtable(int initialCapacity) {
-        map = new LinkedHashMap<K, V>(initialCapacity);
+        map = new LinkedHashMap<>(initialCapacity);
     }
 
     public LinkedHashtable(int initialCapacity, float loadFactor) {
-        map = new LinkedHashMap<K, V>(initialCapacity, loadFactor);
+        map = new LinkedHashMap<>(initialCapacity, loadFactor);
     }
 
     public LinkedHashtable(Map<K, V> m) {
-        map = new LinkedHashMap<K, V>(m);
+        map = new LinkedHashMap<>(m);
     }
 
     public synchronized void clear() {
         map.clear();
     }
 
+    @Override
     public boolean contains(Object value) {
         return containsKey(value);
     }
 
+    @Override
     public synchronized boolean containsKey(Object value) {
         return map.containsKey(value);
     }
 
+    @Override
     public synchronized boolean containsValue(Object value) {
         return map.containsValue(value);
     }
 
+    @Override
     public Enumeration<V> elements() {
         return CollectionUtils.asEnumeration(values().iterator());
     }
 
+    @Override
     public synchronized Set<Map.Entry<K, V>> entrySet() {
         return map.entrySet();
     }
 
+    @Override
     public synchronized boolean equals(Object o) {
         return map.equals(o);
     }
 
+    @Override
     public synchronized V get(Object k) {
         return map.get(k);
     }
 
+    @Override
     public synchronized int hashCode() {
         return map.hashCode();
     }
 
+    @Override
     public synchronized boolean isEmpty() {
         return map.isEmpty();
     }
 
+    @Override
     public Enumeration<K> keys() {
         return CollectionUtils.asEnumeration(keySet().iterator());
     }
 
+    @Override
     public synchronized Set<K> keySet() {
         return map.keySet();
     }
 
+    @Override
     public synchronized V put(K k, V v) {
         return map.put(k, v);
     }
 
+    @Override
     public synchronized void putAll(Map<? extends K, ? extends V> m) {
         map.putAll(m);
     }
 
+    @Override
     public synchronized V remove(Object k) {
         return map.remove(k);
     }
 
+    @Override
     public synchronized int size() {
         return map.size();
     }
 
+    @Override
     public synchronized String toString() {
         return map.toString();
     }
 
+    @Override
     public synchronized Collection<V> values() {
         return map.values();
     }
diff --git a/src/main/org/apache/tools/ant/util/LoaderUtils.java b/src/main/org/apache/tools/ant/util/LoaderUtils.java
index e0514f6..799feb5 100644
--- a/src/main/org/apache/tools/ant/util/LoaderUtils.java
+++ b/src/main/org/apache/tools/ant/util/LoaderUtils.java
@@ -94,7 +94,7 @@
      *
      * @since Ant 1.6
      */
-    public static File getClassSource(Class c) {
+    public static File getClassSource(Class<?> c) {
         return normalizeSource(Locator.getClassSource(c));
     }
 
diff --git a/src/main/org/apache/tools/ant/util/MergingMapper.java b/src/main/org/apache/tools/ant/util/MergingMapper.java
index d61ae30..d7281a2 100644
--- a/src/main/org/apache/tools/ant/util/MergingMapper.java
+++ b/src/main/org/apache/tools/ant/util/MergingMapper.java
@@ -46,6 +46,7 @@
      * Ignored.
      * @param from ignored.
      */
+    @Override
     public void setFrom(String from) {
     }
 
@@ -53,6 +54,7 @@
      * Sets the name of the merged file.
      * @param to the name of the merged file.
      */
+    @Override
     public void setTo(String to) {
         mergedFile = new String[] {to};
     }
@@ -62,6 +64,7 @@
      * @param sourceFileName ignored.
      * @return a one-element array containing the merged filename.
      */
+    @Override
     public String[] mapFileName(String sourceFileName) {
         return mergedFile;
     }
diff --git a/src/main/org/apache/tools/ant/util/OutputStreamFunneler.java b/src/main/org/apache/tools/ant/util/OutputStreamFunneler.java
index 9b4cef3..84e0a0a 100644
--- a/src/main/org/apache/tools/ant/util/OutputStreamFunneler.java
+++ b/src/main/org/apache/tools/ant/util/OutputStreamFunneler.java
@@ -44,6 +44,7 @@
             }
         }
 
+        @Override
         public void flush() throws IOException {
             synchronized (OutputStreamFunneler.this) {
                 dieIfClosed();
@@ -51,6 +52,7 @@
             }
         }
 
+        @Override
         public void write(int b) throws IOException {
             synchronized (OutputStreamFunneler.this) {
                 dieIfClosed();
@@ -58,6 +60,7 @@
             }
         }
 
+        @Override
         public void write(byte[] b) throws IOException {
             synchronized (OutputStreamFunneler.this) {
                 dieIfClosed();
@@ -65,6 +68,7 @@
             }
         }
 
+        @Override
         public void write(byte[] b, int off, int len) throws IOException {
             synchronized (OutputStreamFunneler.this) {
                 dieIfClosed();
@@ -72,6 +76,7 @@
             }
         }
 
+        @Override
         public void close() throws IOException {
             release(this);
         }
diff --git a/src/main/org/apache/tools/ant/util/PackageNameMapper.java b/src/main/org/apache/tools/ant/util/PackageNameMapper.java
index 3025667..e50906d 100644
--- a/src/main/org/apache/tools/ant/util/PackageNameMapper.java
+++ b/src/main/org/apache/tools/ant/util/PackageNameMapper.java
@@ -37,6 +37,7 @@
      *@param  name  Source filename
      *@return       Replaced variable part
      */
+    @Override
     protected String extractVariablePart(String name) {
         String var = name.substring(prefixLength,
                 name.length() - postfixLength);
diff --git a/src/main/org/apache/tools/ant/util/PermissionUtils.java b/src/main/org/apache/tools/ant/util/PermissionUtils.java
new file mode 100644
index 0000000..a6664fb
--- /dev/null
+++ b/src/main/org/apache/tools/ant/util/PermissionUtils.java
@@ -0,0 +1,246 @@
+/*
+ *  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.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.PosixFileAttributeView;
+import java.nio.file.attribute.PosixFilePermission;
+import java.util.EnumSet;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.ArchiveResource;
+import org.apache.tools.ant.types.resources.FileProvider;
+
+/**
+ * Contains helper methods for dealing with {@link
+ * PosixFilePermission} or the traditional Unix mode representation of
+ * permissions.
+ *
+ * @since Ant 1.10.0
+ */
+public class PermissionUtils {
+
+    private PermissionUtils() { }
+
+    /**
+     * Translates a set of permissions into a Unix stat(2) {@code
+     * st_mode} result.
+     * @param permissions the permissions
+     * @param type the file type
+     * @return the "mode"
+     */
+    public static int modeFromPermissions(Set<PosixFilePermission> permissions,
+                                          FileType type) {
+        int mode;
+        switch (type) {
+        case SYMLINK:
+            mode = 012;
+            break;
+        case REGULAR_FILE:
+            mode = 010;
+            break;
+        case DIR:
+            mode = 004;
+            break;
+        default:
+            // OTHER could be a character or block device, a socket or a FIFO - so don't set anything
+            mode = 0;
+            break;
+        }
+        mode <<= 3;
+        mode <<= 3; // we don't support sticky, setuid, setgid
+        mode |= modeFromPermissions(permissions, "OWNER");
+        mode <<= 3;
+        mode |= modeFromPermissions(permissions, "GROUP");
+        mode <<= 3;
+        mode |= modeFromPermissions(permissions, "OTHERS");
+        return mode;
+    }
+
+    /**
+     * Translates a Unix stat(2) {@code st_mode} compatible value into
+     * a set of permissions.
+     * @param mode the "mode"
+     * @return set of permissions
+     */
+    public static Set<PosixFilePermission> permissionsFromMode(int mode) {
+        Set<PosixFilePermission> permissions = EnumSet.noneOf(PosixFilePermission.class);
+        addPermissions(permissions, "OTHERS", mode);
+        addPermissions(permissions, "GROUP", mode >> 3);
+        addPermissions(permissions, "OWNER", mode >> 6);
+        return permissions;
+    }
+
+    /**
+     * Sets permissions on a {@link Resource} - doesn't do anything
+     * for unsupported resource types.
+     *
+     * <p>Supported types are:</p>
+     * <ul>
+     *  <li>any {@link FileProvider}</li>
+     *  <li>{@link ArchiveResource}</li>
+     * </ul>
+     *
+     * @param r the resource to set permissions for
+     * @param permissions the permissions
+     * @param posixNotSupportedCallback optional callback that is
+     * invoked for a file provider resource if the file-system holding
+     * the file doesn't support PosixFilePermissions. The Path
+     * corresponding to the file is passed to the callback.
+     * @throws IOException if something goes wrong
+     */
+    public static void setPermissions(Resource r, Set<PosixFilePermission> permissions,
+                                      Consumer<Path> posixNotSupportedCallback)
+        throws IOException {
+        FileProvider f = r.as(FileProvider.class);
+        if (f != null) {
+            Path p = f.getFile().toPath();
+            PosixFileAttributeView view =
+                Files.getFileAttributeView(p, PosixFileAttributeView.class);
+            if (view != null) {
+                view.setPermissions(permissions);
+            } else if (posixNotSupportedCallback != null) {
+                posixNotSupportedCallback.accept(p);
+            }
+        } else if (r instanceof ArchiveResource) {
+            ((ArchiveResource) r).setMode(modeFromPermissions(permissions,
+                                                              FileType.of(r)));
+        }
+    }
+
+    /**
+     * Sets permissions of a {@link Resource} - returns an empty set
+     * for unsupported resource types or file systems that don't
+     * support PosixFilePermissions and no fallback has been
+     * provided..
+     *
+     * <p>Supported types are:</p>
+     * <ul>
+     *  <li>any {@link FileProvider}</li>
+     *  <li>{@link ArchiveResource}</li>
+     * </ul>
+     *
+     * @param r the resource to read permissions from
+     * @param posixNotSupportedFallback optional fallback function to provide
+     * permissions for file system that don't support
+     * PosixFilePermissions. The Path corresponding to the file is
+     * passed to the callback.
+     * @return the permissions
+     * @throws IOException if something goes wrong
+     */
+    public static Set<PosixFilePermission> getPermissions(Resource r,
+            Function<Path, Set<PosixFilePermission>> posixNotSupportedFallback)
+        throws IOException {
+        FileProvider f = r.as(FileProvider.class);
+        if (f != null) {
+            Path p = f.getFile().toPath();
+            PosixFileAttributeView view =
+                Files.getFileAttributeView(p, PosixFileAttributeView.class);
+            if (view != null) {
+                return view.readAttributes().permissions();
+            } else if (posixNotSupportedFallback != null) {
+                return posixNotSupportedFallback.apply(p);
+            }
+        } else if (r instanceof ArchiveResource) {
+            return permissionsFromMode(((ArchiveResource) r).getMode());
+        }
+        return EnumSet.noneOf(PosixFilePermission.class);
+    }
+
+    private static long modeFromPermissions(Set<PosixFilePermission> permissions,
+                                            String prefix) {
+        long mode = 0;
+        if (permissions.contains(PosixFilePermission.valueOf(prefix + "_READ"))) {
+            mode |= 4;
+        }
+        if (permissions.contains(PosixFilePermission.valueOf(prefix + "_WRITE"))) {
+            mode |= 2;
+        }
+        if (permissions.contains(PosixFilePermission.valueOf(prefix + "_EXECUTE"))) {
+            mode |= 1;
+        }
+        return mode;
+    }
+
+    private static void addPermissions(Set<PosixFilePermission> permissions,
+                                       String prefix, long mode) {
+        if ((mode & 1) == 1) {
+            permissions.add(PosixFilePermission.valueOf(prefix + "_EXECUTE"));
+        }
+        if ((mode & 2) == 2) {
+            permissions.add(PosixFilePermission.valueOf(prefix + "_WRITE"));
+        }
+        if ((mode & 4) == 4) {
+            permissions.add(PosixFilePermission.valueOf(prefix + "_READ"));
+        }
+    }
+
+    /**
+     * The supported types of files, maps to the {@code isFoo} methods
+     * in {@link java.nio.file.attribute.BasicFileAttributes}.
+     */
+    public enum FileType {
+        /** A regular file. */
+        REGULAR_FILE,
+        /** A directory. */
+        DIR,
+        /** A symbolic link. */
+        SYMLINK,
+        /** Something that is neither a regular file nor a directory nor a symbolic link. */
+        OTHER;
+
+        /**
+         * Determines the file type of a {@link Path}.
+         *
+         * @param p Path
+         * @return FileType
+         * @throws IOException if file attributes cannot be read
+         */
+        public static FileType of(Path p) throws IOException {
+            BasicFileAttributes attrs =
+                Files.readAttributes(p, BasicFileAttributes.class);
+            if (attrs.isRegularFile()) {
+                return FileType.REGULAR_FILE;
+            } else if (attrs.isDirectory()) {
+                return FileType.DIR;
+            } else if (attrs.isSymbolicLink()) {
+                return FileType.SYMLINK;
+            }
+            return FileType.OTHER;
+        }
+
+        /**
+         * Determines the file type of a {@link Resource}.
+         *
+         * @param r Resource
+         * @return FileType
+         */
+        public static FileType of(Resource r) {
+            if (r.isDirectory()) {
+                return FileType.DIR;
+            }
+            return FileType.REGULAR_FILE;
+        }
+    }
+}
diff --git a/src/main/org/apache/tools/ant/util/PropertyOutputStream.java b/src/main/org/apache/tools/ant/util/PropertyOutputStream.java
index 59a1b7e..6fdfdbd 100644
--- a/src/main/org/apache/tools/ant/util/PropertyOutputStream.java
+++ b/src/main/org/apache/tools/ant/util/PropertyOutputStream.java
@@ -19,13 +19,15 @@
 package org.apache.tools.ant.util;
 
 import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
 
 import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.resources.PropertyResource;
 
 /**
- * Exception thrown when an attempt is made to get an OutputStream
- * from an immutable Resource.
+ * {@link OutputStream} that writes an Ant property.
  * @since Ant 1.7
+ * @see PropertyResource#getOutputStream()
  */
 public class PropertyOutputStream extends ByteArrayOutputStream {
     private Project project;
@@ -58,6 +60,7 @@
     /**
      * Close the PropertyOutputStream, storing the property.
      */
+    @Override
     public void close() {
         if (project != null && property != null) {
             String s = new String(toByteArray());
diff --git a/src/main/org/apache/tools/ant/util/ProxySetup.java b/src/main/org/apache/tools/ant/util/ProxySetup.java
index ea69e72..60f9eb7 100644
--- a/src/main/org/apache/tools/ant/util/ProxySetup.java
+++ b/src/main/org/apache/tools/ant/util/ProxySetup.java
@@ -95,7 +95,7 @@
      * is set, use that instead. Else set to "true".
      */
     public void enableProxies() {
-        if (!(getSystemProxySetting() != null)) {
+        if (getSystemProxySetting() == null) {
             String proxies = owner.getProperty(USE_SYSTEM_PROXIES);
             if (proxies == null || Project.toBoolean(proxies)) {
                 proxies = "true";
diff --git a/src/main/org/apache/tools/ant/util/ReaderInputStream.java b/src/main/org/apache/tools/ant/util/ReaderInputStream.java
index 21733b6..e9abc80 100644
--- a/src/main/org/apache/tools/ant/util/ReaderInputStream.java
+++ b/src/main/org/apache/tools/ant/util/ReaderInputStream.java
@@ -60,9 +60,8 @@
         this(reader);
         if (encoding == null) {
             throw new IllegalArgumentException("encoding must not be null");
-        } else {
-            this.encoding = encoding;
         }
+        this.encoding = encoding;
     }
 
     /**
@@ -72,6 +71,7 @@
      *
      * @exception IOException if the original <code>Reader</code> fails to be read
      */
+    @Override
     public synchronized int read() throws IOException {
         if (in == null) {
             throw new IOException("Stream Closed");
@@ -104,6 +104,7 @@
      *         the end of the stream
      * @exception IOException if an error occurs
      */
+    @Override
     public synchronized int read(byte[] b, int off, int len)
         throws IOException {
         if (in == null) {
@@ -144,6 +145,7 @@
      * @param limit the maximum limit of bytes that can be read before the
      *              mark position becomes invalid
      */
+    @Override
     public synchronized void mark(final int limit) {
         try {
             in.mark(limit);
@@ -152,11 +154,11 @@
         }
     }
 
-
     /**
      * @return   the current number of bytes ready for reading
      * @exception IOException if an error occurs
      */
+    @Override
     public synchronized int available() throws IOException {
         if (in == null) {
             throw new IOException("Stream Closed");
@@ -173,6 +175,7 @@
     /**
      * @return false - mark is not supported
      */
+    @Override
     public boolean markSupported() {
         return false;   // would be imprecise
     }
@@ -182,6 +185,7 @@
      *
      * @exception IOException if the Reader fails to be reset
      */
+    @Override
     public synchronized void reset() throws IOException {
         if (in == null) {
             throw new IOException("Stream Closed");
@@ -195,6 +199,7 @@
      *
      * @exception IOException if the original Reader fails to be closed
      */
+    @Override
     public synchronized void close() throws IOException {
         if (in != null) {
             in.close();
diff --git a/src/main/org/apache/tools/ant/util/ReflectUtil.java b/src/main/org/apache/tools/ant/util/ReflectUtil.java
index bc62fa0..8392f71 100644
--- a/src/main/org/apache/tools/ant/util/ReflectUtil.java
+++ b/src/main/org/apache/tools/ant/util/ReflectUtil.java
@@ -21,6 +21,8 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 
@@ -61,16 +63,16 @@
 
     /**
      * Call a method on the object with no parameters.
+     * @param <T> desired type
      * @param obj  the object to invoke the method on.
      * @param methodName the name of the method to call
      * @return the object returned by the method
      */
-    public static Object invoke(Object obj, String methodName) {
+    @SuppressWarnings("unchecked")
+    public static <T> T invoke(Object obj, String methodName) {
         try {
-            Method method;
-            method = obj.getClass().getMethod(
-                        methodName, (Class[]) null);
-            return method.invoke(obj, (Object[]) null);
+            Method method = obj.getClass().getMethod(methodName);
+            return (T) method.invoke(obj);
         } catch (Exception t) {
             throwBuildException(t);
             return null; // NotReached
@@ -81,16 +83,16 @@
      * Call a method on the object with no parameters.
      * Note: Unlike the invoke method above, this
      * calls class or static methods, not instance methods.
+     * @param <T> desired type
      * @param obj  the object to invoke the method on.
      * @param methodName the name of the method to call
      * @return the object returned by the method
      */
-    public static Object invokeStatic(Object obj, String methodName) {
+    @SuppressWarnings("unchecked")
+    public static <T> T invokeStatic(Object obj, String methodName) {
         try {
-            Method method;
-            method = ((Class<?>) obj).getMethod(
-                    methodName, (Class[]) null);
-            return method.invoke(obj, (Object[]) null);
+            Method method = ((Class<?>) obj).getMethod(methodName);
+            return (T) method.invoke(obj);
         } catch (Exception t) {
             throwBuildException(t);
             return null; // NotReached
@@ -99,19 +101,19 @@
 
     /**
      * Call a method on the object with one argument.
+     * @param <T> desired type
      * @param obj  the object to invoke the method on.
      * @param methodName the name of the method to call
      * @param argType    the type of argument.
      * @param arg        the value of the argument.
      * @return the object returned by the method
      */
-    public static Object invoke(
+    @SuppressWarnings("unchecked")
+    public static <T> T invoke(
         Object obj, String methodName, Class<?> argType, Object arg) {
         try {
-            Method method;
-            method = obj.getClass().getMethod(
-                methodName, new Class[] {argType});
-            return method.invoke(obj, new Object[] {arg});
+            Method method = obj.getClass().getMethod(methodName, argType);
+            return (T) method.invoke(obj, arg);
         } catch (Exception t) {
             throwBuildException(t);
             return null; // NotReached
@@ -120,6 +122,7 @@
 
     /**
      * Call a method on the object with two argument.
+     * @param <T> desired type
      * @param obj  the object to invoke the method on.
      * @param methodName the name of the method to call
      * @param argType1   the type of the first argument.
@@ -128,14 +131,14 @@
      * @param arg2       the value of the second argument.
      * @return the object returned by the method
      */
-    public static Object invoke(
+    @SuppressWarnings("unchecked")
+    public static <T> T invoke(
         Object obj, String methodName, Class<?> argType1, Object arg1,
         Class<?> argType2, Object arg2) {
         try {
-            Method method;
-            method = obj.getClass().getMethod(
-                methodName, new Class[] {argType1, argType2});
-            return method.invoke(obj, new Object[] {arg1, arg2});
+            Method method =
+                obj.getClass().getMethod(methodName, argType1, argType2);
+            return (T) method.invoke(obj, arg1, arg2);
         } catch (Exception t) {
             throwBuildException(t);
             return null; // NotReached
@@ -144,17 +147,19 @@
 
     /**
      * Get the value of a field in an object.
+     * @param <T> desired type
      * @param obj the object to look at.
      * @param fieldName the name of the field in the object.
      * @return the value of the field.
      * @throws BuildException if there is an error.
      */
-    public static Object getField(Object obj, String fieldName)
+    @SuppressWarnings("unchecked")
+    public static <T> T getField(Object obj, String fieldName)
         throws BuildException {
         try {
             Field field = obj.getClass().getDeclaredField(fieldName);
             field.setAccessible(true);
-            return field.get(obj);
+            return (T) field.get(obj);
         } catch (Exception t) {
             throwBuildException(t);
             return null; // NotReached
@@ -187,9 +192,8 @@
                 return (BuildException) t2;
             }
             return new BuildException(t2);
-        } else {
-            return new BuildException(t);
         }
+        return new BuildException(t);
     }
 
     /**
@@ -203,15 +207,10 @@
     public static boolean respondsTo(Object o, String methodName)
         throws BuildException {
         try {
-            Method[] methods = o.getClass().getMethods();
-            for (int i = 0; i < methods.length; i++) {
-                if (methods[i].getName().equals(methodName)) {
-                    return true;
-                }
-            }
-            return false;
+            return Stream.of(o.getClass().getMethods()).map(Method::getName)
+                .anyMatch(Predicate.isEqual(methodName));
         } catch (Exception t) {
             throw toBuildException(t);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/org/apache/tools/ant/util/ReflectWrapper.java b/src/main/org/apache/tools/ant/util/ReflectWrapper.java
index e34363e..2001516 100644
--- a/src/main/org/apache/tools/ant/util/ReflectWrapper.java
+++ b/src/main/org/apache/tools/ant/util/ReflectWrapper.java
@@ -28,6 +28,7 @@
 
 public class ReflectWrapper {
     private Object obj;
+
     /**
      * Construct a wrapped object using the no arg constructor.
      * @param loader the classloader to use to construct the class.
@@ -35,11 +36,9 @@
      */
     public ReflectWrapper(ClassLoader loader, String name) {
         try {
-            Class clazz;
-            clazz = Class.forName(name, true, loader);
-            Constructor constructor;
-            constructor = clazz.getConstructor((Class[]) null);
-            obj = constructor.newInstance((Object[]) null);
+            Class<?> clazz = Class.forName(name, true, loader);
+            Constructor<?> constructor = clazz.getConstructor();
+            obj = constructor.newInstance();
         } catch (Exception t) {
             ReflectUtil.throwBuildException(t);
         }
@@ -54,35 +53,39 @@
     }
 
     /**
+     * @param <T> desired type
      * @return the wrapped object.
      */
-    public Object getObject() {
-        return obj;
+    @SuppressWarnings("unchecked")
+    public <T> T getObject() {
+        return (T) obj;
     }
 
     /**
      * Call a method on the object with no parameters.
+     * @param <T> desired type
      * @param methodName the name of the method to call
      * @return the object returned by the method
      */
-    public Object invoke(String methodName) {
+    public <T> T invoke(String methodName) {
         return ReflectUtil.invoke(obj, methodName);
     }
 
     /**
      * Call a method on the object with one argument.
+     * @param <T> desired type
      * @param methodName the name of the method to call
      * @param argType    the type of argument.
      * @param arg        the value of the argument.
      * @return the object returned by the method
      */
-    public Object invoke(
-        String methodName, Class argType, Object arg) {
+    public <T> T invoke(String methodName, Class<?> argType, Object arg) {
         return ReflectUtil.invoke(obj, methodName, argType, arg);
     }
 
     /**
      * Call a method on the object with one argument.
+     * @param <T> desired type
      * @param methodName the name of the method to call
      * @param argType1   the type of the first argument.
      * @param arg1       the value of the first argument.
@@ -90,10 +93,9 @@
      * @param arg2       the value of the second argument.
      * @return the object returned by the method
      */
-    public Object invoke(
-        String methodName, Class argType1, Object arg1,
-        Class argType2, Object arg2) {
-        return ReflectUtil.invoke(
-            obj, methodName, argType1, arg1, argType2, arg2);
+    public <T> T invoke(String methodName, Class<?> argType1, Object arg1,
+        Class<?> argType2, Object arg2) {
+        return ReflectUtil.invoke(obj, methodName, argType1, arg1, argType2,
+            arg2);
     }
 }
diff --git a/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java b/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java
index fa620d9..82bc109 100644
--- a/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java
+++ b/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java
@@ -18,7 +18,7 @@
 
 package org.apache.tools.ant.util;
 
-import java.util.Vector;
+import java.util.List;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.util.regexp.RegexpMatcher;
@@ -77,19 +77,19 @@
      * @param from the from pattern.
      * @throws BuildException on error.
      */
+    @Override
     public void setFrom(String from) throws BuildException {
-        if (from != null) {
-            try {
-                reg.setPattern(from);
-            } catch (NoClassDefFoundError e) {
-                // depending on the implementation the actual RE won't
-                // get instantiated in the constructor.
-                throw new BuildException("Cannot load regular expression matcher",
-                                         e);
-            }
-        } else {
+        if (from == null) {
             throw new BuildException("this mapper requires a 'from' attribute");
         }
+        try {
+            reg.setPattern(from);
+        } catch (NoClassDefFoundError e) {
+            // depending on the implementation the actual RE won't
+            // get instantiated in the constructor.
+            throw new BuildException("Cannot load regular expression matcher",
+                e);
+        }
     }
 
     /**
@@ -97,12 +97,12 @@
      * @param to the to pattern.
      * @throws BuildException on error.
      */
+    @Override
     public void setTo(String to) {
-        if (to != null) {
-            this.to = to.toCharArray();
-        } else {
+        if (to == null) {
             throw new BuildException("this mapper requires a 'to' attribute");
         }
+        this.to = to.toCharArray();
     }
 
     /**
@@ -113,6 +113,7 @@
      * @return a one-element array containing the translated file or
      *         null if the to pattern did not match
      */
+    @Override
     public String[] mapFileName(String sourceFileName) {
         if (handleDirSep) {
             if (sourceFileName.indexOf("\\") != -1) {
@@ -133,7 +134,7 @@
      * @return the translated file name.
      */
     protected String replaceReferences(String source) {
-        Vector v = reg.getGroups(source, regexpOptions);
+        List<String> v = reg.getGroups(source, regexpOptions);
 
         result.setLength(0);
         for (int i = 0; i < to.length; i++) {
@@ -141,7 +142,7 @@
                 if (++i < to.length) {
                     int value = Character.digit(to[i], DECIMAL);
                     if (value > -1) {
-                        result.append((String) v.elementAt(value));
+                        result.append(v.get(value));
                     } else {
                         result.append(to[i]);
                     }
diff --git a/src/main/org/apache/tools/ant/util/ResourceUtils.java b/src/main/org/apache/tools/ant/util/ResourceUtils.java
index 004cb6c..8e042ba 100644
--- a/src/main/org/apache/tools/ant/util/ResourceUtils.java
+++ b/src/main/org/apache/tools/ant/util/ResourceUtils.java
@@ -21,8 +21,6 @@
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -30,12 +28,15 @@
 import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.nio.channels.FileChannel;
+import java.nio.charset.Charset;
+import java.nio.file.StandardOpenOption;
 import java.util.Arrays;
 import java.util.Vector;
 
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.ProjectComponent;
 import org.apache.tools.ant.filters.util.ChainReaderHelper;
+import org.apache.tools.ant.types.FilterChain;
 import org.apache.tools.ant.types.FilterSetCollection;
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.types.ResourceCollection;
@@ -143,24 +144,8 @@
                                                             final ResourceFactory targets,
                                                             final long granularity) {
         logFuture(logTo, source, granularity);
-        final ResourceSelectorProvider p =
-            new ResourceSelectorProvider() {
-                public ResourceSelector
-                    getTargetSelectorForSource(final Resource sr) {
-                    return new ResourceSelector() {
-                        public boolean isSelected(final Resource target) {
-                            /* Extra I/O, probably wasted:
-                               if (target.isDirectory()) {
-                               return false;
-                               }
-                            */
-                            return SelectorUtils.isOutOfDate(sr, target,
-                                                             granularity);
-                        }
-                    };
-                }
-            };
-        return selectSources(logTo, source, mapper, targets, p);
+        return selectSources(logTo, source, mapper, targets,
+            sr -> target -> SelectorUtils.isOutOfDate(sr, target, granularity));
     }
 
     /**
@@ -182,7 +167,7 @@
                                                    final FileNameMapper mapper,
                                                    final ResourceFactory targets,
                                                    final ResourceSelectorProvider selector) {
-        if (source.size() == 0) {
+        if (source.isEmpty()) {
             logTo.log("No sources found.", Project.MSG_VERBOSE);
             return Resources.NONE;
         }
@@ -302,7 +287,7 @@
      * @since Ant 1.7
      */
     public static void copyResource(final Resource source, final Resource dest,
-                             final FilterSetCollection filters, final Vector filterChains,
+                             final FilterSetCollection filters, final Vector<FilterChain> filterChains,
                              final boolean overwrite, final boolean preserveLastModified,
                              final String inputEncoding, final String outputEncoding,
                              final Project project)
@@ -339,7 +324,7 @@
      * @since Ant 1.8
      */
     public static void copyResource(final Resource source, final Resource dest,
-                            final FilterSetCollection filters, final Vector filterChains,
+                            final FilterSetCollection filters, final Vector<FilterChain> filterChains,
                             final boolean overwrite, final boolean preserveLastModified,
                                     final boolean append,
                             final String inputEncoding, final String outputEncoding,
@@ -379,7 +364,7 @@
      * @since Ant 1.8.2
      */
     public static void copyResource(final Resource source, final Resource dest,
-                            final FilterSetCollection filters, final Vector filterChains,
+                            final FilterSetCollection filters, final Vector<FilterChain> filterChains,
                             final boolean overwrite, final boolean preserveLastModified,
                                     final boolean append,
                                     final String inputEncoding, final String outputEncoding,
@@ -392,8 +377,8 @@
         final boolean filterSetsAvailable = (filters != null
                                              && filters.hasFilters());
         final boolean filterChainsAvailable = (filterChains != null
-                                               && filterChains.size() > 0);
-        String effectiveInputEncoding = null;
+                                               && !filterChains.isEmpty());
+        String effectiveInputEncoding;
         if (source instanceof StringResource) {
             effectiveInputEncoding = ((StringResource) source).getEncoding();
         } else {
@@ -406,25 +391,25 @@
         if (destFile != null && destFile.isFile() && !destFile.canWrite()) {
             if (!force) {
                 throw new ReadOnlyTargetFileException(destFile);
-            } else if (!FILE_UTILS.tryHardToDelete(destFile)) {
-                throw new IOException("failed to delete read-only "
-                                      + "destination file " + destFile);
+            }
+            if (!FILE_UTILS.tryHardToDelete(destFile)) {
+                throw new IOException(
+                    "failed to delete read-only destination file " + destFile);
             }
         }
 
         if (filterSetsAvailable) {
             copyWithFilterSets(source, dest, filters, filterChains,
-                               filterChainsAvailable, append,
-                               effectiveInputEncoding, outputEncoding,
-                               project);
+                               append, effectiveInputEncoding,
+                               outputEncoding, project);
         } else if (filterChainsAvailable
                    || (effectiveInputEncoding != null
                        && !effectiveInputEncoding.equals(outputEncoding))
                    || (effectiveInputEncoding == null && outputEncoding != null)) {
             copyWithFilterChainsOrTranscoding(source, dest, filterChains,
-                                              filterChainsAvailable, append,
-                                              effectiveInputEncoding,
-                                              outputEncoding, project);
+                                              append, effectiveInputEncoding,
+                                              outputEncoding,
+                                              project);
         } else {
             boolean copied = false;
             if (source.as(FileProvider.class) != null
@@ -562,9 +547,8 @@
         if (fileProvider instanceof FileResource || fileProvider == null) {
             return (FileResource) fileProvider;
         }
-        final FileResource result = new FileResource(fileProvider.getFile());
-        result.setProject(Project.getProject(fileProvider));
-        return result;
+        return new FileResource(Project.getProject(fileProvider),
+            fileProvider.getFile());
     }
 
     /**
@@ -583,11 +567,9 @@
      * @since Ant 1.7
      */
     private static int binaryCompare(final Resource r1, final Resource r2) throws IOException {
-        InputStream in1 = null;
-        InputStream in2 = null;
-        try {
-            in1 = new BufferedInputStream(r1.getInputStream());
-            in2 = new BufferedInputStream(r2.getInputStream());
+        try (InputStream in1 = new BufferedInputStream(r1.getInputStream());
+                InputStream in2 =
+                    new BufferedInputStream(r2.getInputStream())) {
 
             for (int b1 = in1.read(); b1 != -1; b1 = in1.read()) {
                 final int b2 = in2.read();
@@ -596,9 +578,6 @@
                 }
             }
             return in2.read() == -1 ? 0 : -1;
-        } finally {
-            FileUtils.close(in1);
-            FileUtils.close(in2);
         }
     }
 
@@ -613,11 +592,10 @@
      * @since Ant 1.7
      */
     private static int textCompare(final Resource r1, final Resource r2) throws IOException {
-        BufferedReader in1 = null;
-        BufferedReader in2 = null;
-        try {
-            in1 = new BufferedReader(new InputStreamReader(r1.getInputStream()));
-            in2 = new BufferedReader(new InputStreamReader(r2.getInputStream()));
+        try (BufferedReader in1 =
+            new BufferedReader(new InputStreamReader(r1.getInputStream()));
+                BufferedReader in2 = new BufferedReader(
+                    new InputStreamReader(r2.getInputStream()))) {
 
             String expected = in1.readLine();
             while (expected != null) {
@@ -631,9 +609,6 @@
                 expected = in1.readLine();
             }
             return in2.readLine() == null ? 0 : -1; //NOSONAR
-        } finally {
-            FileUtils.close(in1);
-            FileUtils.close(in2);
         }
     }
 
@@ -660,10 +635,9 @@
 
     private static void copyWithFilterSets(final Resource source, final Resource dest,
                                            final FilterSetCollection filters,
-                                           final Vector filterChains,
-                                           final boolean filterChainsAvailable,
-                                           final boolean append, final String inputEncoding,
-                                           final String outputEncoding,
+                                           final Vector<FilterChain> filterChains,
+                                           final boolean append,
+                                           final String inputEncoding, final String outputEncoding,
                                            final Project project)
         throws IOException {
 
@@ -673,34 +647,12 @@
             return;
         }
 
-        BufferedReader in = null;
-        BufferedWriter out = null;
-        try {
-            InputStreamReader isr = null;
-            if (inputEncoding == null) {
-                isr = new InputStreamReader(source.getInputStream());
-            } else {
-                isr = new InputStreamReader(source.getInputStream(),
-                                            inputEncoding);
-            }
-            in = new BufferedReader(isr);
-            final OutputStream os = getOutputStream(dest, append, project);
-            OutputStreamWriter osw;
-            if (outputEncoding == null) {
-                osw = new OutputStreamWriter(os);
-            } else {
-                osw = new OutputStreamWriter(os, outputEncoding);
-            }
-            out = new BufferedWriter(osw);
-            if (filterChainsAvailable) {
-                final ChainReaderHelper crh = new ChainReaderHelper();
-                crh.setBufferSize(FileUtils.BUF_SIZE);
-                crh.setPrimaryReader(in);
-                crh.setFilterChains(filterChains);
-                crh.setProject(project);
-                final Reader rdr = crh.getAssembledReader();
-                in = new BufferedReader(rdr);
-            }
+        try (Reader in = filterWith(project, inputEncoding, filterChains,
+                source.getInputStream());
+             BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
+                     getOutputStream(dest, append, project),
+                     charsetFor(outputEncoding)))) {
+
             final LineTokenizer lineTokenizer = new LineTokenizer();
             lineTokenizer.setIncludeDelims(true);
             String newline = null;
@@ -716,16 +668,30 @@
                 }
                 line = lineTokenizer.getToken(in);
             }
-        } finally {
-            FileUtils.close(out);
-            FileUtils.close(in);
         }
     }
 
+    private static Reader filterWith(Project project, String encoding,
+        Vector<FilterChain> filterChains, InputStream input) {
+        Reader r = new InputStreamReader(input, charsetFor(encoding));
+        if (filterChains != null && !filterChains.isEmpty()) {
+            final ChainReaderHelper crh = new ChainReaderHelper();
+            crh.setBufferSize(FileUtils.BUF_SIZE);
+            crh.setPrimaryReader(r);
+            crh.setFilterChains(filterChains);
+            crh.setProject(project);
+            r = crh.getAssembledReader();
+        }
+        return new BufferedReader(r);
+    }
+
+    private static Charset charsetFor(String encoding) {
+        return encoding == null ? Charset.defaultCharset() : Charset.forName(encoding);
+    }
+
     private static void copyWithFilterChainsOrTranscoding(final Resource source,
                                                           final Resource dest,
-                                                          final Vector filterChains,
-                                                          final boolean filterChainsAvailable,
+                                                          final Vector<FilterChain> filterChains,
                                                           final boolean append,
                                                           final String inputEncoding,
                                                           final String outputEncoding,
@@ -738,34 +704,11 @@
             return;
         }
 
-        BufferedReader in = null;
-        BufferedWriter out = null;
-        try {
-            InputStreamReader isr = null;
-            if (inputEncoding == null) {
-                isr = new InputStreamReader(source.getInputStream());
-            } else {
-                isr = new InputStreamReader(source.getInputStream(),
-                                            inputEncoding);
-            }
-            in = new BufferedReader(isr);
-            final OutputStream os = getOutputStream(dest, append, project);
-            OutputStreamWriter osw;
-            if (outputEncoding == null) {
-                osw = new OutputStreamWriter(os);
-            } else {
-                osw = new OutputStreamWriter(os, outputEncoding);
-            }
-            out = new BufferedWriter(osw);
-            if (filterChainsAvailable) {
-                final ChainReaderHelper crh = new ChainReaderHelper();
-                crh.setBufferSize(FileUtils.BUF_SIZE);
-                crh.setPrimaryReader(in);
-                crh.setFilterChains(filterChains);
-                crh.setProject(project);
-                final Reader rdr = crh.getAssembledReader();
-                in = new BufferedReader(rdr);
-            }
+        try (Reader in = filterWith(project, inputEncoding, filterChains,
+                source.getInputStream());
+             BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
+                     getOutputStream(dest, append, project),
+                     charsetFor(outputEncoding)))) {
             final char[] buffer = new char[FileUtils.BUF_SIZE];
             while (true) {
                 final int nRead = in.read(buffer, 0, buffer.length);
@@ -774,10 +717,8 @@
                 }
                 out.write(buffer, 0, nRead);
             }
-        } finally {
-            FileUtils.close(out);
-            FileUtils.close(in);
         }
+
     }
 
     private static void copyUsingFileChannels(final File sourceFile,
@@ -796,30 +737,20 @@
                                   + " for " + destFile);
         }
 
-        FileInputStream in = null;
-        FileOutputStream out = null;
-        FileChannel srcChannel = null;
-        FileChannel destChannel = null;
-
-        try {
-            in = new FileInputStream(sourceFile);
-            out = new FileOutputStream(destFile);
-
-            srcChannel = in.getChannel();
-            destChannel = out.getChannel();
-
+        try (FileChannel srcChannel =
+            FileChannel.open(sourceFile.toPath(), StandardOpenOption.READ);
+                FileChannel destChannel = FileChannel.open(destFile.toPath(),
+                    StandardOpenOption.CREATE,
+                    StandardOpenOption.TRUNCATE_EXISTING,
+                    StandardOpenOption.WRITE)) {
             long position = 0;
             final long count = srcChannel.size();
             while (position < count) {
-                final long chunk = Math.min(MAX_IO_CHUNK_SIZE, count - position);
+                final long chunk =
+                    Math.min(MAX_IO_CHUNK_SIZE, count - position);
                 position +=
                     destChannel.transferFrom(srcChannel, position, chunk);
             }
-        } finally {
-            FileUtils.close(srcChannel);
-            FileUtils.close(destChannel);
-            FileUtils.close(out);
-            FileUtils.close(in);
         }
     }
 
@@ -832,12 +763,8 @@
             log(project, "Skipping (self) copy of " + source +  " to " + dest);
             return;
         }
-
-        InputStream in = null;
-        OutputStream out = null;
-        try {
-            in = source.getInputStream();
-            out = getOutputStream(dest, append, project);
+        try (InputStream in = source.getInputStream();
+             OutputStream out = getOutputStream(dest, append, project)) {
 
             final byte[] buffer = new byte[FileUtils.BUF_SIZE];
             int count = 0;
@@ -845,9 +772,6 @@
                 out.write(buffer, 0, count);
                 count = in.read(buffer, 0, buffer.length);
             } while (count != -1);
-        } finally {
-            FileUtils.close(out);
-            FileUtils.close(in);
         }
     }
 
diff --git a/src/main/org/apache/tools/ant/util/ScriptFixBSFPath.java b/src/main/org/apache/tools/ant/util/ScriptFixBSFPath.java
index ca76e56..407c5c6 100644
--- a/src/main/org/apache/tools/ant/util/ScriptFixBSFPath.java
+++ b/src/main/org/apache/tools/ant/util/ScriptFixBSFPath.java
@@ -56,7 +56,7 @@
             "xslt",       "org.apache.xpath.objects.XObject"};
 
     /** A map of languages for which the engine in located in bsf */
-    private static final Map BSF_LANGUAGE_MAP = new HashMap();
+    private static final Map<String, String> BSF_LANGUAGE_MAP = new HashMap<>();
     static {
         for (int i = 0; i < BSF_LANGUAGES.length; i = i + 2) {
             BSF_LANGUAGE_MAP.put(BSF_LANGUAGES[i], BSF_LANGUAGES[i + 1]);
diff --git a/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java b/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java
index 5e2857e..6cf3962 100644
--- a/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java
+++ b/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java
@@ -19,14 +19,13 @@
 
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 
 import org.apache.tools.ant.BuildException;
@@ -34,6 +33,8 @@
 import org.apache.tools.ant.ProjectComponent;
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.PropertyResource;
+import org.apache.tools.ant.types.resources.StringResource;
 
 /**
  * This is a common abstract base case for script runners.
@@ -51,6 +52,11 @@
     /** Script content */
     private String script = "";
 
+    private String encoding;
+
+    /** Enable script compilation. */
+    private boolean compiled;
+
     /** Project this runner is used in */
     private Project project;
 
@@ -58,7 +64,7 @@
     private ClassLoader scriptLoader;
 
     /** Beans to be provided to the script */
-    private Map beans = new HashMap();
+    private final Map<String, Object> beans = new HashMap<>();
 
     /**
      * Add a list of named objects to the list to be exported to the script
@@ -66,19 +72,17 @@
      * @param dictionary a map of objects to be placed into the script context
      *        indexed by String names.
      */
-    public void addBeans(Map dictionary) {
-        for (Iterator i = dictionary.keySet().iterator(); i.hasNext();) {
-            String key = (String) i.next();
+    public void addBeans(Map<String, ?> dictionary) {
+        dictionary.forEach((k, v) -> {
             try {
-                Object val = dictionary.get(key);
-                addBean(key, val);
+                addBean(k, v);
             } catch (BuildException ex) {
                 // The key is in the dictionary but cannot be retrieved
                 // This is usually due references that refer to tasks
                 // that have not been taskdefed in the current run.
                 // Ignore
             }
-        }
+        });
     }
 
     /**
@@ -94,7 +98,6 @@
         for (int i = 1; isValid && i < key.length(); i++) {
             isValid = Character.isJavaIdentifierPart(key.charAt(i));
         }
-
         if (isValid) {
             beans.put(key, bean);
         }
@@ -104,7 +107,7 @@
      * Get the beans used for the script.
      * @return the map of beans.
      */
-    protected Map getBeans() {
+    protected Map<String, Object> getBeans() {
         return beans;
     }
 
@@ -187,19 +190,47 @@
     }
 
     /**
+     * Whether to use script compilation if available.
+     * @since Ant 1.10.2
+     * @param compiled if true, compile the script if possible.
+     */
+    public final void setCompiled(boolean compiled) {
+        this.compiled = compiled;
+    }
+
+    /**
+     * Get the compiled attribute.
+     * @since Ant 1.10.2
+     * @return the attribute.
+     */
+    public final boolean getCompiled() {
+        return compiled;
+    }
+
+    /**
+     * Set encoding of the script from an external file; optional.
+     * @since Ant 1.10.2
+     * @param encoding  encoding of the external file containing the script source.
+     */
+    public void setEncoding(String encoding) {
+        this.encoding = encoding;
+    }
+
+    /**
      * Load the script from an external file; optional.
      * @param file the file containing the script source.
      */
     public void setSrc(File file) {
         String filename = file.getPath();
-        if (!file.exists()) {
-            throw new BuildException("file " + filename + " not found.");
-        }
-        try {
-            readSource(new FileReader(file), filename);
-        } catch (FileNotFoundException e) {
+
+        try (InputStream in = Files.newInputStream(file.toPath())) {
+            final Charset charset = null == encoding ? Charset.defaultCharset()
+                : Charset.forName(encoding);
+
+            readSource(in, filename, charset);
+        } catch (IOException e) {
             //this can only happen if the file got deleted a short moment ago
-            throw new BuildException("file " + filename + " not found.");
+            throw new BuildException("file " + filename + " not found.", e);
         }
     }
 
@@ -207,20 +238,17 @@
      * Read some source in from the given reader
      * @param in the input stream to pass into a buffered reader.
      * @param name the name to use in error messages
+     * @param charset the encoding for the reader, may be null.
      */
-    private void readSource(Reader reader, String name) {
-        BufferedReader in = null;
-        try {
-            in = new BufferedReader(reader);
-            script += FileUtils.safeReadFully(in);
+    private void readSource(InputStream in, String name, Charset charset) {
+        try (Reader reader =
+            new BufferedReader(new InputStreamReader(in, charset))) {
+            script += FileUtils.safeReadFully(reader);
         } catch (IOException ex) {
             throw new BuildException("Failed to read " + name, ex);
-        } finally {
-            FileUtils.close(in);
         }
     }
 
-
     /**
      * Add a resource to the source list.
      * @since Ant 1.7.1
@@ -228,17 +256,24 @@
      * @throws BuildException if the resource cannot be read
      */
     public void loadResource(Resource sourceResource) {
+        if (sourceResource instanceof StringResource) {
+            script += ((StringResource) sourceResource).getValue();
+            return;
+        }
+        if (sourceResource instanceof PropertyResource) {
+            script += ((PropertyResource) sourceResource).getValue();
+            return;
+        }
+
         String name = sourceResource.toLongString();
-        InputStream in = null;
-        try {
-            in = sourceResource.getInputStream();
+        try (InputStream in = sourceResource.getInputStream()) {
+            readSource(in, name, Charset.defaultCharset());
         } catch (IOException e) {
             throw new BuildException("Failed to open " + name, e);
         } catch (UnsupportedOperationException e) {
             throw new BuildException(
-                "Failed to open " + name + " -it is not readable", e);
+                "Failed to open " + name + " - it is not readable", e);
         }
-        readSource(new InputStreamReader(in), name);
     }
 
     /**
@@ -248,9 +283,7 @@
      * @throws BuildException if a resource cannot be read
      */
     public void loadResources(ResourceCollection collection) {
-        for (Resource resource : collection) {
-            loadResource(resource);
-        }
+        collection.forEach(this::loadResource);
     }
 
     /**
@@ -326,8 +359,7 @@
      */
     protected void checkLanguage() {
         if (language == null) {
-            throw new BuildException(
-                "script language must be specified");
+            throw new BuildException("script language must be specified");
         }
     }
 
@@ -356,5 +388,4 @@
         Thread.currentThread().setContextClassLoader(
                  origLoader);
     }
-
 }
diff --git a/src/main/org/apache/tools/ant/util/ScriptRunnerHelper.java b/src/main/org/apache/tools/ant/util/ScriptRunnerHelper.java
index e25811d..efdb1b0 100644
--- a/src/main/org/apache/tools/ant/util/ScriptRunnerHelper.java
+++ b/src/main/org/apache/tools/ant/util/ScriptRunnerHelper.java
@@ -31,9 +31,11 @@
 public class ScriptRunnerHelper {
     private ClasspathUtils.Delegate cpDelegate = null;
     private File    srcFile;
+    private String  encoding;
     private String  manager = "auto";
     private String  language;
     private String  text;
+    private boolean compiled = false;
     private boolean setBeans = true;
     private ProjectComponent projectComponent;
     private ClassLoader scriptLoader = null;
@@ -53,6 +55,12 @@
      */
     public ScriptRunnerBase getScriptRunner() {
         ScriptRunnerBase runner = getRunner();
+        runner.setCompiled(compiled);
+
+        if (encoding != null) {
+            // set it first, because runner.setSrc() loads immediately the file
+            runner.setEncoding(encoding);
+        }
         if (srcFile != null) {
             runner.setSrc(srcFile);
         }
@@ -108,6 +116,34 @@
     }
 
     /**
+     * Get the external script file; optional.
+     * @return the file containing the script source.
+     * @since Ant 1.10.2
+     */
+    public File getSrc() {
+        return srcFile;
+    }
+
+    /**
+     * Set the encoding of the script from an external file; optional.
+     *
+     * @param encoding the encoding of the file containing the script source.
+     * @since Ant 1.10.2
+     */
+    public void setEncoding(String encoding) {
+        this.encoding = encoding;
+    }
+
+    /**
+     * Get the external file encoding.
+     * @return the encoding of the file containing the script source.
+     * @since Ant 1.10.2
+     */
+    public String getEncoding() {
+        return encoding;
+    }
+
+    /**
      * Add script text.
      *
      * @param text a component of the script text to be added.
@@ -143,6 +179,28 @@
     }
 
     /**
+     * Enable the compilation of the script if possible.
+     * If this is true and the compilation feature is available in
+     * the script engine, the script is compiled before the first
+     * evaluation, and should be cached for future evaluations.
+     * Otherwise, the script is evaluated each time.
+     * The default is false.
+     *
+     * @param compiled the value to set.
+     */
+    public void setCompiled(boolean compiled) {
+        this.compiled = compiled;
+    }
+
+    /**
+     * Get the compilation feature.
+     * @return the compilation feature.
+     */
+    public boolean getCompiled() {
+        return this.compiled;
+    }
+
+    /**
      * Set the setbeans attribute.
      * If this is true, &lt;script&gt; will create variables in the
      * script instance for all
diff --git a/src/main/org/apache/tools/ant/util/SourceFileScanner.java b/src/main/org/apache/tools/ant/util/SourceFileScanner.java
index c79f034..7d76eaf 100644
--- a/src/main/org/apache/tools/ant/util/SourceFileScanner.java
+++ b/src/main/org/apache/tools/ant/util/SourceFileScanner.java
@@ -19,7 +19,7 @@
 package org.apache.tools.ant.util;
 
 import java.io.File;
-import java.util.Vector;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.Task;
 import org.apache.tools.ant.types.Resource;
@@ -90,28 +90,21 @@
                              FileNameMapper mapper, long granularity) {
         // record destdir for later use in getResource
         this.destDir = destDir;
-        Vector v = new Vector();
-        for (int i = 0; i < files.length; i++) {
-            final String name = files[i];
-            v.addElement(new FileResource(srcDir, name) {
+
+        Resource[] sourceResources =
+            Stream.of(files).map(f -> new FileResource(srcDir, f) {
+                @Override
                 public String getName() {
-                    return name;
+                    return f;
                 }
-            });
-        }
-        Resource[] sourceresources = new Resource[v.size()];
-        v.copyInto(sourceresources);
+            }).toArray(Resource[]::new);
 
         // build the list of sources which are out of date with
         // respect to the target
-        Resource[] outofdate =
-            ResourceUtils.selectOutOfDateSources(task, sourceresources,
-                                                 mapper, this, granularity);
-        String[] result = new String[outofdate.length];
-        for (int counter = 0; counter < outofdate.length; counter++) {
-            result[counter] = outofdate[counter].getName();
-        }
-        return result;
+        return Stream
+            .of(ResourceUtils.selectOutOfDateSources(task, sourceResources,
+                mapper, this, granularity))
+            .map(Resource::getName).toArray(String[]::new);
     }
 
     /**
@@ -150,12 +143,8 @@
      */
     public File[] restrictAsFiles(String[] files, File srcDir, File destDir,
                                   FileNameMapper mapper, long granularity) {
-        String[] res = restrict(files, srcDir, destDir, mapper, granularity);
-        File[] result = new File[res.length];
-        for (int i = 0; i < res.length; i++) {
-            result[i] = new File(srcDir, res[i]);
-        }
-        return result;
+        return Stream.of(restrict(files, srcDir, destDir, mapper, granularity))
+            .map(name -> new File(srcDir, name)).toArray(File[]::new);
     }
 
     /**
@@ -165,6 +154,7 @@
      *
      * @since Ant 1.5.2
      */
+    @Override
     public Resource getResource(String name) {
         return new FileResource(destDir, name);
     }
diff --git a/src/main/org/apache/tools/ant/util/SplitClassLoader.java b/src/main/org/apache/tools/ant/util/SplitClassLoader.java
index 9d657da..c3f61e3 100644
--- a/src/main/org/apache/tools/ant/util/SplitClassLoader.java
+++ b/src/main/org/apache/tools/ant/util/SplitClassLoader.java
@@ -45,9 +45,10 @@
 
     // forceLoadClass is not convenient here since it would not
     // properly deal with inner classes of these classes.
-    protected synchronized Class loadClass(String classname, boolean resolve)
+    @Override
+    protected synchronized Class<?> loadClass(String classname, boolean resolve)
         throws ClassNotFoundException {
-        Class theClass = findLoadedClass(classname);
+        Class<?> theClass = findLoadedClass(classname);
         if (theClass != null) {
             return theClass;
         }
@@ -57,9 +58,8 @@
                 resolveClass(theClass);
             }
             return theClass;
-        } else {
-            return super.loadClass(classname, resolve);
         }
+        return super.loadClass(classname, resolve);
     }
 
     private boolean isSplit(String classname) {
diff --git a/src/main/org/apache/tools/ant/util/StringTokenizer.java b/src/main/org/apache/tools/ant/util/StringTokenizer.java
index 7addf31..5835335 100644
--- a/src/main/org/apache/tools/ant/util/StringTokenizer.java
+++ b/src/main/org/apache/tools/ant/util/StringTokenizer.java
@@ -96,8 +96,8 @@
         }
         boolean inToken = true;
         intraString = "";
-        StringBuffer word = new StringBuffer();
-        StringBuffer padding = new StringBuffer();
+        StringBuilder word = new StringBuilder();
+        StringBuilder padding = new StringBuilder();
         while (ch != -1) {
             char c = (char) ch;
             boolean isDelim = isDelim(c);
@@ -116,13 +116,11 @@
                 } else {
                     word.append(c);
                 }
+            } else if (isDelim) {
+                padding.append(c);
             } else {
-                if (isDelim) {
-                    padding.append(c);
-                } else {
-                    pushed = ch;
-                    break;
-                }
+                pushed = ch;
+                break;
             }
             ch = in.read();
         }
@@ -136,6 +134,7 @@
     /**
      * @return the intratoken string
      */
+    @Override
     public String getPostToken() {
         return suppressDelims || includeDelims ? "" : intraString;
     }
diff --git a/src/main/org/apache/tools/ant/util/StringUtils.java b/src/main/org/apache/tools/ant/util/StringUtils.java
index 4ce9ee3..70191ed 100644
--- a/src/main/org/apache/tools/ant/util/StringUtils.java
+++ b/src/main/org/apache/tools/ant/util/StringUtils.java
@@ -19,7 +19,11 @@
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Vector;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
 
@@ -148,7 +152,7 @@
      * @since Ant 1.7
      */
     public static String resolveBackSlash(String input) {
-        StringBuffer b = new StringBuffer();
+        StringBuilder b = new StringBuilder();
         boolean backSlashSeen = false;
         for (int i = 0; i < input.length(); ++i) {
             char c = input.charAt(i);
@@ -251,9 +255,8 @@
     public static String removeSuffix(String string, String suffix) {
         if (string.endsWith(suffix)) {
             return string.substring(0, string.length() - suffix.length());
-        } else {
-            return string;
         }
+        return string;
     }
 
     /**
@@ -266,8 +269,55 @@
     public static String removePrefix(String string, String prefix) {
         if (string.startsWith(prefix)) {
             return string.substring(prefix.length());
-        } else {
-            return string;
         }
+        return string;
     }
+
+    /**
+     * Joins the string representation of the elements of a collection to
+     * a joined string with a given separator.
+     * @param collection Collection of the data to be joined (may be null)
+     * @param separator Separator between elements (may be null)
+     * @return the joined string
+     */
+    public static String join(Collection<?> collection, CharSequence separator) {
+        if (collection == null) {
+            return "";
+        }
+        return collection.stream().map(String::valueOf)
+            .collect(joining(separator));
+    }
+
+    /**
+     * Joins the string representation of the elements of an array to
+     * a joined string with a given separator.
+     * @param array Array of the data to be joined (may be null)
+     * @param separator Separator between elements (may be null)
+     * @return the joined string
+     */
+    public static String join(Object[] array, CharSequence separator) {
+        if (array == null) {
+            return "";
+        }
+        return join(Arrays.asList(array), separator);
+    }
+
+    private static Collector<CharSequence, ?, String> joining(CharSequence separator) {
+        return separator == null ? Collectors.joining() : Collectors.joining(separator);
+    }
+
+    /**
+     * @param inputString String to trim
+     * @return null if the input string is null or empty or contain only empty spaces.
+     * It returns the input string without leading and trailing spaces otherwise.
+     *
+     */
+    public static String trimToNull(String inputString) {
+        if (inputString == null) {
+            return null;
+        }
+        String tmpString = inputString.trim();
+        return tmpString.isEmpty() ? null : tmpString;
+    }
+
 }
diff --git a/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java b/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java
index 20975dd..5e12094 100644
--- a/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java
+++ b/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java
@@ -19,7 +19,6 @@
 
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.io.FilenameFilter;
 import java.io.IOException;
 
 import org.apache.tools.ant.BuildException;
@@ -31,7 +30,11 @@
  * a symbolic link based on the absent support for them in Java.
  *
  * @since Ant 1.8.0
+ * @deprecated Starting Ant 1.10.2, this class is now deprecated in favour
+ *              of the Java {@link java.nio.file.Files} APIs introduced in
+ *              Java 7, for dealing with symbolic links
  */
+@Deprecated
 public class SymbolicLinkUtils {
     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
 
@@ -176,11 +179,7 @@
         final File f = new File(parent, name);
         if (!f.exists()) {
             final String localName = f.getName();
-            final String[] c = parent.list(new FilenameFilter() {
-                    public boolean accept(final File d, final String n) {
-                        return localName.equals(n);
-                    }
-                });
+            final String[] c = parent.list((d, n) -> localName.equals(n));
             return c != null && c.length > 0;
         }
         return false;
diff --git a/src/main/org/apache/tools/ant/util/TeeOutputStream.java b/src/main/org/apache/tools/ant/util/TeeOutputStream.java
index eb8da3f..44c2f4a 100644
--- a/src/main/org/apache/tools/ant/util/TeeOutputStream.java
+++ b/src/main/org/apache/tools/ant/util/TeeOutputStream.java
@@ -43,6 +43,7 @@
      * Close both output streams.
      * @throws IOException on error.
      */
+    @Override
     public void close() throws IOException {
         try {
             left.close();
@@ -55,6 +56,7 @@
      * Flush both output streams.
      * @throws IOException on error
      */
+    @Override
     public void flush() throws IOException {
         left.flush();
         right.flush();
@@ -65,6 +67,7 @@
      * @param b an array of bytes.
      * @throws IOException on error.
      */
+    @Override
     public void write(byte[] b) throws IOException {
         left.write(b);
         right.write(b);
@@ -77,6 +80,7 @@
      * @param len   the number of bytes to write.
      * @throws IOException on error.
      */
+    @Override
     public void write(byte[] b, int off, int len) throws IOException {
         left.write(b, off, len);
         right.write(b, off, len);
@@ -87,9 +91,9 @@
      * @param b the byte to write.
      * @throws IOException on error.
      */
+    @Override
     public void write(int b) throws IOException {
         left.write(b);
         right.write(b);
     }
 }
-
diff --git a/src/main/org/apache/tools/ant/util/UnPackageNameMapper.java b/src/main/org/apache/tools/ant/util/UnPackageNameMapper.java
index 1777279..36c7e40 100644
--- a/src/main/org/apache/tools/ant/util/UnPackageNameMapper.java
+++ b/src/main/org/apache/tools/ant/util/UnPackageNameMapper.java
@@ -39,6 +39,7 @@
      *@param  name  Source filename
      *@return       Replaced variable part
      */
+    @Override
     protected String extractVariablePart(String name) {
         String var = name.substring(prefixLength,
                 name.length() - postfixLength);
diff --git a/src/main/org/apache/tools/ant/util/VectorSet.java b/src/main/org/apache/tools/ant/util/VectorSet.java
index db13129..9c152ca 100644
--- a/src/main/org/apache/tools/ant/util/VectorSet.java
+++ b/src/main/org/apache/tools/ant/util/VectorSet.java
@@ -42,9 +42,13 @@
 
     private final HashSet<E> set = new HashSet<E>();
 
-    public VectorSet() { super(); }
+    public VectorSet() {
+        super();
+    }
 
-    public VectorSet(int initialCapacity) { super(initialCapacity); }
+    public VectorSet(int initialCapacity) {
+        super(initialCapacity);
+    }
 
     public VectorSet(int initialCapacity, int capacityIncrement) {
         super(initialCapacity, capacityIncrement);
@@ -52,12 +56,11 @@
 
     public VectorSet(Collection<? extends E> c) {
         if (c != null) {
-            for (E e : c) {
-                add(e);
-            }
+            this.addAll(c);
         }
     }
 
+    @Override
     public synchronized boolean add(E o) {
         if (!set.contains(o)) {
             doAdd(size(), o);
@@ -70,6 +73,7 @@
      * This implementation may not add the element at the given index
      * if it is already contained in the collection.
      */
+    @Override
     public void add(int index, E o) {
         doAdd(index, o);
     }
@@ -89,10 +93,12 @@
         }
     }
 
+    @Override
     public synchronized void addElement(E o) {
         doAdd(size(), o);
     }
 
+    @Override
     public synchronized boolean addAll(Collection<? extends E> c) {
         boolean changed = false;
         for (E e : c) {
@@ -105,8 +111,9 @@
      * This implementation may not add all elements at the given index
      * if any of them are already contained in the collection.
      */
+    @Override
     public synchronized boolean addAll(int index, Collection<? extends E> c) {
-        LinkedList toAdd = new LinkedList();
+        LinkedList<E> toAdd = new LinkedList<>();
         for (E e : c) {
             if (set.add(e)) {
                 toAdd.add(e);
@@ -128,36 +135,43 @@
         return true;
     }
 
+    @Override
     public synchronized void clear() {
         super.clear();
         set.clear();
     }
 
-    public Object clone() {
+    @Override
+    public VectorSet<E> clone() {
         @SuppressWarnings("unchecked")
         final VectorSet<E> vs = (VectorSet<E>) super.clone();
         vs.set.addAll(set);
         return vs;
     }
 
+    @Override
     public synchronized boolean contains(Object o) {
         return set.contains(o);
     }
 
+    @Override
     public synchronized boolean containsAll(Collection<?> c) {
         return set.containsAll(c);
     }
 
+    @Override
     public void insertElementAt(E o, int index) {
         doAdd(index, o);
     }
 
+    @Override
     public synchronized E remove(int index) {
         E o = get(index);
         remove(o);
         return o;
     }
 
+    @Override
     public boolean remove(Object o) {
         return doRemove(o);
     }
@@ -177,6 +191,7 @@
         return false;
     }
 
+    @Override
     public synchronized boolean removeAll(Collection<?> c) {
         boolean changed = false;
         for (Object o : c) {
@@ -185,30 +200,35 @@
         return changed;
     }
 
+    @Override
     public synchronized void removeAllElements() {
         set.clear();
         super.removeAllElements();
     }
 
+    @Override
     public boolean removeElement(Object o) {
         return doRemove(o);
     }
 
+    @Override
     public synchronized void removeElementAt(int index) {
         remove(get(index));
     }
 
+    @Override
     public synchronized void removeRange(final int fromIndex, int toIndex) {
         while (toIndex > fromIndex) {
             remove(--toIndex);
         }
     }
 
+    @Override
     public synchronized boolean retainAll(Collection<?> c) {
         if (!(c instanceof Set)) {
-            c = new HashSet<Object>(c);
+            c = new HashSet<>(c);
         }
-        LinkedList<E> l = new LinkedList<E>();
+        LinkedList<E> l = new LinkedList<>();
         for (E o : this) {
             if (!c.contains(o)) {
                 l.addLast(o);
@@ -221,6 +241,7 @@
         return false;
     }
 
+    @Override
     public synchronized E set(int index, E o) {
         E orig = get(index);
         if (set.add(o)) {
@@ -235,6 +256,7 @@
         return orig;
     }
 
+    @Override
     public void setElementAt(E o, int index) {
         set(index, o);
     }
diff --git a/src/main/org/apache/tools/ant/util/Watchdog.java b/src/main/org/apache/tools/ant/util/Watchdog.java
index 318b526..67ebce6 100644
--- a/src/main/org/apache/tools/ant/util/Watchdog.java
+++ b/src/main/org/apache/tools/ant/util/Watchdog.java
@@ -18,8 +18,9 @@
 
 package org.apache.tools.ant.util;
 
-import java.util.Enumeration;
-import java.util.Vector;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 /**
  * Generalization of <code>ExecuteWatchdog</code>
@@ -31,19 +32,22 @@
  */
 public class Watchdog implements Runnable {
 
-    private Vector observers = new Vector(1);
-    private long timeout = -1;
-    /**
-     * marked as volatile to stop the compiler caching values or (in java1.5+,
-     * reordering access)
-     */
-    private volatile boolean stopped = false;
     /**
      * Error string.
      * {@value}
      */
     public static final String ERROR_INVALID_TIMEOUT = "timeout less than 1.";
 
+    private List<TimeoutObserver> observers =
+        Collections.synchronizedList(new ArrayList<>(1));
+    private long timeout = -1;
+
+    /**
+     * marked as volatile to stop the compiler caching values or (in java1.5+,
+     * reordering access)
+     */
+    private volatile boolean stopped = false;
+
     /**
      * Constructor for Watchdog.
      * @param timeout the timeout to use in milliseconds (must be &gt;= 1).
@@ -60,8 +64,7 @@
      * @param to the timeout observer to add.
      */
     public void addTimeoutObserver(TimeoutObserver to) {
-        //no need to synchronize, as Vector is always synchronized
-        observers.addElement(to);
+        observers.add(to);
     }
 
     /**
@@ -69,8 +72,7 @@
      * @param to the timeout observer to remove.
      */
     public void removeTimeoutObserver(TimeoutObserver to) {
-        //no need to synchronize, as Vector is always synchronized
-        observers.removeElement(to);
+        observers.remove(to);
     }
 
     /**
@@ -78,10 +80,7 @@
      * This happens in the watchdog thread.
      */
     protected final void fireTimeoutOccured() {
-        Enumeration e = observers.elements();
-        while (e.hasMoreElements()) {
-            ((TimeoutObserver) e.nextElement()).timeoutOccured(this);
-        }
+        observers.forEach(o -> o.timeoutOccured(this));
     }
 
     /**
@@ -108,6 +107,7 @@
      * if the stop flag has not been set when the wait has returned or
      * has been interrupted, the watch dog listeners are informed.
      */
+    @Override
     public synchronized void run() {
         long now = System.currentTimeMillis();
         final long until = now + timeout;
diff --git a/src/main/org/apache/tools/ant/util/WeakishReference.java b/src/main/org/apache/tools/ant/util/WeakishReference.java
index 9568a28..d7c15b0 100644
--- a/src/main/org/apache/tools/ant/util/WeakishReference.java
+++ b/src/main/org/apache/tools/ant/util/WeakishReference.java
@@ -34,6 +34,7 @@
  * @deprecated deprecated 1.7; will be removed in Ant1.8
  *             Just use {@link java.lang.ref.WeakReference} directly.
  */
+@Deprecated
 public class WeakishReference  {
 
 
diff --git a/src/main/org/apache/tools/ant/util/XMLFragment.java b/src/main/org/apache/tools/ant/util/XMLFragment.java
index 36a6158..3fe5ddd 100644
--- a/src/main/org/apache/tools/ant/util/XMLFragment.java
+++ b/src/main/org/apache/tools/ant/util/XMLFragment.java
@@ -74,9 +74,10 @@
      * @param qName the qualified name of the nested element
      * @return an object that the element is applied to
      */
+    @Override
     public Object createDynamicElement(String uri, String name, String qName) {
-        Element e = null;
-        if (uri.equals("")) {
+        Element e;
+        if ("".equals(uri)) {
             e = doc.createElement(name);
         } else {
             e = doc.createElementNS(uri, qName);
@@ -93,7 +94,7 @@
     private void addText(Node n, String s) {
         s = getProject().replaceProperties(s);
         //only text nodes that are non null after property expansion are added
-        if (s != null && !s.trim().equals("")) {
+        if (s != null && !s.trim().isEmpty()) {
             Text t = doc.createTextNode(s.trim());
             n.appendChild(t);
         }
@@ -124,9 +125,10 @@
          * @param qName the qualified name of the attribute
          * @param value the value of the attribute
          */
+        @Override
         public void setDynamicAttribute(
             String uri, String name, String qName, String value) {
-            if (uri.equals("")) {
+            if ("".equals(uri)) {
                 e.setAttribute(name, value);
             } else {
                 e.setAttributeNS(uri, qName, value);
@@ -140,9 +142,10 @@
          * @param qName the qualified name of the nested element
          * @return an object that the element is applied to
          */
+        @Override
         public Object createDynamicElement(String uri, String name, String qName) {
             Element e2 = null;
-            if (uri.equals("")) {
+            if ("".equals(uri)) {
                 e2 = doc.createElement(name);
             } else {
                 e2 = doc.createElementNS(uri, qName);
diff --git a/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java b/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java
index b5ef999..d2f0323 100644
--- a/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java
+++ b/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java
@@ -42,7 +42,7 @@
     private Path classPath = new Path(null);
 
     /** The list of root classes */
-    private final Vector<String> rootClasses = new VectorSet<String>();
+    private final Vector<String> rootClasses = new VectorSet<>();
 
     /** true if dependencies have been determined */
     private boolean determined = false;
@@ -68,6 +68,7 @@
      * @param closure true if dependencies should be traversed to determine
      *      indirect dependencies.
      */
+    @Override
     public void setClosure(boolean closure) {
         this.closure = closure;
     }
@@ -79,10 +80,11 @@
      *
      * @return an enumeration of File instances.
      */
+    @Override
     public Enumeration<File> getFileDependencies() {
         if (!supportsFileDependencies()) {
-            throw new BuildException("File dependencies are not supported "
-                + "by this analyzer");
+            throw new BuildException(
+                "File dependencies are not supported by this analyzer");
         }
         if (!determined) {
             determineDependencies(fileDependencies, classDependencies);
@@ -97,6 +99,7 @@
      * @return an enumeration of Strings, each being the name of a Java
      *      class in dot notation.
      */
+    @Override
     public Enumeration<String> getClassDependencies() {
         if (!determined) {
             determineDependencies(fileDependencies, classDependencies);
@@ -112,6 +115,7 @@
      *         class or null if the class could not be found.
      * @exception IOException if the files in the classpath cannot be read.
      */
+    @Override
     public File getClassContainer(String classname) throws IOException {
         String classLocation = classname.replace('.', '/') + ".class";
         // we look through the classpath elements. If the element is a dir
@@ -127,6 +131,7 @@
      *         source or null if the source for the class could not be found.
      * @exception IOException if the files in the sourcepath cannot be read.
      */
+    @Override
     public File getSourceContainer(String classname) throws IOException {
         String sourceLocation = classname.replace('.', '/') + ".java";
 
@@ -144,6 +149,7 @@
      * @param sourcePath The Path instance specifying the source path
      *      elements.
      */
+    @Override
     public void addSourcePath(Path sourcePath) {
         if (sourcePath == null) {
             return;
@@ -160,6 +166,7 @@
      *
      * @param classPath the Path instance specifying the classpath elements
      */
+    @Override
     public void addClassPath(Path classPath) {
         if (classPath == null) {
             return;
@@ -176,6 +183,7 @@
      *
      * @param className the name of the class in Java dot notation.
      */
+    @Override
     public void addRootClass(String className) {
         if (className == null) {
             return;
@@ -192,6 +200,7 @@
      * @param name the name of the aspect being configured
      * @param info the configuration info.
      */
+    @Override
     public void config(String name, Object info) {
         // do nothing by default
     }
@@ -200,11 +209,12 @@
      * Reset the dependency list. This will reset the determined
      * dependencies and the also list of root classes.
      */
+    @Override
     public void reset() {
         rootClasses.removeAllElements();
         determined = false;
-        fileDependencies = new Vector<File>();
-        classDependencies = new Vector<String>();
+        fileDependencies = new Vector<>();
+        classDependencies = new Vector<>();
     }
 
     /**
@@ -268,16 +278,10 @@
                 }
             } else {
                 // must be a zip of some sort
-                ZipFile zipFile = null;
-                try {
-                    zipFile = new ZipFile(element);
+                try (ZipFile zipFile = new ZipFile(element)) {
                     if (zipFile.getEntry(resourceLocation) != null) {
                         return element;
                     }
-                } finally {
-                    if (zipFile != null) {
-                        zipFile.close();
-                    }
                 }
             }
         }
diff --git a/src/main/org/apache/tools/ant/util/depend/bcel/AncestorAnalyzer.java b/src/main/org/apache/tools/ant/util/depend/bcel/AncestorAnalyzer.java
index 613bc77..fa2e9ee 100644
--- a/src/main/org/apache/tools/ant/util/depend/bcel/AncestorAnalyzer.java
+++ b/src/main/org/apache/tools/ant/util/depend/bcel/AncestorAnalyzer.java
@@ -19,8 +19,10 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.Vector;
+
 import org.apache.bcel.classfile.ClassParser;
 import org.apache.bcel.classfile.JavaClass;
 import org.apache.tools.ant.BuildException;
@@ -61,33 +63,33 @@
      * @param classes a vector to be populated with the names of the
      *      dependency classes.
      */
+    @Override
     protected void determineDependencies(Vector<File> files, Vector<String> classes) {
         // we get the root classes and build up a set of
         // classes upon which they depend
-        Hashtable<String, String> dependencies = new Hashtable<String, String>();
-        Hashtable<File, File> containers = new Hashtable<File, File>();
-        Hashtable<String, String> toAnalyze = new Hashtable<String, String>();
-        Hashtable<String, String> nextAnalyze = new Hashtable<String, String>();
+        Set<String> dependencies = new HashSet<>();
+        Set<File> containers = new HashSet<>();
+        Set<String> toAnalyze = new HashSet<>();
+        Set<String> nextAnalyze = new HashSet<>();
 
         for (Enumeration<String> e = getRootClasses(); e.hasMoreElements();) {
-            String classname = e.nextElement();
-            toAnalyze.put(classname, classname);
+            toAnalyze.add(e.nextElement());
         }
 
         int count = 0;
         int maxCount = isClosureRequired() ? MAX_LOOPS : 2;
-        while (toAnalyze.size() != 0 && count++ < maxCount) {
+        while (!toAnalyze.isEmpty() && count++ < maxCount) {
             nextAnalyze.clear();
-            for (String classname : toAnalyze.keySet()) {
-                dependencies.put(classname, classname);
+            for (String classname : toAnalyze) {
+                dependencies.add(classname);
                 try {
                     File container = getClassContainer(classname);
                     if (container == null) {
                         continue;
                     }
-                    containers.put(container, container);
+                    containers.add(container);
 
-                    ClassParser parser = null;
+                    ClassParser parser;
                     if (container.getName().endsWith(".class")) {
                         parser = new ClassParser(container.getPath());
                     } else {
@@ -96,18 +98,16 @@
                     }
 
                     JavaClass javaClass = parser.parse();
-                    String[] interfaces = javaClass.getInterfaceNames();
-                    for (int i = 0; i < interfaces.length; ++i) {
-                        String interfaceName = interfaces[i];
-                        if (!dependencies.containsKey(interfaceName)) {
-                            nextAnalyze.put(interfaceName, interfaceName);
+                    for (String interfaceName : javaClass.getInterfaceNames()) {
+                        if (!dependencies.contains(interfaceName)) {
+                            nextAnalyze.add(interfaceName);
                         }
                     }
 
                     if (javaClass.isClass()) {
                         String superClass = javaClass.getSuperclassName();
-                        if (!dependencies.containsKey(superClass)) {
-                            nextAnalyze.put(superClass, superClass);
+                        if (!dependencies.contains(superClass)) {
+                            nextAnalyze.add(superClass);
                         }
                     }
                 } catch (IOException ioe) {
@@ -115,20 +115,16 @@
                 }
             }
 
-            Hashtable<String, String> temp = toAnalyze;
+            Set<String> temp = toAnalyze;
             toAnalyze = nextAnalyze;
             nextAnalyze = temp;
         }
 
-        files.removeAllElements();
-        for (File f : containers.keySet()) {
-            files.add(f);
-        }
+        files.clear();
+        files.addAll(containers);
 
-        classes.removeAllElements();
-        for (String dependency : dependencies.keySet()) {
-            classes.add(dependency);
-        }
+        classes.clear();
+        classes.addAll(dependencies);
     }
 
     /**
@@ -136,6 +132,7 @@
      *
      * @return true if the analyzer provides dependency file information.
      */
+    @Override
     protected boolean supportsFileDependencies() {
         return true;
     }
diff --git a/src/main/org/apache/tools/ant/util/depend/bcel/DependencyVisitor.java b/src/main/org/apache/tools/ant/util/depend/bcel/DependencyVisitor.java
index d31d453..45be038 100644
--- a/src/main/org/apache/tools/ant/util/depend/bcel/DependencyVisitor.java
+++ b/src/main/org/apache/tools/ant/util/depend/bcel/DependencyVisitor.java
@@ -17,8 +17,10 @@
  */
 package org.apache.tools.ant.util.depend.bcel;
 
+import java.util.Collections;
 import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.StringTokenizer;
 
 import org.apache.bcel.classfile.ConstantClass;
@@ -35,7 +37,7 @@
  */
 public class DependencyVisitor extends EmptyVisitor {
     /** The collected dependencies */
-    private final Hashtable<String, String> dependencies = new Hashtable<String, String>();
+    private final Set<String> dependencies = new HashSet<>();
     /**
      * The current class's constant pool - used to determine class names
      * from class references.
@@ -49,7 +51,7 @@
      *      visited classes depend.
      */
     public Enumeration<String> getDependencies() {
-        return dependencies.keys();
+        return Collections.enumeration(dependencies);
     }
 
     /** Clear the current set of collected dependencies. */
@@ -62,6 +64,7 @@
      *
      * @param constantPool the constant pool of the class being visited.
      */
+    @Override
     public void visitConstantPool(final ConstantPool constantPool) {
         this.constantPool = constantPool;
     }
@@ -71,6 +74,7 @@
      *
      * @param constantClass the constantClass entry for the class reference
      */
+    @Override
     public void visitConstantClass(final ConstantClass constantClass) {
         final String classname
              = constantClass.getConstantValue(constantPool).toString();
@@ -84,18 +88,19 @@
      *
      * @param obj the name and type reference being visited.
      */
+    @Override
     public void visitConstantNameAndType(final ConstantNameAndType obj) {
         final String name = obj.getName(constantPool);
-        if (obj.getSignature(constantPool).equals("Ljava/lang/Class;")
+        if ("Ljava/lang/Class;".equals(obj.getSignature(constantPool))
                 && name.startsWith("class$")) {
             String classname
                 = name.substring("class$".length()).replace('$', '.');
             // does the class have a package structure
-            final int index = classname.lastIndexOf(".");
+            final int index = classname.lastIndexOf('.');
             if (index > 0) {
                 char start;
                 // check if the package structure is more than 1 level deep
-                final int index2 = classname.lastIndexOf(".", index - 1);
+                final int index2 = classname.lastIndexOf('.', index - 1);
                 if (index2 != -1) {
                     // class name has more than 1 package level 'com.company.Class'
                     start = classname.charAt(index2 + 1);
@@ -128,6 +133,7 @@
      *
      * @param field the field being visited
      */
+    @Override
     public void visitField(final Field field) {
         addClasses(field.getSignature());
     }
@@ -137,6 +143,7 @@
      *
      * @param javaClass the class being visited.
      */
+    @Override
     public void visitJavaClass(final JavaClass javaClass) {
         addClass(javaClass.getClassName());
     }
@@ -146,9 +153,10 @@
      *
      * @param method the method being visited.
      */
+    @Override
     public void visitMethod(final Method method) {
         final String signature = method.getSignature();
-        final int pos = signature.indexOf(")");
+        final int pos = signature.indexOf(')');
         addClasses(signature.substring(1, pos));
         addClasses(signature.substring(pos + 1));
     }
@@ -159,7 +167,7 @@
      * @param classname the class to be added to the list of dependencies.
      */
     void addClass(final String classname) {
-        dependencies.put(classname, classname);
+        dependencies.add(classname);
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/util/depend/bcel/FullAnalyzer.java b/src/main/org/apache/tools/ant/util/depend/bcel/FullAnalyzer.java
index 3bd6c75..0c6af25 100644
--- a/src/main/org/apache/tools/ant/util/depend/bcel/FullAnalyzer.java
+++ b/src/main/org/apache/tools/ant/util/depend/bcel/FullAnalyzer.java
@@ -18,9 +18,12 @@
 package org.apache.tools.ant.util.depend.bcel;
 import java.io.File;
 import java.io.IOException;
+import java.util.Collections;
 import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.Vector;
+
 import org.apache.bcel.classfile.ClassParser;
 import org.apache.bcel.classfile.DescendingVisitor;
 import org.apache.bcel.classfile.JavaClass;
@@ -60,31 +63,28 @@
      * @param classes a vector to be populated with the names of the
      *      dependency classes.
      */
+    @Override
     protected void determineDependencies(Vector<File> files, Vector<String> classes) {
         // we get the root classes and build up a set of
         // classes upon which they depend
-        Hashtable<String, String> dependencies = new Hashtable<String, String>();
-        Hashtable<File, File> containers = new Hashtable<File, File>();
-        Hashtable<String, String> toAnalyze = new Hashtable<String, String>();
-        for (Enumeration<String> e = getRootClasses(); e.hasMoreElements();) {
-            String classname = e.nextElement();
-            toAnalyze.put(classname, classname);
-        }
+        Set<String> dependencies = new HashSet<>();
+        Set<File> containers = new HashSet<>();
+        Set<String> toAnalyze = new HashSet<>(Collections.list(getRootClasses()));
 
         int count = 0;
         int maxCount = isClosureRequired() ? MAX_LOOPS : 2;
-        while (toAnalyze.size() != 0 && count++ < maxCount) {
+        while (!toAnalyze.isEmpty() && count++ < maxCount) {
             DependencyVisitor dependencyVisitor = new DependencyVisitor();
-            for (String classname : toAnalyze.keySet()) {
-                dependencies.put(classname, classname);
+            for (String classname : toAnalyze) {
+                dependencies.add(classname);
                 try {
                     File container = getClassContainer(classname);
                     if (container == null) {
                         continue;
                     }
-                    containers.put(container, container);
+                    containers.add(container);
 
-                    ClassParser parser = null;
+                    ClassParser parser;
                     if (container.getName().endsWith(".class")) {
                         parser = new ClassParser(container.getPath());
                     } else {
@@ -107,21 +107,17 @@
             Enumeration<String> depsEnum = dependencyVisitor.getDependencies();
             while (depsEnum.hasMoreElements()) {
                 String className = depsEnum.nextElement();
-                if (!dependencies.containsKey(className)) {
-                    toAnalyze.put(className, className);
+                if (!dependencies.contains(className)) {
+                    toAnalyze.add(className);
                 }
             }
         }
 
-        files.removeAllElements();
-        for (File f : containers.keySet()) {
-            files.add(f);
-        }
+        files.clear();
+        files.addAll(containers);
 
-        classes.removeAllElements();
-        for (String dependency : dependencies.keySet()) {
-            classes.add(dependency);
-        }
+        classes.clear();
+        classes.addAll(dependencies);
     }
 
     /**
@@ -129,6 +125,7 @@
      *
      * @return true if the analyzer provides dependency file information.
      */
+    @Override
     protected boolean supportsFileDependencies() {
         return true;
     }
diff --git a/src/main/org/apache/tools/ant/util/facade/FacadeTaskHelper.java b/src/main/org/apache/tools/ant/util/facade/FacadeTaskHelper.java
index 4fb4341..dd05c4b 100644
--- a/src/main/org/apache/tools/ant/util/facade/FacadeTaskHelper.java
+++ b/src/main/org/apache/tools/ant/util/facade/FacadeTaskHelper.java
@@ -20,6 +20,8 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
+import java.util.stream.Stream;
 
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.types.Path;
@@ -37,7 +39,7 @@
     /**
      * Command line arguments.
      */
-    private List<ImplementationSpecificArgument> args = new ArrayList<ImplementationSpecificArgument>();
+    private List<ImplementationSpecificArgument> args = new ArrayList<>();
 
     /**
      * The explicitly chosen implementation.
@@ -126,17 +128,10 @@
      * @return an array of command line arguments.
      */
     public String[] getArgs() {
-        List<String> tmp = new ArrayList<String>(args.size());
-        for (ImplementationSpecificArgument arg : args) {
-            String[] curr = arg.getParts(getImplementation());
-            if (curr != null) {
-                for (int i = 0; i < curr.length; i++) {
-                    tmp.add(curr[i]);
-                }
-            }
-        }
-        String[] res = new String[tmp.size()];
-        return (String[]) tmp.toArray(res);
+        String implementation = getImplementation();
+        return args.stream().map(arg -> arg.getParts(implementation))
+            .filter(Objects::nonNull).flatMap(Stream::of)
+            .toArray(String[]::new);
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/util/facade/ImplementationSpecificArgument.java b/src/main/org/apache/tools/ant/util/facade/ImplementationSpecificArgument.java
index ba7f14a..4af7f34 100644
--- a/src/main/org/apache/tools/ant/util/facade/ImplementationSpecificArgument.java
+++ b/src/main/org/apache/tools/ant/util/facade/ImplementationSpecificArgument.java
@@ -30,11 +30,6 @@
 public class ImplementationSpecificArgument extends Commandline.Argument {
     private String impl;
 
-    /** Constructor for ImplementationSpecificArgument. */
-    public ImplementationSpecificArgument() {
-        super();
-    }
-
     /**
      * Set the implementation this argument is for.
      * @param impl the implementation this command line argument is for.
@@ -54,8 +49,7 @@
     public final String[] getParts(String chosenImpl) {
         if (impl == null || impl.equals(chosenImpl)) {
             return super.getParts();
-        } else {
-            return new String[0];
         }
+        return new String[0];
     }
 }
diff --git a/src/main/org/apache/tools/ant/util/java15/ProxyDiagnostics.java b/src/main/org/apache/tools/ant/util/java15/ProxyDiagnostics.java
index e7412d6..97022ff 100644
--- a/src/main/org/apache/tools/ant/util/java15/ProxyDiagnostics.java
+++ b/src/main/org/apache/tools/ant/util/java15/ProxyDiagnostics.java
@@ -25,8 +25,6 @@
 import java.net.SocketAddress;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.util.Iterator;
-import java.util.List;
 
 import org.apache.tools.ant.BuildException;
 
@@ -40,8 +38,6 @@
  */
 public class ProxyDiagnostics {
 
-    private String destination;
-
     private URI destURI;
 
     /** {@value} */
@@ -53,7 +49,6 @@
      * @throws BuildException if the URI is malformed.
      */
     public ProxyDiagnostics(String destination) {
-        this.destination = destination;
         try {
             this.destURI = new URI(destination);
         } catch (URISyntaxException e) {
@@ -73,35 +68,33 @@
      * Get the diagnostics for proxy information.
      * @return the information.
      */
+    @Override
     public String toString() {
         ProxySelector selector = ProxySelector.getDefault();
-        List list = selector.select(destURI);
-        StringBuffer result = new StringBuffer();
-        Iterator proxies = list.listIterator();
-        while (proxies.hasNext()) {
-            Proxy proxy = (Proxy) proxies.next();
+        StringBuilder result = new StringBuilder();
+        for (Proxy proxy : selector.select(destURI)) {
             SocketAddress address = proxy.address();
             if (address == null) {
                 result.append("Direct connection\n");
-            } else {
-                result.append(proxy.toString());
-                if (address instanceof InetSocketAddress) {
-                    InetSocketAddress ina = (InetSocketAddress) address;
-                    result.append(' ');
-                    result.append(ina.getHostName());
-                    result.append(':');
-                    result.append(ina.getPort());
-                    if (ina.isUnresolved()) {
-                        result.append(" [unresolved]");
-                    } else {
-                        InetAddress addr = ina.getAddress();
-                        result.append(" [");
-                        result.append(addr.getHostAddress());
-                        result.append(']');
-                    }
-                }
-                result.append('\n');
+                continue;
             }
+            result.append(proxy);
+            if (address instanceof InetSocketAddress) {
+                InetSocketAddress ina = (InetSocketAddress) address;
+                result.append(' ');
+                result.append(ina.getHostName());
+                result.append(':');
+                result.append(ina.getPort());
+                if (ina.isUnresolved()) {
+                    result.append(" [unresolved]");
+                } else {
+                    InetAddress addr = ina.getAddress();
+                    result.append(" [");
+                    result.append(addr.getHostAddress());
+                    result.append(']');
+                }
+            }
+            result.append('\n');
         }
         return result.toString();
     }
diff --git a/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java b/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
index 7a5cfa4..5a58998 100644
--- a/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
+++ b/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
@@ -18,10 +18,21 @@
 
 package org.apache.tools.ant.util.optional;
 
-import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.BiConsumer;
+import java.util.stream.Collectors;
+
+import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.SimpleBindings;
 
 import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.util.ReflectWrapper;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
 import org.apache.tools.ant.util.ScriptRunnerBase;
 
 /**
@@ -29,19 +40,22 @@
  * @since Ant 1.7.0
  */
 public class JavaxScriptRunner extends ScriptRunnerBase {
-    private ReflectWrapper engine;
+    private ScriptEngine keptEngine;
+    private CompiledScript compiledScript;
 
     /**
      * Get the name of the manager prefix.
      * @return "javax"
      */
+    @Override
     public String getManagerName() {
         return "javax";
     }
 
     /** {@inheritDoc}. */
+    @Override
     public boolean supportsLanguage() {
-        if (engine != null) {
+        if (keptEngine != null) {
             return true;
         }
         checkLanguage();
@@ -63,6 +77,7 @@
      *
      * @exception BuildException if something goes wrong executing the script.
      */
+    @Override
     public void executeScript(String execName) throws BuildException {
         evaluateScript(execName);
     }
@@ -79,28 +94,61 @@
         checkLanguage();
         ClassLoader origLoader = replaceContextLoader();
         try {
-            ReflectWrapper engine = createEngine();
+            if (getCompiled()) {
+                final String compiledScriptRefName =
+                    String.format("%s.%s.%d.%d", MagicNames.SCRIPT_CACHE,
+                        getLanguage(), Objects.hashCode(getScript()),
+                        Objects.hashCode(getClass().getClassLoader()));
+
+                if (null == compiledScript) {
+                    compiledScript = getProject().getReference(compiledScriptRefName);
+                }
+                if (null == compiledScript) {
+                    final ScriptEngine engine = createEngine();
+                    if (engine == null) {
+                        throw new BuildException(
+                            "Unable to create javax script engine for %s",
+                            getLanguage());
+                    }
+                    if (Compilable.class.isInstance(engine)) {
+                        getProject().log("compile script " + execName,
+                            Project.MSG_VERBOSE);
+
+                        compiledScript =
+                            ((Compilable) engine).compile(getScript());
+                    } else {
+                        getProject().log(
+                            "script compilation not available for " + execName,
+                            Project.MSG_VERBOSE);
+                        compiledScript = null;
+                    }
+                    getProject().addReference(compiledScriptRefName,
+                        compiledScript);
+                }
+                if (null != compiledScript) {
+                    final Bindings bindings = new SimpleBindings();
+
+                    applyBindings(bindings::put);
+
+                    getProject().log(
+                        "run compiled script " + compiledScriptRefName,
+                        Project.MSG_DEBUG);
+
+                    return compiledScript.eval(bindings);
+                }
+            }
+
+            ScriptEngine engine = createEngine();
             if (engine == null) {
                 throw new BuildException(
                     "Unable to create javax script engine for "
-                    + getLanguage());
+                        + getLanguage());
             }
-            for (Iterator i = getBeans().keySet().iterator(); i.hasNext();) {
-                String key = (String) i.next();
-                Object value = getBeans().get(key);
-                if ("FX".equalsIgnoreCase(getLanguage())) {
-                    engine.invoke(
-                        "put", String.class, key
-                        + ":" + value.getClass().getName(),
-                        Object.class, value);
-                } else {
-                    engine.invoke(
-                        "put", String.class, key,
-                        Object.class, value);
-                }
-            }
-            // execute the script
-            return engine.invoke("eval", String.class, getScript());
+
+            applyBindings(engine::put);
+
+            return engine.eval(getScript());
+
         } catch (BuildException be) {
             //catch and rethrow build exceptions
 
@@ -114,7 +162,7 @@
             Throwable t = be;
             Throwable te = be.getCause();
             if (te != null) {
-                if  (te instanceof BuildException) {
+                if (te instanceof BuildException) {
                     throw (BuildException) te;
                 } else {
                     t = te;
@@ -126,22 +174,29 @@
         }
     }
 
-    private ReflectWrapper createEngine() {
-        if (engine != null) {
-            return engine;
+    private void applyBindings(BiConsumer<String, Object> target) {
+        Map<String, Object> source = getBeans();
+
+        if ("FX".equalsIgnoreCase(getLanguage())) {
+            source = source.entrySet().stream()
+                .collect(Collectors.toMap(
+                    e -> String.format("%s:%s", e.getKey(),
+                        e.getValue().getClass().getName()),
+                    Map.Entry::getValue));
         }
-        ReflectWrapper manager = new ReflectWrapper(
-            getClass().getClassLoader(), "javax.script.ScriptEngineManager");
-        Object e = manager.invoke(
-            "getEngineByName", String.class, getLanguage());
-        if (e == null) {
-            return null;
+        source.forEach(target::accept);
+    }
+
+    private ScriptEngine createEngine() {
+        if (keptEngine != null) {
+            return keptEngine;
         }
-        ReflectWrapper ret = new ReflectWrapper(e);
-        if (getKeepEngine()) {
-            this.engine = ret;
+        ScriptEngine result =
+            new ScriptEngineManager().getEngineByName(getLanguage());
+        if (result != null && getKeepEngine()) {
+            this.keptEngine = result;
         }
-        return ret;
+        return result;
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java b/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java
index e704ab2..f1ccac8 100644
--- a/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java
+++ b/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java
@@ -36,6 +36,7 @@
      * This throws an ExitException(status) exception.
      * @param status the exit status
      */
+    @Override
     public void checkExit(int status) {
         throw new ExitException(status);
     }
@@ -45,6 +46,7 @@
      * This does nothing.
      * @param perm the requested permission.
      */
+    @Override
     public void checkPermission(Permission perm) {
         // no permission here
     }
diff --git a/src/main/org/apache/tools/ant/util/optional/ScriptRunner.java b/src/main/org/apache/tools/ant/util/optional/ScriptRunner.java
index 45c3ede..e9ace11 100644
--- a/src/main/org/apache/tools/ant/util/optional/ScriptRunner.java
+++ b/src/main/org/apache/tools/ant/util/optional/ScriptRunner.java
@@ -17,8 +17,7 @@
  */
 package org.apache.tools.ant.util.optional;
 
-import java.util.Hashtable;
-import java.util.Iterator;
+import java.util.Map;
 
 import org.apache.bsf.BSFEngine;
 import org.apache.bsf.BSFException;
@@ -49,6 +48,7 @@
      * Get the name of the manager prefix.
      * @return "bsf"
      */
+    @Override
     public String getManagerName() {
         return "bsf";
     }
@@ -57,10 +57,11 @@
      * Check if bsf supports the language.
      * @return true if bsf can create an engine for this language.
      */
+    @Override
     public boolean supportsLanguage() {
-        Hashtable table = (Hashtable) ReflectUtil.getField(
-            new BSFManager(), "registeredEngines");
-        String engineClassName = (String) table.get(getLanguage());
+        Map<String, String> table =
+            ReflectUtil.getField(new BSFManager(), "registeredEngines");
+        String engineClassName = table.get(getLanguage());
         if (engineClassName == null) {
             getProject().log(
                 "This is no BSF engine class for language '"
@@ -87,6 +88,7 @@
      * @param execName the name that will be passed to BSF for this script execution.
      * @exception BuildException if something goes wrong executing the script.
      */
+    @Override
     public void executeScript(String execName) throws BuildException {
         checkLanguage();
         ClassLoader origLoader = replaceContextLoader();
@@ -113,6 +115,7 @@
      * @return the result of the evaluation
      * @exception BuildException if something goes wrong executing the script.
      */
+    @Override
     public Object evaluateScript(String execName) throws BuildException {
         checkLanguage();
         ClassLoader origLoader = replaceContextLoader();
@@ -145,8 +148,7 @@
     }
 
     private void declareBeans(BSFManager m) throws BSFException {
-        for (Iterator i = getBeans().keySet().iterator(); i.hasNext();) {
-            String key = (String) i.next();
+        for (String key : getBeans().keySet()) {
             Object value = getBeans().get(key);
             if (value != null) {
                 m.declareBean(key, value, value.getClass());
diff --git a/src/main/org/apache/tools/ant/util/optional/WeakishReference12.java b/src/main/org/apache/tools/ant/util/optional/WeakishReference12.java
index 4cd1278..89f8672 100644
--- a/src/main/org/apache/tools/ant/util/optional/WeakishReference12.java
+++ b/src/main/org/apache/tools/ant/util/optional/WeakishReference12.java
@@ -30,6 +30,7 @@
  * WeakishReference(Object) constructor, and both that and this are thin
  * facades on the underlying no-longer-abstract base class.
  */
+@Deprecated
 public class WeakishReference12 extends WeakishReference.HardReference  {
 
 
diff --git a/src/main/org/apache/tools/ant/util/regexp/JakartaOroMatcher.java b/src/main/org/apache/tools/ant/util/regexp/JakartaOroMatcher.java
index 5c43376..24ca761 100644
--- a/src/main/org/apache/tools/ant/util/regexp/JakartaOroMatcher.java
+++ b/src/main/org/apache/tools/ant/util/regexp/JakartaOroMatcher.java
@@ -40,15 +40,10 @@
     // CheckStyle:VisibilityModifier ON
 
     /**
-     * Constructor for JakartaOroMatcher.
-     */
-    public JakartaOroMatcher() {
-    }
-
-    /**
      * Set the regexp pattern from the String description.
      * @param pattern the pattern to match
      */
+    @Override
     public void setPattern(final String pattern) {
         this.pattern = pattern;
     }
@@ -57,6 +52,7 @@
      * Get a String representation of the regexp pattern
      * @return the pattern
      */
+    @Override
     public String getPattern() {
         return this.pattern;
     }
@@ -71,8 +67,7 @@
         throws BuildException {
         try {
             // compute the compiler options based on the input options first
-            final Pattern p = compiler.compile(pattern, getCompilerOptions(options));
-            return p;
+            return compiler.compile(pattern, getCompilerOptions(options));
         } catch (final Exception e) {
             throw new BuildException(e);
         }
@@ -84,6 +79,7 @@
      * @return true if the pattern matches
      * @throws BuildException on error
      */
+    @Override
     public boolean matches(final String argument) throws BuildException {
         return matches(argument, MATCH_DEFAULT);
     }
@@ -95,10 +91,10 @@
      * @return true if the pattern matches
      * @throws BuildException on error
      */
+    @Override
     public boolean matches(final String input, final int options)
         throws BuildException {
-        final Pattern p = getCompiledPattern(options);
-        return matcher.contains(input, p);
+        return matcher.contains(input, getCompiledPattern(options));
     }
 
     /**
@@ -112,7 +108,8 @@
      * @return the vector of groups
      * @throws BuildException on error
      */
-    public Vector getGroups(final String argument) throws BuildException {
+    @Override
+    public Vector<String> getGroups(final String argument) throws BuildException {
         return getGroups(argument, MATCH_DEFAULT);
     }
 
@@ -127,12 +124,13 @@
      * @return the vector of groups
      * @throws BuildException on error
      */
-    public Vector getGroups(final String input, final int options)
+    @Override
+    public Vector<String> getGroups(final String input, final int options)
         throws BuildException {
         if (!matches(input, options)) {
             return null;
         }
-        final Vector v = new Vector();
+        final Vector<String> v = new Vector<>();
         final MatchResult mr = matcher.getMatch();
         final int cnt = mr.groups();
         for (int i = 0; i < cnt; i++) {
@@ -141,7 +139,7 @@
             if (match == null) {
                 match = "";
             }
-            v.addElement(match);
+            v.add(match);
         }
         return v;
     }
diff --git a/src/main/org/apache/tools/ant/util/regexp/JakartaOroRegexp.java b/src/main/org/apache/tools/ant/util/regexp/JakartaOroRegexp.java
index 32cebeb..f837d86 100644
--- a/src/main/org/apache/tools/ant/util/regexp/JakartaOroRegexp.java
+++ b/src/main/org/apache/tools/ant/util/regexp/JakartaOroRegexp.java
@@ -29,11 +29,6 @@
 
     private static final int DECIMAL = 10;
 
-    /** Constructor for JakartaOroRegexp */
-    public JakartaOroRegexp() {
-        super();
-    }
-
     /**
      * Perform a substitution on the regular expression.
      * @param input The string to substitute on
@@ -45,7 +40,7 @@
     public String substitute(final String input, final String argument, final int options)
         throws BuildException {
         // translate \1 to $1 so that the Perl5Substitution will work
-        final StringBuffer subst = new StringBuffer();
+        final StringBuilder subst = new StringBuilder();
         for (int i = 0; i < argument.length(); i++) {
             char c = argument.charAt(i);
             if (c == '$') {
@@ -56,7 +51,7 @@
                     c = argument.charAt(i);
                     final int value = Character.digit(c, DECIMAL);
                     if (value > -1) {
-                        subst.append("$").append(value);
+                        subst.append('$').append(value);
                     } else {
                         subst.append(c);
                     }
@@ -87,12 +82,8 @@
      * @return the oro substitution options
      */
     protected int getSubsOptions(final int options) {
-        final boolean replaceAll = RegexpUtil.hasFlag(options, REPLACE_ALL);
-        int subsOptions = 1;
-        if (replaceAll) {
-            subsOptions = Util.SUBSTITUTE_ALL;
-        }
-        return subsOptions;
+        return RegexpUtil.hasFlag(options, REPLACE_ALL) ? Util.SUBSTITUTE_ALL
+            : 1;
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java b/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java
index 3e14415..4b02c5b 100644
--- a/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java
+++ b/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java
@@ -35,6 +35,7 @@
      * Set the regexp pattern from the String description.
      * @param pattern the pattern to match
      */
+    @Override
     public void setPattern(String pattern) {
         this.pattern = pattern;
     }
@@ -43,6 +44,7 @@
      * Get a String representation of the regexp pattern
      * @return the pattern
      */
+    @Override
     public String getPattern() {
         return pattern;
     }
@@ -72,6 +74,7 @@
      * @return true if the pattern matches
      * @throws BuildException on error
      */
+    @Override
     public boolean matches(String argument) throws BuildException {
         return matches(argument, MATCH_DEFAULT);
     }
@@ -83,6 +86,7 @@
      * @return true if the pattern matches
      * @throws BuildException on error
      */
+    @Override
     public boolean matches(String input, int options)
         throws BuildException {
         return matches(input, getCompiledPattern(options));
@@ -103,7 +107,8 @@
      * @return the vector of groups
      * @throws BuildException on error
      */
-    public Vector getGroups(String argument) throws BuildException {
+    @Override
+    public Vector<String> getGroups(String argument) throws BuildException {
         return getGroups(argument, MATCH_DEFAULT);
     }
 
@@ -118,13 +123,14 @@
      * @return the vector of groups
      * @throws BuildException on error
      */
-    public Vector getGroups(String input, int options)
+    @Override
+    public Vector<String> getGroups(String input, int options)
         throws BuildException {
         RE reg = getCompiledPattern(options);
         if (!matches(input, reg)) {
             return null;
         }
-        Vector v = new Vector();
+        Vector<String> v = new Vector<>();
         int cnt = reg.getParenCount();
         for (int i = 0; i < cnt; i++) {
             String match = reg.getParen(i);
@@ -132,7 +138,7 @@
             if (match == null) {
                 match = "";
             }
-            v.addElement(match);
+            v.add(match);
         }
         return v;
     }
diff --git a/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpRegexp.java b/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpRegexp.java
index cdb6de9..781ecf4 100644
--- a/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpRegexp.java
+++ b/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpRegexp.java
@@ -29,11 +29,6 @@
 
     private static final int DECIMAL = 10;
 
-    /** Constructor for JakartaRegexpRegexp */
-    public JakartaRegexpRegexp() {
-        super();
-    }
-
     /**
      * Convert ant regexp substitution option to apache regex options.
      *
@@ -56,12 +51,13 @@
      * @return the result of the operation
      * @throws BuildException on error
      */
+    @Override
     public String substitute(String input, String argument, int options)
         throws BuildException {
-        Vector v = getGroups(input, options);
+        Vector<String> v = getGroups(input, options);
 
         // replace \1 with the corresponding group
-        StringBuffer result = new StringBuffer();
+        StringBuilder result = new StringBuilder();
         for (int i = 0; i < argument.length(); i++) {
             char c = argument.charAt(i);
             if (c == '\\') {
@@ -81,10 +77,8 @@
                 result.append(c);
             }
         }
-        argument = result.toString();
-
         RE reg = getCompiledPattern(options);
         int sOptions = getSubsOptions(options);
-        return reg.subst(input, argument, sOptions);
+        return reg.subst(input, result.toString(), sOptions);
     }
 }
diff --git a/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcher.java b/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcher.java
index 8c241d4..ac27b99 100644
--- a/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcher.java
+++ b/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcher.java
@@ -34,14 +34,11 @@
 
     private String pattern;
 
-    /** Constructor for JakartaOroRegexp */
-    public Jdk14RegexpMatcher() {
-    }
-
     /**
      * Set the regexp pattern from the String description.
      * @param pattern the pattern to match
      */
+    @Override
     public void setPattern(String pattern) {
         this.pattern = pattern;
     }
@@ -51,6 +48,7 @@
      * @return the pattern
      * @throws BuildException on error
      */
+    @Override
     public String getPattern() {
         return pattern;
     }
@@ -65,8 +63,7 @@
         throws BuildException {
         int cOptions = getCompilerOptions(options);
         try {
-            Pattern p = Pattern.compile(this.pattern, cOptions);
-            return p;
+            return Pattern.compile(this.pattern, cOptions);
         } catch (PatternSyntaxException e) {
             throw new BuildException(e);
         }
@@ -78,6 +75,7 @@
      * @return true if the pattern matches
      * @throws BuildException on error
      */
+    @Override
     public boolean matches(String argument) throws BuildException {
         return matches(argument, MATCH_DEFAULT);
     }
@@ -89,11 +87,11 @@
      * @return true if the pattern matches
      * @throws BuildException on error
      */
+    @Override
     public boolean matches(String input, int options)
         throws BuildException {
         try {
-            Pattern p = getCompiledPattern(options);
-            return p.matcher(input).find();
+            return getCompiledPattern(options).matcher(input).find();
         } catch (Exception e) {
             throw new BuildException(e);
         }
@@ -110,7 +108,8 @@
      * @return the vector of groups
      * @throws BuildException on error
      */
-    public Vector getGroups(String argument) throws BuildException {
+    @Override
+    public Vector<String> getGroups(String argument) throws BuildException {
         return getGroups(argument, MATCH_DEFAULT);
     }
 
@@ -125,14 +124,15 @@
      * @return the vector of groups
      * @throws BuildException on error
      */
-    public Vector getGroups(String input, int options)
+    @Override
+    public Vector<String> getGroups(String input, int options)
         throws BuildException {
         Pattern p = getCompiledPattern(options);
         Matcher matcher = p.matcher(input);
         if (!matcher.find()) {
             return null;
         }
-        Vector v = new Vector();
+        Vector<String> v = new Vector<>();
         int cnt = matcher.groupCount();
         for (int i = 0; i <= cnt; i++) {
             String match = matcher.group(i);
@@ -140,7 +140,7 @@
             if (match == null) {
                 match = "";
             }
-            v.addElement(match);
+            v.add(match);
         }
         return v;
     }
diff --git a/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexp.java b/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexp.java
index de0054f..55fe893 100644
--- a/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexp.java
+++ b/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexp.java
@@ -29,11 +29,6 @@
 
     private static final int DECIMAL = 10;
 
-    /** Constructor for Jdk14RegexpRegexp */
-    public Jdk14RegexpRegexp() {
-        super();
-    }
-
     /**
      * Convert ant regexp substitution option to jdk1.4 options.
      *
@@ -56,10 +51,11 @@
      * @return the result of the operation
      * @throws BuildException on error
      */
+    @Override
     public String substitute(String input, String argument, int options)
         throws BuildException {
         // translate \1 to $(1) so that the Matcher will work
-        StringBuffer subst = new StringBuffer();
+        StringBuilder subst = new StringBuilder();
         for (int i = 0; i < argument.length(); i++) {
             char c = argument.charAt(i);
             if (c == '$') {
@@ -70,7 +66,7 @@
                     c = argument.charAt(i);
                     int value = Character.digit(c, DECIMAL);
                     if (value > -1) {
-                        subst.append("$").append(value);
+                        subst.append('$').append(value);
                     } else {
                         subst.append(c);
                     }
@@ -82,7 +78,6 @@
                 subst.append(c);
             }
         }
-        argument = subst.toString();
 
         int sOptions = getSubsOptions(options);
         Pattern p = getCompiledPattern(options);
@@ -90,15 +85,12 @@
 
         Matcher m = p.matcher(input);
         if (RegexpUtil.hasFlag(sOptions, REPLACE_ALL)) {
-            sb.append(m.replaceAll(argument));
+            sb.append(m.replaceAll(subst.toString()));
+        } else if (m.find()) {
+            m.appendReplacement(sb, subst.toString());
+            m.appendTail(sb);
         } else {
-            boolean res = m.find();
-            if (res) {
-                m.appendReplacement(sb, argument);
-                m.appendTail(sb);
-            } else {
-                sb.append(input);
-            }
+            sb.append(input);
         }
         return sb.toString();
     }
diff --git a/src/main/org/apache/tools/ant/util/regexp/RegexpFactory.java b/src/main/org/apache/tools/ant/util/regexp/RegexpFactory.java
index 7077a21..8e1ee0a 100644
--- a/src/main/org/apache/tools/ant/util/regexp/RegexpFactory.java
+++ b/src/main/org/apache/tools/ant/util/regexp/RegexpFactory.java
@@ -30,10 +30,6 @@
  */
 public class RegexpFactory extends RegexpMatcherFactory {
 
-    /** Constructor for RegexpFactory */
-    public RegexpFactory() {
-    }
-
     /***
      * Create a new regular expression matcher instance.
      * @return the matcher instance
@@ -51,7 +47,7 @@
      * @throws BuildException on error
      */
     public Regexp newRegexp(Project p) throws BuildException {
-        String systemDefault = null;
+        String systemDefault;
         if (p == null) {
             systemDefault = System.getProperty(MagicNames.REGEXP_IMPL);
         } else {
@@ -78,8 +74,8 @@
      * @see RegexpMatcherFactory#createInstance(String)
      */
     protected Regexp createRegexpInstance(String classname) throws BuildException {
-        return (Regexp) ClasspathUtils.newInstance(classname, RegexpFactory.class.getClassLoader(),
-                Regexp.class);
+        return ClasspathUtils.newInstance(classname,
+            RegexpFactory.class.getClassLoader(), Regexp.class);
     }
 
 }
diff --git a/src/main/org/apache/tools/ant/util/regexp/RegexpMatcher.java b/src/main/org/apache/tools/ant/util/regexp/RegexpMatcher.java
index 7938d8b..0ee4605 100644
--- a/src/main/org/apache/tools/ant/util/regexp/RegexpMatcher.java
+++ b/src/main/org/apache/tools/ant/util/regexp/RegexpMatcher.java
@@ -83,7 +83,7 @@
      * @return the vector of groups
      * @throws BuildException on error
      */
-    Vector getGroups(String argument) throws BuildException;
+    Vector<String> getGroups(String argument) throws BuildException;
 
     /***
      * Does this regular expression match the input, given
@@ -105,6 +105,6 @@
      * @return the vector of groups
      * @throws BuildException on error
      */
-    Vector getGroups(String input, int options) throws BuildException;
+    Vector<String> getGroups(String input, int options) throws BuildException;
 
 }
diff --git a/src/main/org/apache/tools/ant/util/regexp/RegexpMatcherFactory.java b/src/main/org/apache/tools/ant/util/regexp/RegexpMatcherFactory.java
index 4f2082d..b34645c 100644
--- a/src/main/org/apache/tools/ant/util/regexp/RegexpMatcherFactory.java
+++ b/src/main/org/apache/tools/ant/util/regexp/RegexpMatcherFactory.java
@@ -33,10 +33,6 @@
  */
 public class RegexpMatcherFactory {
 
-    /** Constructor for RegexpMatcherFactory. */
-    public RegexpMatcherFactory() {
-    }
-
     /***
      * Create a new regular expression instance.
      * @return the matcher
@@ -54,7 +50,7 @@
      * @throws BuildException on error
      */
     public RegexpMatcher newRegexpMatcher(Project p) throws BuildException {
-        String systemDefault = null;
+        String systemDefault;
         if (p == null) {
             systemDefault = System.getProperty(MagicNames.REGEXP_IMPL);
         } else {
@@ -78,8 +74,8 @@
      * @exception BuildException if an error occurs
      */
     protected RegexpMatcher createInstance(String className) throws BuildException {
-        return (RegexpMatcher) ClasspathUtils.newInstance(className, RegexpMatcherFactory.class
-                .getClassLoader(), RegexpMatcher.class);
+        return ClasspathUtils.newInstance(className,
+            RegexpMatcherFactory.class.getClassLoader(), RegexpMatcher.class);
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/util/regexp/RegexpUtil.java b/src/main/org/apache/tools/ant/util/regexp/RegexpUtil.java
index 18fb95a..dcd00b4 100644
--- a/src/main/org/apache/tools/ant/util/regexp/RegexpUtil.java
+++ b/src/main/org/apache/tools/ant/util/regexp/RegexpUtil.java
@@ -33,7 +33,7 @@
      * @return true if the flag is set
      */
     public static boolean hasFlag(int options, int flag) {
-        return ((options & flag) > 0);
+        return (options & flag) > 0;
     }
 
     /**
@@ -44,7 +44,7 @@
      * @return the options with the flag unset
      */
     public static int removeFlag(int options, int flag) {
-        return (options & (0xFFFFFFFF - flag));
+        return options & (0xFFFFFFFF - flag);
     }
 
     /**
diff --git a/src/main/org/apache/tools/mail/ErrorInQuitException.java b/src/main/org/apache/tools/mail/ErrorInQuitException.java
index 6f78a14..353fdf4 100644
--- a/src/main/org/apache/tools/mail/ErrorInQuitException.java
+++ b/src/main/org/apache/tools/mail/ErrorInQuitException.java
@@ -31,6 +31,8 @@
  */
 public class ErrorInQuitException extends IOException {
 
+    private static final long serialVersionUID = 1L;
+
     /**
      * Initialise from an IOException
      *
diff --git a/src/main/org/apache/tools/mail/MailMessage.java b/src/main/org/apache/tools/mail/MailMessage.java
index b1ca493..7eb0bc1 100644
--- a/src/main/org/apache/tools/mail/MailMessage.java
+++ b/src/main/org/apache/tools/mail/MailMessage.java
@@ -32,8 +32,10 @@
 import java.io.PrintStream;
 import java.net.InetAddress;
 import java.net.Socket;
-import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.Map;
 import java.util.Vector;
+import java.util.stream.Collectors;
 
 /**
  * A class to help send SMTP email.
@@ -113,23 +115,23 @@
     private String from;
 
     /** list of email addresses to reply to */
-    private Vector replyto;
+    private final Vector<String> replyto = new Vector<>();
 
     /** list of email addresses to send to */
-    private Vector to;
+    private final Vector<String> to = new Vector<>();
 
     /** list of email addresses to cc to */
-    private Vector cc;
+    private final Vector<String> cc = new Vector<>();
 
     /** headers to send in the mail */
-    private Vector headersKeys;
-    private Vector headersValues;
+    private final Map<String, String> headers = new LinkedHashMap<>();
 
     private MailPrintStream out;
 
     private SmtpResponseReader in;
 
     private Socket socket;
+
     private static final int OK_READY = 220;
     private static final int OK_HELO = 250;
     private static final int OK_FROM = 250;
@@ -139,46 +141,41 @@
     private static final int OK_DOT = 250;
     private static final int OK_QUIT = 221;
 
-  /**
-   * Constructs a new MailMessage to send an email.
-   * Use localhost as the mail server with port 25.
-   *
-   * @exception IOException if there's any problem contacting the mail server
-   */
-  public MailMessage() throws IOException {
-    this(DEFAULT_HOST, DEFAULT_PORT);
-  }
+    /**
+     * Constructs a new MailMessage to send an email.
+     * Use localhost as the mail server with port 25.
+     *
+     * @exception IOException if there's any problem contacting the mail server
+     */
+    public MailMessage() throws IOException {
+        this(DEFAULT_HOST, DEFAULT_PORT);
+    }
 
-  /**
-   * Constructs a new MailMessage to send an email.
-   * Use the given host as the mail server with port 25.
-   *
-   * @param host the mail server to use
-   * @exception IOException if there's any problem contacting the mail server
-   */
-  public MailMessage(String host) throws IOException {
-    this(host, DEFAULT_PORT);
-  }
+    /**
+     * Constructs a new MailMessage to send an email.
+     * Use the given host as the mail server with port 25.
+     *
+     * @param host the mail server to use
+     * @exception IOException if there's any problem contacting the mail server
+     */
+    public MailMessage(String host) throws IOException {
+        this(host, DEFAULT_PORT);
+    }
 
-  /**
-   * Constructs a new MailMessage to send an email.
-   * Use the given host and port as the mail server.
-   *
-   * @param host the mail server to use
-   * @param port the port to connect to
-   * @exception IOException if there's any problem contacting the mail server
-   */
-  public MailMessage(String host, int port) throws IOException {
-    this.port = port;
-    this.host = host;
-    replyto = new Vector();
-    to = new Vector();
-    cc = new Vector();
-    headersKeys = new Vector();
-    headersValues = new Vector();
-    connect();
-    sendHelo();
-  }
+    /**
+     * Constructs a new MailMessage to send an email.
+     * Use the given host and port as the mail server.
+     *
+     * @param host the mail server to use
+     * @param port the port to connect to
+     * @exception IOException if there's any problem contacting the mail server
+     */
+    public MailMessage(String host, int port) throws IOException {
+        this.port = port;
+        this.host = host;
+        connect();
+        sendHelo();
+    }
 
     /**
      * Set the port to connect to the SMTP host.
@@ -208,231 +205,219 @@
      *
      */
     public void replyto(String rto) {
-      this.replyto.addElement(rto);
+        this.replyto.addElement(rto);
     }
 
-  /**
-   * Sets the to address.  Also sets the "To" header.  This method may be
-   * called multiple times.
-   *
-   * @param to the to address
-   * @exception IOException if there's any problem reported by the mail server
-   */
-  public void to(String to) throws IOException {
-    sendRcpt(to);
-    this.to.addElement(to);
-  }
-
-  /**
-   * Sets the cc address.  Also sets the "Cc" header.  This method may be
-   * called multiple times.
-   *
-   * @param cc the cc address
-   * @exception IOException if there's any problem reported by the mail server
-   */
-  public void cc(String cc) throws IOException {
-    sendRcpt(cc);
-    this.cc.addElement(cc);
-  }
-
-  /**
-   * Sets the bcc address.  Does NOT set any header since it's a *blind* copy.
-   * This method may be called multiple times.
-   *
-   * @param bcc the bcc address
-   * @exception IOException if there's any problem reported by the mail server
-   */
-  public void bcc(String bcc) throws IOException {
-    sendRcpt(bcc);
-    // No need to keep track of Bcc'd addresses
-  }
-
-  /**
-   * Sets the subject of the mail message.  Actually sets the "Subject"
-   * header.
-   * @param subj the subject of the mail message
-   */
-  public void setSubject(String subj) {
-    setHeader("Subject", subj);
-  }
-
-  /**
-   * Sets the named header to the given value.  RFC 822 provides the rules for
-   * what text may constitute a header name and value.
-   * @param name name of the header
-   * @param value contents of the header
-   */
-  public void setHeader(String name, String value) {
-    // Blindly trust the user doesn't set any invalid headers
-    headersKeys.add(name);
-    headersValues.add(value);
-  }
-
-  /**
-   * Returns a PrintStream that can be used to write the body of the message.
-   * A stream is used since email bodies are byte-oriented.  A writer can
-   * be wrapped on top if necessary for internationalization.
-   * This is actually done in Message.java
-   *
-   * @return a printstream containing the data and the headers of the email
-   * @exception IOException if there's any problem reported by the mail server
-   * @see org.apache.tools.ant.taskdefs.email.Message
-   */
-  public PrintStream getPrintStream() throws IOException {
-    setFromHeader();
-    setReplyToHeader();
-    setToHeader();
-    setCcHeader();
-    setHeader("X-Mailer", "org.apache.tools.mail.MailMessage (ant.apache.org)");
-    sendData();
-    flushHeaders();
-    return out;
-  }
-
-
-  // RFC 822 s4.1: "From:" header must be sent
-  // We rely on error checking by the MTA
-  void setFromHeader() {
-    setHeader("From", from);
-  }
-
-  // RFC 822 s4.1: "Reply-To:" header is optional
-  void setReplyToHeader() {
-    if (!replyto.isEmpty()) {
-      setHeader("Reply-To", vectorToList(replyto));
+    /**
+     * Sets the to address.  Also sets the "To" header.  This method may be
+     * called multiple times.
+     *
+     * @param to the to address
+     * @exception IOException if there's any problem reported by the mail server
+     */
+    public void to(String to) throws IOException {
+        sendRcpt(to);
+        this.to.addElement(to);
     }
-  }
 
-  void setToHeader() {
-    if (!to.isEmpty()) {
-      setHeader("To", vectorToList(to));
+    /**
+     * Sets the cc address.  Also sets the "Cc" header.  This method may be
+     * called multiple times.
+     *
+     * @param cc the cc address
+     * @exception IOException if there's any problem reported by the mail server
+     */
+    public void cc(String cc) throws IOException {
+        sendRcpt(cc);
+        this.cc.addElement(cc);
     }
-  }
 
-  void setCcHeader() {
-    if (!cc.isEmpty()) {
-      setHeader("Cc", vectorToList(cc));
+    /**
+     * Sets the bcc address.  Does NOT set any header since it's a *blind* copy.
+     * This method may be called multiple times.
+     *
+     * @param bcc the bcc address
+     * @exception IOException if there's any problem reported by the mail server
+     */
+    public void bcc(String bcc) throws IOException {
+        sendRcpt(bcc);
+        // No need to keep track of Bcc'd addresses
     }
-  }
 
-  String vectorToList(Vector v) {
-    StringBuffer buf = new StringBuffer();
-    Enumeration e = v.elements();
-    while (e.hasMoreElements()) {
-      buf.append(e.nextElement());
-      if (e.hasMoreElements()) {
-        buf.append(", ");
-      }
+    /**
+     * Sets the subject of the mail message.  Actually sets the "Subject"
+     * header.
+     * @param subj the subject of the mail message
+     */
+    public void setSubject(String subj) {
+        setHeader("Subject", subj);
     }
-    return buf.toString();
-  }
 
-  void flushHeaders() throws IOException {
-    // RFC 822 s4.1:
-    //   "Header fields are NOT required to occur in any particular order,
-    //    except that the message body MUST occur AFTER the headers"
-    // (the same section specifies a recommended order, which we ignore)
-   final int size = headersKeys.size();
-   for (int i = 0; i < size; i++) {
-      String name = (String) headersKeys.elementAt(i);
-      String value = (String) headersValues.elementAt(i);
-      out.println(name + ": " + value);
+    /**
+     * Sets the named header to the given value.  RFC 822 provides the rules for
+     * what text may constitute a header name and value.
+     * @param name name of the header
+     * @param value contents of the header
+     */
+    public void setHeader(String name, String value) {
+        // Blindly trust the user doesn't set any invalid headers
+        headers.put(name, value);
     }
-    out.println();
-    out.flush();
-  }
 
-  /**
-   * Sends the message and closes the connection to the server.
-   * The MailMessage object cannot be reused.
-   *
-   * @exception IOException if there's any problem reported by the mail server
-   */
-  public void sendAndClose() throws IOException {
-      try {
-          sendDot();
-          sendQuit();
-      } finally {
-          disconnect();
-      }
-  }
+    /**
+     * Returns a PrintStream that can be used to write the body of the message.
+     * A stream is used since email bodies are byte-oriented.  A writer can
+     * be wrapped on top if necessary for internationalization.
+     * This is actually done in Message.java
+     *
+     * @return a printstream containing the data and the headers of the email
+     * @exception IOException if there's any problem reported by the mail server
+     * @see org.apache.tools.ant.taskdefs.email.Message
+     */
+    public PrintStream getPrintStream() throws IOException {
+        setFromHeader();
+        setReplyToHeader();
+        setToHeader();
+        setCcHeader();
+        setHeader("X-Mailer",
+            "org.apache.tools.mail.MailMessage (ant.apache.org)");
+        sendData();
+        flushHeaders();
+        return out;
+    }
 
-  // Make a limited attempt to extract a sanitized email address
-  // Prefer text in <brackets>, ignore anything in (parentheses)
-  static String sanitizeAddress(String s) {
-    int paramDepth = 0;
-    int start = 0;
-    int end = 0;
-    int len = s.length();
+    // RFC 822 s4.1: "From:" header must be sent
+    // We rely on error checking by the MTA
+    void setFromHeader() {
+        setHeader("From", from);
+    }
 
-    for (int i = 0; i < len; i++) {
-      char c = s.charAt(i);
-      if (c == '(') {
-        paramDepth++;
-        if (start == 0) {
-          end = i;  // support "address (name)"
+    // RFC 822 s4.1: "Reply-To:" header is optional
+    void setReplyToHeader() {
+        if (!replyto.isEmpty()) {
+            setHeader("Reply-To", vectorToList(replyto));
         }
-      } else if (c == ')') {
-        paramDepth--;
+    }
+
+    void setToHeader() {
+        if (!to.isEmpty()) {
+            setHeader("To", vectorToList(to));
+        }
+    }
+
+    void setCcHeader() {
+        if (!cc.isEmpty()) {
+            setHeader("Cc", vectorToList(cc));
+        }
+    }
+
+    String vectorToList(Vector<String> v) {
+        return v.stream().collect(Collectors.joining(", "));
+    }
+
+    void flushHeaders() throws IOException {
+        // RFC 822 s4.1:
+        //   "Header fields are NOT required to occur in any particular order,
+        //    except that the message body MUST occur AFTER the headers"
+        // (the same section specifies a recommended order, which we ignore)
+        headers.forEach((k, v) -> out.printf("%s: %s%n", k, v));
+        out.println();
+        out.flush();
+    }
+
+    /**
+     * Sends the message and closes the connection to the server.
+     * The MailMessage object cannot be reused.
+     *
+     * @exception IOException if there's any problem reported by the mail server
+     */
+    public void sendAndClose() throws IOException {
+        try {
+            sendDot();
+            sendQuit();
+        } finally {
+            disconnect();
+        }
+    }
+
+    // Make a limited attempt to extract a sanitized email address
+    // Prefer text in <brackets>, ignore anything in (parentheses)
+    static String sanitizeAddress(String s) {
+        int paramDepth = 0;
+        int start = 0;
+        int end = 0;
+        int len = s.length();
+
+        for (int i = 0; i < len; i++) {
+            char c = s.charAt(i);
+            if (c == '(') {
+                paramDepth++;
+                if (start == 0) {
+                    end = i; // support "address (name)"
+                }
+            } else if (c == ')') {
+                paramDepth--;
+                if (end == 0) {
+                    start = i + 1; // support "(name) address"
+                }
+            } else if (paramDepth == 0 && c == '<') {
+                start = i + 1;
+            } else if (paramDepth == 0 && c == '>') {
+                end = i;
+            }
+        }
+
         if (end == 0) {
-          start = i + 1;  // support "(name) address"
+            end = len;
         }
-      } else if (paramDepth == 0 && c == '<') {
-        start = i + 1;
-      } else if (paramDepth == 0 && c == '>') {
-        end = i;
-      }
+
+        return s.substring(start, end);
     }
 
-    if (end == 0) {
-      end = len;
+    // * * * * * Raw protocol methods below here * * * * *
+
+    void connect() throws IOException {
+        socket = new Socket(host, port);
+        out = new MailPrintStream(
+            new BufferedOutputStream(socket.getOutputStream()));
+        in = new SmtpResponseReader(socket.getInputStream());
+        getReady();
     }
 
-    return s.substring(start, end);
-  }
-
-  // * * * * * Raw protocol methods below here * * * * *
-
-  void connect() throws IOException {
-    socket = new Socket(host, port);
-    out = new MailPrintStream(
-          new BufferedOutputStream(
-          socket.getOutputStream()));
-    in = new SmtpResponseReader(socket.getInputStream());
-    getReady();
-  }
-
-  void getReady() throws IOException {
-    String response = in.getResponse();
-    int[] ok = {OK_READY};
-    if (!isResponseOK(response, ok)) {
-      throw new IOException(
-        "Didn't get introduction from server: " + response);
+    void getReady() throws IOException {
+        String response = in.getResponse();
+        int[] ok = {OK_READY};
+        if (!isResponseOK(response, ok)) {
+            throw new IOException(
+                "Didn't get introduction from server: " + response);
+        }
     }
-  }
-  void sendHelo() throws IOException {
-    String local = InetAddress.getLocalHost().getHostName();
-    int[] ok = {OK_HELO};
-    send("HELO " + local, ok);
-  }
-  void sendFrom(String from) throws IOException {
-    int[] ok = {OK_FROM};
-    send("MAIL FROM: " + "<" + sanitizeAddress(from) + ">", ok);
-  }
-  void sendRcpt(String rcpt) throws IOException {
-    int[] ok = {OK_RCPT_1, OK_RCPT_2};
-    send("RCPT TO: " + "<" + sanitizeAddress(rcpt) + ">", ok);
-  }
 
-  void sendData() throws IOException {
-    int[] ok = {OK_DATA};
-    send("DATA", ok);
-  }
+    void sendHelo() throws IOException {
+        String local = InetAddress.getLocalHost().getHostName();
+        int[] ok = {OK_HELO};
+        send("HELO " + local, ok);
+    }
 
-  void sendDot() throws IOException {
-    int[] ok = {OK_DOT};
-    send("\r\n.", ok);  // make sure dot is on new line
-  }
+    void sendFrom(String from) throws IOException {
+        int[] ok = {OK_FROM};
+        send("MAIL FROM: " + "<" + sanitizeAddress(from) + ">", ok);
+    }
+
+    void sendRcpt(String rcpt) throws IOException {
+        int[] ok = {OK_RCPT_1, OK_RCPT_2};
+        send("RCPT TO: " + "<" + sanitizeAddress(rcpt) + ">", ok);
+    }
+
+    void sendData() throws IOException {
+        int[] ok = {OK_DATA};
+        send("DATA", ok);
+    }
+
+    void sendDot() throws IOException {
+        int[] ok = {OK_DOT};
+        send("\r\n.", ok); // make sure dot is on new line
+    }
 
     void sendQuit() throws IOException {
         int[] ok = {OK_QUIT};
@@ -444,23 +429,23 @@
     }
 
     void send(String msg, int[] ok) throws IOException {
-        out.rawPrint(msg + "\r\n");  // raw supports <CRLF>.<CRLF>
+        out.rawPrint(msg + "\r\n"); // raw supports <CRLF>.<CRLF>
         String response = in.getResponse();
         if (!isResponseOK(response, ok)) {
-            throw new IOException("Unexpected reply to command: "
-                                  + msg + ": " + response);
+            throw new IOException(
+                "Unexpected reply to command: " + msg + ": " + response);
         }
     }
 
-  boolean isResponseOK(String response, int[] ok) {
-    // Check that the response is one of the valid codes
-    for (int i = 0; i < ok.length; i++) {
-      if (response.startsWith("" + ok[i])) {
-        return true;
-      }
+    boolean isResponseOK(String response, int[] ok) {
+        // Check that the response is one of the valid codes
+        for (int i = 0; i < ok.length; i++) {
+            if (response.startsWith("" + ok[i])) {
+                return true;
+            }
+        }
+        return false;
     }
-    return false;
-  }
 
     void disconnect() throws IOException {
         if (out != null) {
@@ -489,42 +474,43 @@
 */
 class MailPrintStream extends PrintStream {
 
-  private int lastChar;
+    private int lastChar;
 
-  public MailPrintStream(OutputStream out) {
-    super(out, true);  // deprecated, but email is byte-oriented
-  }
-
-  // Mac does \n\r, but that's tough to distinguish from Windows \r\n\r\n.
-  // Don't tackle that problem right now.
-  public void write(int b) {
-    if (b == '\n' && lastChar != '\r') {
-      rawWrite('\r');  // ensure always \r\n
-      rawWrite(b);
-    } else if (b == '.' && lastChar == '\n') {
-      rawWrite('.');  // add extra dot
-      rawWrite(b);
-    } else {
-      rawWrite(b);
+    public MailPrintStream(OutputStream out) {
+        super(out, true); // deprecated, but email is byte-oriented
     }
-    lastChar = b;
-  }
 
-  public void write(byte[] buf, int off, int len) {
-    for (int i = 0; i < len; i++) {
-      write(buf[off + i]);
+    // Mac does \n\r, but that's tough to distinguish from Windows \r\n\r\n.
+    // Don't tackle that problem right now.
+    @Override
+    public void write(int b) {
+        if (b == '\n' && lastChar != '\r') {
+            rawWrite('\r'); // ensure always \r\n
+            rawWrite(b);
+        } else if (b == '.' && lastChar == '\n') {
+            rawWrite('.'); // add extra dot
+            rawWrite(b);
+        } else {
+            rawWrite(b);
+        }
+        lastChar = b;
     }
-  }
 
-  void rawWrite(int b) {
-    super.write(b);
-  }
-
-  void rawPrint(String s) {
-    int len = s.length();
-    for (int i = 0; i < len; i++) {
-      rawWrite(s.charAt(i));
+    @Override
+    public void write(byte[] buf, int off, int len) {
+        for (int i = 0; i < len; i++) {
+            write(buf[off + i]);
+        }
     }
-  }
+
+    void rawWrite(int b) {
+        super.write(b);
+    }
+
+    void rawPrint(String s) {
+        int len = s.length();
+        for (int i = 0; i < len; i++) {
+            rawWrite(s.charAt(i));
+        }
+    }
 }
-
diff --git a/src/main/org/apache/tools/mail/SmtpResponseReader.java b/src/main/org/apache/tools/mail/SmtpResponseReader.java
index 8178a86..69b11b4 100644
--- a/src/main/org/apache/tools/mail/SmtpResponseReader.java
+++ b/src/main/org/apache/tools/mail/SmtpResponseReader.java
@@ -35,7 +35,6 @@
     // CheckStyle:VisibilityModifier OFF - bc
     protected BufferedReader reader = null;
     // CheckStyle:VisibilityModifier ON
-    private StringBuffer result = new StringBuffer();
 
     /**
      * Wrap this input stream.
@@ -54,7 +53,7 @@
      * @throws IOException on error.
      */
     public String getResponse() throws IOException {
-        result.setLength(0);
+        StringBuilder result = new StringBuilder();
         String line = reader.readLine();
         // CheckStyle:MagicNumber OFF
         if (line != null && line.length() >= 3) {
@@ -64,7 +63,7 @@
         // CheckStyle:MagicNumber ON
 
         while (line != null) {
-            append(line);
+            appendTo(result, line);
             if (!hasMoreLines(line)) {
                 break;
             }
@@ -95,11 +94,10 @@
     /**
      * Append the text from this line of the response.
      */
-    private void append(String line) {
+    private static void appendTo(StringBuilder target, String line) {
         // CheckStyle:MagicNumber OFF
         if (line.length() > 4) {
-            result.append(line.substring(4));
-            result.append(" ");
+            target.append(line.substring(4)).append(' ');
         }
         // CheckStyle:MagicNumber ON
     }
diff --git a/src/main/org/apache/tools/zip/ZipFile.java b/src/main/org/apache/tools/zip/ZipFile.java
index a50570e..9a51f5c 100644
--- a/src/main/org/apache/tools/zip/ZipFile.java
+++ b/src/main/org/apache/tools/zip/ZipFile.java
@@ -35,10 +35,10 @@
 import java.util.Comparator;
 import java.util.Enumeration;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 import java.util.zip.Inflater;
 import java.util.zip.InflaterInputStream;
 import java.util.zip.ZipException;
@@ -86,13 +86,13 @@
      * List of entries in the order they appear inside the central
      * directory.
      */
-    private final List<ZipEntry> entries = new LinkedList<ZipEntry>();
+    private final List<ZipEntry> entries = new LinkedList<>();
 
     /**
      * Maps String to list of ZipEntrys, name -> actual entries.
      */
     private final Map<String, LinkedList<ZipEntry>> nameMap =
-        new HashMap<String, LinkedList<ZipEntry>>(HASH_SIZE);
+        new HashMap<>(HASH_SIZE);
 
     private static final class OffsetEntry {
         private long headerOffset = -1;
@@ -241,6 +241,7 @@
      * Closes the archive.
      * @throws IOException if an error occurs closing the archive.
      */
+    @Override
     public void close() throws IOException {
         // this flag is only written here and read in finalize() which
         // can never be run in parallel.
@@ -288,9 +289,8 @@
      * @since Ant 1.9.0
      */
     public Enumeration<ZipEntry> getEntriesInPhysicalOrder() {
-        final ZipEntry[] allEntries = entries.toArray(new ZipEntry[0]);
-        Arrays.sort(allEntries, OFFSET_COMPARATOR);
-        return Collections.enumeration(Arrays.asList(allEntries));
+        return entries.stream().sorted(OFFSET_COMPARATOR).collect(Collectors
+            .collectingAndThen(Collectors.toList(), Collections::enumeration));
     }
 
     /**
@@ -322,7 +322,7 @@
     public Iterable<ZipEntry> getEntries(final String name) {
         final List<ZipEntry> entriesOfThatName = nameMap.get(name);
         return entriesOfThatName != null ? entriesOfThatName
-            : Collections.<ZipEntry>emptyList();
+            : Collections.emptyList();
     }
 
     /**
@@ -335,12 +335,11 @@
      * @since 1.9.2
      */
     public Iterable<ZipEntry> getEntriesInPhysicalOrder(final String name) {
-        ZipEntry[] entriesOfThatName = new ZipEntry[0];
         if (nameMap.containsKey(name)) {
-            entriesOfThatName = nameMap.get(name).toArray(entriesOfThatName);
-            Arrays.sort(entriesOfThatName, OFFSET_COMPARATOR);
+            return nameMap.get(name).stream().sorted(OFFSET_COMPARATOR)
+                .collect(Collectors.toList());
         }
-        return Arrays.asList(entriesOfThatName);
+        return Collections.emptyList();
     }
 
     /**
@@ -405,8 +404,8 @@
     protected void finalize() throws Throwable {
         try {
             if (!closed) {
-                System.err.println("Cleaning up unclosed ZipFile for archive "
-                                   + archiveName);
+                System.err.printf("Cleaning up unclosed %s for archive %s%n",
+                    getClass().getSimpleName(), archiveName);
                 close();
             }
         } finally {
@@ -452,8 +451,7 @@
      */
     private Map<ZipEntry, NameAndComment> populateFromCentralDirectory()
         throws IOException {
-        final HashMap<ZipEntry, NameAndComment> noUTF8Flag =
-            new HashMap<ZipEntry, NameAndComment>();
+        final Map<ZipEntry, NameAndComment> noUTF8Flag = new HashMap<>();
 
         positionAtCentralDirectory();
 
@@ -461,8 +459,8 @@
         long sig = ZipLong.getValue(WORD_BUF);
 
         if (sig != CFH_SIG && startsWithLocalFileHeader()) {
-            throw new IOException("central directory is empty, can't expand"
-                                  + " corrupt archive.");
+            throw new IOException(
+                "central directory is empty, can't expand corrupt archive.");
         }
 
         while (sig == CFH_SIG) {
@@ -744,8 +742,8 @@
         archive.seek(ZipEightByteInteger.getLongValue(DWORD_BUF));
         archive.readFully(WORD_BUF);
         if (!Arrays.equals(WORD_BUF, ZipOutputStream.ZIP64_EOCD_SIG)) {
-            throw new ZipException("archive's ZIP64 end of central "
-                                   + "directory locator is corrupt.");
+            throw new ZipException(
+                "archive's ZIP64 end of central directory locator is corrupt.");
         }
         skipBytes(ZIP64_EOCD_CFD_LOCATOR_OFFSET
                   - WORD /* signature has already been read */);
@@ -858,10 +856,10 @@
     private void resolveLocalFileHeaderData(final Map<ZipEntry, NameAndComment>
                                             entriesWithoutUTF8Flag)
         throws IOException {
-        for (final Iterator<ZipEntry> it = entries.iterator(); it.hasNext();) {
+        for (ZipEntry zipEntry : entries) {
             // entries is filled in populateFromCentralDirectory and
             // never modified
-            final Entry ze = (Entry) it.next();
+            final Entry ze = (Entry) zipEntry;
             final OffsetEntry offsetEntry = ze.getOffsetEntry();
             final long offset = offsetEntry.headerOffset;
             archive.seek(offset + LFH_OFFSET_FOR_FILENAME_LENGTH);
@@ -873,8 +871,8 @@
             while (lenToSkip > 0) {
                 final int skipped = archive.skipBytes(lenToSkip);
                 if (skipped <= 0) {
-                    throw new IOException("failed to skip file name in"
-                                          + " local file header");
+                    throw new IOException(
+                        "failed to skip file name in local file header");
                 }
                 lenToSkip -= skipped;
             }
@@ -893,7 +891,7 @@
             final String name = ze.getName();
             LinkedList<ZipEntry> entriesOfThatName = nameMap.get(name);
             if (entriesOfThatName == null) {
-                entriesOfThatName = new LinkedList<ZipEntry>();
+                entriesOfThatName = new LinkedList<>();
                 nameMap.put(name, entriesOfThatName);
             }
             entriesOfThatName.addLast(ze);
@@ -958,7 +956,7 @@
             if (len > remaining) {
                 len = (int) remaining;
             }
-            int ret = -1;
+            int ret;
             synchronized (archive) {
                 archive.seek(loc);
                 ret = archive.read(b, off, len);
@@ -996,25 +994,22 @@
      *
      * @since Ant 1.9.0
      */
-    private final Comparator<ZipEntry> OFFSET_COMPARATOR =
-        new Comparator<ZipEntry>() {
-        public int compare(final ZipEntry e1, final ZipEntry e2) {
-            if (e1 == e2) {
-                return 0;
-            }
-
-            final Entry ent1 = e1 instanceof Entry ? (Entry) e1 : null;
-            final Entry ent2 = e2 instanceof Entry ? (Entry) e2 : null;
-            if (ent1 == null) {
-                return 1;
-            }
-            if (ent2 == null) {
-                return -1;
-            }
-            final long val = (ent1.getOffsetEntry().headerOffset
-                        - ent2.getOffsetEntry().headerOffset);
-            return val == 0 ? 0 : val < 0 ? -1 : +1;
+    private final Comparator<ZipEntry> OFFSET_COMPARATOR = (e1, e2) -> {
+        if (e1 == e2) {
+            return 0;
         }
+
+        final Entry ent1 = e1 instanceof Entry ? (Entry) e1 : null;
+        final Entry ent2 = e2 instanceof Entry ? (Entry) e2 : null;
+        if (ent1 == null) {
+            return 1;
+        }
+        if (ent2 == null) {
+            return -1;
+        }
+        final long val = (ent1.getOffsetEntry().headerOffset
+                    - ent2.getOffsetEntry().headerOffset);
+        return val == 0 ? 0 : val < 0 ? -1 : +1;
     };
 
     /**
diff --git a/src/main/org/apache/tools/zip/ZipOutputStream.java b/src/main/org/apache/tools/zip/ZipOutputStream.java
index f2117d8..16cff04 100644
--- a/src/main/org/apache/tools/zip/ZipOutputStream.java
+++ b/src/main/org/apache/tools/zip/ZipOutputStream.java
@@ -31,12 +31,12 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
+import java.nio.file.Files;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
@@ -356,7 +356,7 @@
                 }
                 _raf = null;
             }
-            out = new FileOutputStream(file);
+            out = Files.newOutputStream(file.toPath());
         }
         raf = _raf;
     }
diff --git a/src/tests/antunit/antunit-base.xml b/src/tests/antunit/antunit-base.xml
index 4bd4643..30bb0ea 100644
--- a/src/tests/antunit/antunit-base.xml
+++ b/src/tests/antunit/antunit-base.xml
@@ -31,10 +31,6 @@
     <javaversion atleast="10"/>
   </condition>
   <available property="jdk9+" classname="java.lang.module.ModuleDescriptor"/>
-  <available property="jdk1.8+" classname="java.lang.reflect.Executable"/>
-  <available property="jdk1.7+" classname="java.nio.file.FileSystem"/>
-  <available property="jdk1.6+" classname="java.net.CookieStore"/>
-  <available property="jdk1.5+" classname="java.net.Proxy"/>
   <condition property="build.sysclasspath.only">
     <equals arg1="${build.sysclasspath}" arg2="only"/>
   </condition>
diff --git a/src/tests/antunit/core/location/src/task/EchoLocation.java b/src/tests/antunit/core/location/src/task/EchoLocation.java
index a2031e6..ce54c03 100644
--- a/src/tests/antunit/core/location/src/task/EchoLocation.java
+++ b/src/tests/antunit/core/location/src/task/EchoLocation.java
@@ -6,7 +6,7 @@
  * (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
+ *    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,
diff --git a/src/tests/antunit/taskdefs/apt-test.xml b/src/tests/antunit/taskdefs/apt-test.xml
deleted file mode 100644
index 9b24001..0000000
--- a/src/tests/antunit/taskdefs/apt-test.xml
+++ /dev/null
@@ -1,158 +0,0 @@
-<?xml version="1.0"?>
-<!--
-  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 default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
-  <import file="../antunit-base.xml" />
-  <!-- apt tests -->
-
-  <property name="build.dir" location="aptbuild" />
-  <property name="classes.dir" location="${build.dir}/classes" />
-  <property name="classes2.dir" location="${build.dir}/classes2" />
-  <property name="preprocess.dir" location="${build.dir}/source" />
-  <property name="src" location="apt" />
-
-  <property name="AptExample.class" location="${classes.dir}/AptExample.class" />
-
-  <macrodef name="assertCompiled">
-    <attribute name="file" />
-    <sequential >
-      <fail  message="not found: @{file}">
-        <condition>
-          <not>
-            <available file="@{file}" />
-          </not>
-        </condition>
-      </fail>
-    </sequential>
-  </macrodef>
-
-  <macrodef name="assertProcessed">
-    <sequential>
-      <au:assertLogContains text="DistributedAnnotationProcessor-is-go"/>
-      <au:assertLogContains text="[-Abuild.dir="/>
-      <au:assertLogContains text="visiting DistributedAnnotationFactory"/>
-    </sequential>
-  </macrodef>
-
-  <presetdef name="assertAptExampleCompiled">
-    <assertCompiled file="${AptExample.class}"/>
-  </presetdef>
-
-  <target name="tearDown" depends="antunit-base.tearDown">
-    <delete dir="${build.dir}"/>
-  </target>
-
-  <target name="setUp">
-    <mkdir dir="${classes.dir}"/>
-    <mkdir dir="${classes2.dir}"/>
-    <mkdir dir="${preprocess.dir}"/>
-  </target>
-
-  <target name="testApt" depends="setUp" unless="jdk1.8+">
-    <apt srcdir="${src}"
-         destdir="${classes.dir}"
-         debug="on"
-         compile="true"
-         preprocessdir="${preprocess.dir}">
-    </apt>
-    <assertAptExampleCompiled />
-  </target>
-
-  <target name="testAptFork" depends="setUp" unless="jdk1.8+">
-    <apt srcdir="${src}"
-         destdir="${classes.dir}"
-         debug="on"
-         compile="true"
-         fork="true"
-         preprocessdir="${preprocess.dir}">
-    </apt>
-    <assertAptExampleCompiled />
-  </target>
-
-  <target name="testAptForkFalse" depends="setUp" unless="jdk1.8+">
-    <apt srcdir="${src}"
-         destdir="${classes.dir}"
-         debug="on"
-         compile="true"
-         fork="false"
-         preprocessdir="${preprocess.dir}">
-    </apt>
-    <assertAptExampleCompiled />
-    <au:assertLogContains text="Apt only runs in its own JVM; fork=false option ignored"/>
-
-  </target>
-
-  <target name="testListAnnotationTypes" depends="setUp" unless="jdk1.8+">
-    <apt srcdir="${src}"
-         destdir="${classes.dir}"
-         debug="on"
-         compile="true"
-         preprocessdir="${preprocess.dir}">
-         <compilerarg value="-XListAnnotationTypes" />
-         <compilerarg value="-Xlint:deprecation" /> 
-    </apt>
-  
-    <assertAptExampleCompiled />
-    <au:assertLogContains text="Set of annotations found:"/>
-    <au:assertLogContains text="Distributed"/>
-  </target>
-
-
-  <!-- use the factory we compiled. To avoid trouble
-    we deliver into a version in a new classpath, otherwise
-    the dependency logic will not run Apt-->
-  <target name="testAptNewFactory" depends="testApt" unless="jdk1.8+">
-    <apt srcdir="${src}"
-         destdir="${classes2.dir}"
-         debug="on"
-         compile="true"
-         factory="DistributedAnnotationFactory"
-         preprocessdir="${preprocess.dir}">
-         <factorypath path="${classes.dir}" />
-         <option name="build.dir" value="${build.dir}" />
-    </apt>
-    <assertAptExampleCompiled />
-    <assertProcessed />
-  </target>
-
-  <target name="testAptNewFactoryFork" depends="testApt" unless="jdk1.8+">
-    <apt srcdir="${src}"
-         destdir="${classes2.dir}"
-         debug="on"
-         compile="true"
-         fork="true"
-         factory="DistributedAnnotationFactory"
-         preprocessdir="${preprocess.dir}">
-         <factorypath path="${classes.dir}" />
-         <option name="build.dir" value="${build.dir}" />
-    </apt>
-    <assertAptExampleCompiled />
-    <assertProcessed />
-  </target>
-
-  <target name="testAptUnderJDK18" if="jdk1.8+">
-    <au:expectfailure expectedMessage="apt does not exist under Java 1.8 and higher">
-      <apt srcdir="${src}"
-           destdir="${classes.dir}"
-           debug="on"
-           compile="true"
-           fork="true"
-           preprocessdir="${preprocess.dir}">
-      </apt>
-    </au:expectfailure>
-  </target>
-</project>
\ No newline at end of file
diff --git a/src/tests/antunit/taskdefs/apt/AptExample.java b/src/tests/antunit/taskdefs/apt/AptExample.java
deleted file mode 100644
index 9d6fcba..0000000
--- a/src/tests/antunit/taskdefs/apt/AptExample.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  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.
- *
- */
-/**
- */
-@Distributed(
-        protocol="CORBA",
-        distribution=Distributed.DistributionTypes.FEDERATED
-        )
-public class AptExample {
-}
diff --git a/src/tests/antunit/taskdefs/apt/Distributed.java b/src/tests/antunit/taskdefs/apt/Distributed.java
deleted file mode 100644
index ebc3467..0000000
--- a/src/tests/antunit/taskdefs/apt/Distributed.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  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.
- *
- */
-import java.lang.annotation.Annotation;
-import java.lang.annotation.Target;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- */
-@Documented
-@Retention(value = RetentionPolicy.RUNTIME)
-@Target(value = ElementType.TYPE)
-public @interface Distributed  {
-
-    public DistributionTypes distribution() default DistributionTypes.LOCAL;
-
-    public String protocol() default "RMI";
-
-    public enum DistributionTypes { SINGLETON, LOCAL, FAULT_TOLERANT, FEDERATED, MOBILE};
-
-
-}
diff --git a/src/tests/antunit/taskdefs/apt/DistributedAnnotationFactory.java b/src/tests/antunit/taskdefs/apt/DistributedAnnotationFactory.java
deleted file mode 100644
index a8fb633..0000000
--- a/src/tests/antunit/taskdefs/apt/DistributedAnnotationFactory.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  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.
- *
- */
-import com.sun.mirror.apt.AnnotationProcessorFactory;
-import com.sun.mirror.apt.AnnotationProcessor;
-import com.sun.mirror.apt.AnnotationProcessorEnvironment;
-
-import java.util.Collection;
-import java.util.Set;
-import java.util.Arrays;
-import java.util.Collections;
-
-
-/**
- * This was the first piece of Java1.5 code in the source tree.
- * @since 20050-03-09T21:29:25Z
- */
-public class DistributedAnnotationFactory implements AnnotationProcessorFactory {
-
-    private static final Collection<String> supportedAnnotations
-            = Collections.unmodifiableCollection(Arrays.asList("*"));
-
-    public Collection<String> supportedOptions() {
-        return Collections.emptySet();
-    }
-
-    public Collection<String> supportedAnnotationTypes() {
-        return supportedAnnotations;
-    }
-
-    public AnnotationProcessor getProcessorFor(
-            Set<com.sun.mirror.declaration.AnnotationTypeDeclaration> annotationTypeDeclarations,
-            AnnotationProcessorEnvironment env) {
-        return new DistributedAnnotationProcessor(env);
-    }
-}
diff --git a/src/tests/antunit/taskdefs/apt/DistributedAnnotationProcessor.java b/src/tests/antunit/taskdefs/apt/DistributedAnnotationProcessor.java
deleted file mode 100644
index f94ff7f..0000000
--- a/src/tests/antunit/taskdefs/apt/DistributedAnnotationProcessor.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  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.
- *
- */
-
-//found in tools.jar, not the JRE runtime.
-import com.sun.mirror.apt.AnnotationProcessor;
-import com.sun.mirror.apt.AnnotationProcessorEnvironment;
-import com.sun.mirror.declaration.TypeDeclaration;
-import com.sun.mirror.declaration.ClassDeclaration;
-import com.sun.mirror.util.SimpleDeclarationVisitor;
-import static com.sun.mirror.util.DeclarationVisitors.*;
-
-import java.util.Map;
-
-/**
- * Annotation processor outputs stuff
- */
-
-public class DistributedAnnotationProcessor implements AnnotationProcessor {
-
-    public AnnotationProcessorEnvironment env;
-
-    public DistributedAnnotationProcessor(AnnotationProcessorEnvironment env) {
-        this.env = env;
-    }
-
-    public void echo(String text) {
-        env.getMessager().printNotice(text);
-    }
-
-    public void process() {
-        echo("DistributedAnnotationProcessor-is-go");
-
-        Map<String, String> options=env.getOptions();
-        for(String key:options.keySet()) {
-            echo("Option ["+key+"] = "+options.get(key));
-        }
-
-        //work time
-        for (TypeDeclaration typeDecl : env.getSpecifiedTypeDeclarations()) {
-            typeDecl.accept(getDeclarationScanner(new ClassVisitor(),
-                    NO_OP));
-        }
-    }
-
-    private class ClassVisitor extends SimpleDeclarationVisitor {
-        public void visitClassDeclaration(ClassDeclaration d) {
-            echo("visiting "+ d.getQualifiedName());
-        }
-    }
-}
diff --git a/src/tests/antunit/taskdefs/copy-test.xml b/src/tests/antunit/taskdefs/copy-test.xml
index 51c6277..9b0148b 100644
--- a/src/tests/antunit/taskdefs/copy-test.xml
+++ b/src/tests/antunit/taskdefs/copy-test.xml
@@ -312,13 +312,10 @@
     <mkdir dir="${input}"/>
     <touch file="${output}/${file}"/>
   </target>
-  <target name="makeFileUnwritable"
-          depends="createTestdir,makeFileUnwritable-Unix,makeFileUnwritable-Windows"/>
-  <target name="makeFileUnwritable-Unix" id="unix">
-    <chmod file="${output}/${file}" perm="444"/>
-  </target>
-  <target name="makeFileUnwritable-Windows" unless="unix">
-    <attrib file="${output}/${file}" readonly="true"/>
+  <target name="makeFileUnwritable" depends="createTestdir">
+    <setpermissions mode="444" nonPosixMode="tryDosOrFail">
+      <file file="${output}/${file}"/>
+    </setpermissions>
   </target>
 
   <target name="testCopyOverReadOnlyFile" depends="makeFileUnwritable">
@@ -453,14 +450,9 @@
     <mkdir dir="${output}"/>
     <touch file="${input}/somefile"/>
     <touch file="${output}/somefile"/>
-    <exec executable="chmod" osfamily="unix">
-      <arg value="-w"/>
-      <arg file="${output}/somefile"/>
-    </exec>
-    <exec executable="attrib" osfamily="dos">
-      <arg value="+r"/>
-      <arg file="${output}/somefile"/>
-    </exec>
+    <setpermissions mode="444" nonPosixMode="tryDosOrFail">
+      <file file="${output}/somefile"/>
+    </setpermissions>
     <au:expectfailure>
       <copy todir="${output}" file="${input}/somefile"
             overwrite="true"/>
diff --git a/src/tests/antunit/taskdefs/jar-test.xml b/src/tests/antunit/taskdefs/jar-test.xml
index c2c8834..63646e2 100644
--- a/src/tests/antunit/taskdefs/jar-test.xml
+++ b/src/tests/antunit/taskdefs/jar-test.xml
@@ -249,4 +249,76 @@
         resource="${output}/META-INF/MANIFEST.MF"/>
   </target>
 
+  <target name="multiReleaseJarPart1" description="http://openjdk.java.net/jeps/238">
+    <!-- Preparation of the 'MultiRelease-Project' -->
+    <property name="java8.src"  value="${input}/src/java"/>
+    <property name="java9.src"  value="${input}/src/java9"/>
+    <property name="java10.src" value="${input}/src/java10"/>
+    <property name="java8.classes"  value="${input}/build/classes"/>
+    <property name="java9.classes"  value="${input}/build/classes9"/>
+    <property name="java10.classes" value="${input}/build/classes10"/>
+    <macrodef name="create">
+      <attribute name="version" />
+      <sequential>
+        <local name="src"/>
+        <local name="classes"/>
+        <property name="src" value="${java@{version}.src}"/>
+        <property name="classes" value="${java@{version}.classes}"/>
+        <mkdir dir="${src}/org/apache/ant/test"/>
+        <echo file="${src}/org/apache/ant/test/MRJarTest.java">
+          package org.apache.ant.test;
+          public class MRJarTest {
+            public static final String VERSION = "Java@{version}";
+          }
+        </echo>
+        <mkdir dir="${classes}"/>
+        <javac srcdir="${src}" destdir="${classes}" debug="on" includeantruntime="false"/>
+      </sequential>
+    </macrodef>
+    <create version="8"/>
+    <create version="9"/>
+    <create version="10"/>
+    
+    <!-- Now create the MultiReleaseJar -->
+    <jar destfile="${antunit.tmpdir}/mrjar.jar">
+      <manifest>
+        <!-- special mf-entry according to the spec -->
+        <attribute name="Multi-Release" value="true"/>
+      </manifest>
+      <!-- directory structure according to the spec ... -->
+      <!-- ... default classes loadable by old (<Java9) versions -->
+      <fileset dir="${java8.classes}"/>
+      <!-- ... per release classes, require Java9+ for loadable via standard ClassLoader -->
+      <zipfileset prefix="META-INF/versions/9/" dir="${java9.classes}"/>
+      <zipfileset prefix="META-INF/versions/10/" dir="${java10.classes}"/>
+    </jar>
+    
+    <!-- Now some tests -->
+    <au:assertNestedResourceExists>
+      <zipentry zipfile="${antunit.tmpdir}/mrjar.jar" name="META-INF/versions/9/org/apache/ant/test/MRJarTest.class"/>
+    </au:assertNestedResourceExists>
+    <au:assertNestedResourceExists>
+      <zipentry zipfile="${antunit.tmpdir}/mrjar.jar" name="META-INF/versions/10/org/apache/ant/test/MRJarTest.class"/>
+    </au:assertNestedResourceExists>
+  </target>
+
+  <target name="testMultiReleaseJar" depends="multiReleaseJarPart1"
+          unless="build.sysclasspath.only"
+          description="most of the tests happen in , this target contains the part that cannot be tested insid Gump">
+    <loadresource property="valueFrom8">
+      <javaconstant name="org.apache.ant.test.MRJarTest.VERSION">
+        <classpath>
+          <pathelement location="${antunit.tmpdir}/mrjar.jar"/>
+        </classpath>
+      </javaconstant>
+    </loadresource>
+    <au:assertTrue>
+      <or>
+    	<equals arg1="Java8" arg2="${valueFrom8}"/>
+        <!-- maybe we are running on an early version of Java9 -->
+    	<equals arg1="Java9" arg2="${valueFrom8}"/>
+      </or>
+    </au:assertTrue>
+  </target>
+
 </project>
diff --git a/src/tests/antunit/taskdefs/javac-test.xml b/src/tests/antunit/taskdefs/javac-test.xml
index 48ed15d..7c1f462 100644
--- a/src/tests/antunit/taskdefs/javac-test.xml
+++ b/src/tests/antunit/taskdefs/javac-test.xml
@@ -224,28 +224,7 @@
       <mkdir dir="${javac-dir}/classes"/>
     </sequential>
     
-    <sequential unless:set="jdk9+">
-      <echo>JDK 1.5+</echo>
-      <testJavac source="1.5"/>
-      <delete dir="${javac-dir}/classes"/>
-      <mkdir dir="${javac-dir}/classes"/>
-    </sequential>
-    
-    <sequential if:set="jdk1.6+">
-      <echo>JDK 1.6+</echo>
-      <testJavac source="1.6"/>
-      <delete dir="${javac-dir}/classes"/>
-      <mkdir dir="${javac-dir}/classes"/>
-    </sequential>
-  		
-    <sequential if:set="jdk1.7+">
-      <echo>JDK 1.7+</echo>
-      <testJavac source="1.7"/>
-      <delete dir="${javac-dir}/classes"/>
-      <mkdir dir="${javac-dir}/classes"/>
-    </sequential>
-    
-    <sequential if:set="jdk1.8+">
+    <sequential unless:set="jdk1.9+">
       <echo>JDK 1.8+</echo>
       <testJavac source="1.8"/>
       <delete dir="${javac-dir}/classes"/>
@@ -274,34 +253,6 @@
     </au:expectfailure>
 
     <sequential unless:set="jdk9+">
-      <echo>JDK 1.4+</echo>
-      <testJavac source="1.4" target="1.4"/>
-      <delete dir="${javac-dir}/classes"/>
-      <mkdir dir="${javac-dir}/classes"/>
-    </sequential>
-
-    <sequential unless:set="jdk9+">
-      <echo>JDK 1.5+</echo>
-      <testJavac source="1.5" target="1.5"/>
-      <delete dir="${javac-dir}/classes"/>
-      <mkdir dir="${javac-dir}/classes"/>
-    </sequential>
-    
-    <sequential if:set="jdk1.6+">
-      <echo>JDK 1.6+</echo>
-      <testJavac source="1.6" target="1.6"/>
-      <delete dir="${javac-dir}/classes"/>
-      <mkdir dir="${javac-dir}/classes"/>
-    </sequential>
-        
-    <sequential if:set="jdk1.7+">
-      <echo>JDK 1.7+</echo>
-      <testJavac source="1.7" target="1.7"/>
-      <delete dir="${javac-dir}/classes"/>
-      <mkdir dir="${javac-dir}/classes"/>
-    </sequential>
-    
-    <sequential if:set="jdk1.8+">
       <echo>JDK 1.8+</echo>
       <testJavac source="1.8" target="1.8"/>
       <delete dir="${javac-dir}/classes"/>
@@ -323,7 +274,7 @@
     </sequential>
   </target>
 
-  <target name="testJavacWithNativeHeaderGeneration" if="jdk1.8+" depends="setup">
+  <target name="testJavacWithNativeHeaderGeneration" depends="setup">
     <mkdir dir="${javac-dir}/src/org/example" />
     <mkdir dir="${javac-dir}/classes"/>
     <mkdir dir="${javac-dir}/headers"/>
diff --git a/src/tests/antunit/taskdefs/move-test.xml b/src/tests/antunit/taskdefs/move-test.xml
index 9acac74..3584f9b 100644
--- a/src/tests/antunit/taskdefs/move-test.xml
+++ b/src/tests/antunit/taskdefs/move-test.xml
@@ -134,13 +134,10 @@
     <mkdir dir="${input}"/>
     <touch file="${output}/${file}"/>
   </target>
-  <target name="makeFileUnwritable"
-          depends="createTestdir,makeFileUnwritable-Unix,makeFileUnwritable-Windows"/>
-  <target name="makeFileUnwritable-Unix" id="unix">
-    <chmod file="${output}/${file}" perm="444"/>
-  </target>
-  <target name="makeFileUnwritable-Windows" unless="unix">
-    <attrib file="${output}/${file}" readonly="true"/>
+  <target name="makeFileUnwritable" depends="createTestdir">
+    <setpermissions mode="444" nonPosixMode="tryDosOrFail">
+      <file file="${output}/${file}"/>
+    </setpermissions>
   </target>
 
   <target name="testMoveOverReadOnlyFile" depends="makeFileUnwritable">
diff --git a/src/tests/antunit/taskdefs/optional/junit/junit-test.xml b/src/tests/antunit/taskdefs/optional/junit/junit-test.xml
index e6aa794..d93b96e 100644
--- a/src/tests/antunit/taskdefs/optional/junit/junit-test.xml
+++ b/src/tests/antunit/taskdefs/optional/junit/junit-test.xml
@@ -317,10 +317,7 @@
   </target>
 
   <target name="testTestMethods">
-    <condition property="source" value="6">
-      <isset property="jdk1.6+"/>
-    </condition>
-    <property name="source" value="5"/>
+    <property name="source" value="8"/>
     <echo file="${input}/T1.java">public class T1 extends
 			junit.framework.TestCase {
 			public void testOK() {}
diff --git a/src/tests/antunit/taskdefs/optional/xz/unxz-test.xml b/src/tests/antunit/taskdefs/optional/xz/unxz-test.xml
new file mode 100644
index 0000000..0cfffb4
--- /dev/null
+++ b/src/tests/antunit/taskdefs/optional/xz/unxz-test.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<!--
+  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 default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+  <import file="../../../antunit-base.xml" />
+
+  <target name="setup">
+    <mkdir dir="${output}"/>
+    <available property="xz.present" classname="org.tukaani.xz.XZOutputStream"/>
+  </target>
+
+  <target name="testWithFileResourceToFile" depends="setup" if="xz.present">
+    <unxz dest="${output}/asf-logo.gif">
+      <file file="../../../../../etc/testcases/taskdefs/expected/asf-logo.gif.xz"/>
+    </unxz>
+    <au:assertFilesMatch expected="../../../../../etc/testcases/asf-logo.gif"
+                         actual="${output}/asf-logo.gif"/>
+  </target>
+
+  <target name="testWithFileResourceToDirectory" depends="setup" if="xz.present">
+    <unxz dest="${output}">
+      <file file="../../../../../etc/testcases/taskdefs/expected/asf-logo.gif.xz"/>
+    </unxz>
+    <au:assertFilesMatch expected="../../../../../etc/testcases/asf-logo.gif"
+                         actual="${output}/asf-logo.gif"/>
+  </target>
+
+  <target name="testWithNonFileResourceToFile" depends="setup" if="xz.present">
+    <unxz dest="${output}/greeting.txt">
+      <url url="http://ant.apache.org/webtest/xz/greeting.txt.xz"/>
+    </unxz>
+    <get src="http://ant.apache.org/webtest/gunzip/greeting.txt"
+         dest="${output}/orig.greeting.txt"/>
+    <au:assertFilesMatch expected="${output}/orig.greeting.txt"
+                         actual="${output}/greeting.txt"/>
+  </target>
+
+  <target name="testWithNonFileResourceToDir" depends="setup" if="xz.present">
+    <unxz dest="${output}">
+      <url url="http://ant.apache.org/webtest/xz/greeting.txt.xz"/>
+    </unxz>
+    <get src="http://ant.apache.org/webtest/gunzip/greeting.txt"
+         dest="${output}/orig.greeting.txt"/>
+    <au:assertFilesMatch expected="${output}/orig.greeting.txt"
+                         actual="${output}/greeting.txt"/>
+  </target>
+
+</project>
+
diff --git a/src/tests/antunit/taskdefs/optional/xz/xz-test.xml b/src/tests/antunit/taskdefs/optional/xz/xz-test.xml
new file mode 100644
index 0000000..3e4b6a8
--- /dev/null
+++ b/src/tests/antunit/taskdefs/optional/xz/xz-test.xml
@@ -0,0 +1,47 @@
+<?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 default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+    <!-- note relies on antunit 1.1 -->
+    <import file="../../../antunit-base.xml" />
+
+    <target name="setUp">
+        <mkdir dir="${output}" />
+        <mkdir dir="${output}/empty" />
+        <touch file="${output}/fileone" />
+        <touch file="${output}/filetwo" />
+        <available property="xz.present" classname="org.tukaani.xz.XZOutputStream"/>
+    </target>
+
+    <target name="testFailNone" if="xz.present">
+        <au:expectfailure expectedmessage="No resource selected, xz needs exactly one resource." message="Should have thrown an exception">
+            <xz destfile="${output}/file.gz">
+                <fileset dir="${output}/empty" />
+            </xz>
+        </au:expectfailure>
+    </target>
+
+    <target name="testFailTwo" if="xz.present">
+        <au:expectfailure expectedmessage="xz cannot handle multiple resources at once. (2 resources were selected.)" message="Should have thrown an exception">
+            <xz destfile="${output}/file.xz">
+                <fileset dir="${output}" />
+            </xz>
+        </au:expectfailure>
+    </target>
+
+</project>
diff --git a/src/tests/antunit/taskdefs/secure-input.xml b/src/tests/antunit/taskdefs/secure-input.xml
index 8311ce9..ae0675e 100644
--- a/src/tests/antunit/taskdefs/secure-input.xml
+++ b/src/tests/antunit/taskdefs/secure-input.xml
@@ -22,7 +22,7 @@
   <target name="setUp">
   </target>
 
-  <target name="test-secure-input" if="jdk1.6+">
+  <target name="test-secure-input">
     <input message="secure-input:>" addproperty="the.password">
       <handler classname="org.apache.tools.ant.input.SecureInputHandler" />
     </input>
diff --git a/src/tests/antunit/taskdefs/setpermissions-test.xml b/src/tests/antunit/taskdefs/setpermissions-test.xml
new file mode 100644
index 0000000..99b90e0
--- /dev/null
+++ b/src/tests/antunit/taskdefs/setpermissions-test.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<!--
+  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 xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+  <import file="../antunit-base.xml" />
+
+  <target name="setUp">
+    <mkdir dir="${input}"/>
+    <property name="file" location="${input}/file"/>
+    <touch file="${file}"/>
+  </target>
+
+  <target name="testRequiresNestedResources" depends="setUp">
+    <au:expectfailure expectedMessage="At least one resource-collection is required">
+      <setpermissions mode="644" />
+    </au:expectfailure>
+  </target>
+
+  <target name="testPermissionsSetViaPermissionsAttribute"
+          depends="setUp">
+    <setpermissions permissions="OWNER_READ,GROUP_READ,OTHERS_READ"
+                    nonPosixMode="tryDosOrFail">
+      <file file="${file}"/>
+    </setpermissions>
+    <au:assertFalse>
+      <isfileselected file="${file}">
+        <writable/>
+      </isfileselected>
+    </au:assertFalse>
+    <au:assertTrue>
+      <isfileselected file="${file}">
+        <readable/>
+      </isfileselected>
+    </au:assertTrue>
+  </target>
+
+  <target name="testPermissionsSetViaModeAttribute"
+          depends="setUp">
+    <setpermissions mode="444" nonPosixMode="tryDosOrFail">
+      <file file="${file}"/>
+    </setpermissions>
+    <au:assertFalse>
+      <isfileselected file="${file}">
+        <writable/>
+      </isfileselected>
+    </au:assertFalse>
+    <au:assertTrue>
+      <isfileselected file="${file}">
+        <readable/>
+      </isfileselected>
+    </au:assertTrue>
+  </target>
+</project>
diff --git a/src/tests/antunit/taskdefs/tar-test.xml b/src/tests/antunit/taskdefs/tar-test.xml
index 1aac9a8..d83b5f9 100644
--- a/src/tests/antunit/taskdefs/tar-test.xml
+++ b/src/tests/antunit/taskdefs/tar-test.xml
@@ -24,6 +24,7 @@
   <target name="setUp">
     <mkdir dir="${input}" />
     <mkdir dir="${output}" />
+    <available property="xz.present" classname="org.tukaani.xz.XZOutputStream"/>
   </target>
 
   <target name="testTarFilesetHandlesFilesetReferences" depends="setUp">
@@ -115,4 +116,47 @@
     <untar dest="${output}" src="${output}/x.tar"/>
     <au:assertFileExists file="${output}/${longfile.file.name}"/>
   </target>
+
+  <target name="testGzipCompression" depends="setUp">
+    <au:assertFileExists file="../../../etc/testcases/asf-logo.gif"/>
+    <tar destfile="${input}/asf-logo.gif.tar.gz" compression="gzip">
+      <file file="../../../etc/testcases/asf-logo.gif"/>
+    </tar>
+    <gunzip dest="${input}/asf-logo.gif.tar">
+      <file file="${input}/asf-logo.gif.tar.gz"/>
+    </gunzip>
+    <untar src="${input}/asf-logo.gif.tar" dest="${output}"/>
+    <au:assertFilesMatch
+        expected="../../../etc/testcases/asf-logo.gif"
+        actual="${output}/asf-logo.gif"/>
+  </target>
+
+  <target name="testBzip2Compression" depends="setUp">
+    <au:assertFileExists file="../../../etc/testcases/asf-logo.gif"/>
+    <tar destfile="${input}/asf-logo.gif.tar.bz2" compression="bzip2">
+      <file file="../../../etc/testcases/asf-logo.gif"/>
+    </tar>
+    <bunzip2 dest="${input}/asf-logo.gif.tar">
+      <file file="${input}/asf-logo.gif.tar.bz2"/>
+    </bunzip2>
+    <untar src="${input}/asf-logo.gif.tar" dest="${output}"/>
+    <au:assertFilesMatch
+        expected="../../../etc/testcases/asf-logo.gif"
+        actual="${output}/asf-logo.gif"/>
+  </target>
+
+  <target name="testXzCompression" depends="setUp" if="xz.present">
+    <au:assertFileExists file="../../../etc/testcases/asf-logo.gif"/>
+    <tar destfile="${input}/asf-logo.gif.tar.xz" compression="xz">
+      <file file="../../../etc/testcases/asf-logo.gif"/>
+    </tar>
+    <unxz dest="${input}/asf-logo.gif.tar">
+      <file file="${input}/asf-logo.gif.tar.xz"/>
+    </unxz>
+    <untar src="${input}/asf-logo.gif.tar" dest="${output}"/>
+    <au:assertFilesMatch
+        expected="../../../etc/testcases/asf-logo.gif"
+        actual="${output}/asf-logo.gif"/>
+  </target>
+
 </project>
diff --git a/src/tests/antunit/taskdefs/taskdef-antlib-test.xml b/src/tests/antunit/taskdefs/taskdef-antlib-test.xml
index 58d01f0..72f21ae 100644
--- a/src/tests/antunit/taskdefs/taskdef-antlib-test.xml
+++ b/src/tests/antunit/taskdefs/taskdef-antlib-test.xml
@@ -18,9 +18,7 @@
 <project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
     <import file="../antunit-base.xml" />
 
-    <!-- Java5 has some trouble with the recursive Antlib lookup -->
-
-    <target name="setUp" if="jdk1.6+">
+    <target name="setUp">
         <mkdir dir="${input}/org/example" />
         <property name="tmpdir" location="../../../../build/ant-unit/taskdef" />
         <mkdir dir="${tmpdir}" />
@@ -46,14 +44,14 @@
         <sleep seconds="1"/>
     </target>
 
-    <target name="testAntlib" depends="setUp" if="jdk1.6+">
+    <target name="testAntlib" depends="setUp">
         <taskdef classpath="${test.jar}" uri="antlib:org.example"
                  loaderref="loader1"/>
         <echoooo xmlns="antlib:org.example" message="exemple" />
         <au:assertLogContains text="exempleexempleexempleexemple" />
     </target>
 
-    <target name="testURI" depends="setUp" if="jdk1.6+">
+    <target name="testURI" depends="setUp">
         <taskdef classpath="${test.jar}" uri="urn:my:exemple"
                  loaderref="loader2"
                  resource="org/example/antlib.xml" />
diff --git a/src/tests/antunit/taskdefs/taskdef-test.xml b/src/tests/antunit/taskdefs/taskdef-test.xml
index 9574508..1da8e9f 100644
--- a/src/tests/antunit/taskdefs/taskdef-test.xml
+++ b/src/tests/antunit/taskdefs/taskdef-test.xml
@@ -41,7 +41,7 @@
     <au:assertLogContains text="Hello"/>
   </target>
 
-  <target name="testDirWithPling" depends="setUp" if="jdk1.6+"
+  <target name="testDirWithPling" depends="setUp"
           description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50007">
     <property name="dir" location="${tmpdir}/pl!ng"/>
     <mkdir dir="${dir}"/>
diff --git a/src/tests/antunit/taskdefs/tstamp-test.xml b/src/tests/antunit/taskdefs/tstamp-test.xml
index c9bebf8..c358262 100644
--- a/src/tests/antunit/taskdefs/tstamp-test.xml
+++ b/src/tests/antunit/taskdefs/tstamp-test.xml
@@ -24,4 +24,21 @@
     <tstamp/>
     <au:assertPropertyEquals name="DSTAMP" value="19700102"/>
   </target>
+
+  <target name="testMagicPropertyIso">
+    <local name="ant.tstamp.now.iso"/>
+    <property name="ant.tstamp.now.iso" value="1972-04-17T08:07:00Z"/>
+    <tstamp/>
+    <au:assertPropertyEquals name="DSTAMP" value="19720417"/>
+  </target>
+
+  <target name="testMagicPropertyBoth">
+    <local name="ant.tstamp.now"/>
+    <local name="ant.tstamp.now.iso"/>
+    <property name="ant.tstamp.now" value="100000"/>
+    <property name="ant.tstamp.now.iso" value="1972-04-17T08:07:22Z"/>
+    <tstamp/>
+    <!-- 'iso' overrides 'simple' -->
+    <au:assertPropertyEquals name="DSTAMP" value="19720417"/>
+  </target>
 </project>
diff --git a/src/tests/antunit/taskdefs/untar-test.xml b/src/tests/antunit/taskdefs/untar-test.xml
new file mode 100644
index 0000000..4c04bfe
--- /dev/null
+++ b/src/tests/antunit/taskdefs/untar-test.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+<!--
+  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="untar-test" default="antunit"
+         xmlns:au="antlib:org.apache.ant.antunit">
+  <import file="../antunit-base.xml" />
+
+  <target name="setUp">
+    <mkdir dir="${input}"/>
+    <mkdir dir="${output}/expected" />
+    <mkdir dir="${output}/actual" />
+    <available property="xz.present" classname="org.tukaani.xz.XZOutputStream"/>
+  </target>
+
+  <target name="testGzipCompression" depends="setUp">
+    <untar src="../../../etc/testcases/taskdefs/expected/asf-logo.gif.tar"
+           dest="${output}/expected"/>
+    <untar src="../../../etc/testcases/taskdefs/expected/asf-logo.gif.tar.gz"
+           compression="gzip"
+           dest="${output}/actual"/>
+    <au:assertFilesMatch expected="${output}/expected/asf-logo.gif"
+                         actual="${output}/actual/asf-logo.gif"/>
+  </target>
+
+  <target name="testBzip2Compression" depends="setUp">
+    <untar src="../../../etc/testcases/taskdefs/expected/asf-logo.gif.tar"
+           dest="${output}/expected"/>
+    <untar src="../../../etc/testcases/taskdefs/expected/asf-logo.gif.tar.bz2"
+           compression="bzip2"
+           dest="${output}/actual"/>
+    <au:assertFilesMatch expected="${output}/expected/asf-logo.gif"
+                         actual="${output}/actual/asf-logo.gif"/>
+  </target>
+
+  <target name="testXZCompression" depends="setUp" if="xz.present">
+    <untar src="../../../etc/testcases/taskdefs/expected/asf-logo.gif.tar"
+           dest="${output}/expected"/>
+    <xz destfile="${input}/asf-logo.gif.tar.xz"
+        src="../../../etc/testcases/taskdefs/expected/asf-logo.gif.tar"/>
+    <untar src="${input}/asf-logo.gif.tar.xz"
+           compression="xz"
+           dest="${output}/actual"/>
+    <au:assertFilesMatch expected="${output}/expected/asf-logo.gif"
+                         actual="${output}/actual/asf-logo.gif"/>
+  </target>
+</project>
diff --git a/src/tests/antunit/taskdefs/xslt-test.xml b/src/tests/antunit/taskdefs/xslt-test.xml
index d6f6d66..b327c7b 100644
--- a/src/tests/antunit/taskdefs/xslt-test.xml
+++ b/src/tests/antunit/taskdefs/xslt-test.xml
@@ -187,18 +187,7 @@
     </xslt>
   </target>
 
-
-  <target name="testTraceJdk14" unless="jdk1.5+" depends="setUp">
-    <xslt in="${legacy.dir}/data.xml"
-          out="${output}/out.xml"
-          style="${legacy.dir}/printParams.xsl">
-      <param name="set" expression="myvalue"/>
-      <trace templates="true"/>
-    </xslt>
-    <au:assertLogContains text="Failed to enable tracing" level="warning"/>
-  </target>
-
-  <target name="testTraceJdk15+" if="jdk1.5+" depends="setUp">
+  <target name="testTrace" depends="setUp">
     <xslt in="${legacy.dir}/data.xml"
           out="${output}/out.xml"
           style="${legacy.dir}/printParams.xsl">
diff --git a/src/tests/antunit/types/optional/xz/xzresource-test.xml b/src/tests/antunit/types/optional/xz/xzresource-test.xml
new file mode 100644
index 0000000..56fe66d
--- /dev/null
+++ b/src/tests/antunit/types/optional/xz/xzresource-test.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+  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 xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+  <import file="../../../antunit-base.xml" />
+
+  <target name="setup">
+    <mkdir dir="${output}"/>
+    <available property="xz.present" classname="org.tukaani.xz.XZOutputStream"/>
+  </target>
+
+  <target name="testDocumentationClaimsOnCopy" if="xz.present">
+    <copy todir="${output}">
+      <xzresource>
+        <file file="../../../../../etc/testcases/taskdefs/expected/asf-logo.gif.xz"/>
+      </xzresource>
+      <mapper type="glob" from="*.xz" to="*"/>
+    </copy>
+    <au:assertFilesMatch expected="../../../../../etc/testcases/asf-logo.gif"
+                         actual="${output}/asf-logo.gif"/>
+  </target>
+</project>
diff --git a/src/tests/antunit/types/resources/selectors/readwrite-test.xml b/src/tests/antunit/types/resources/selectors/readwrite-test.xml
index 6a0301b..4247875 100644
--- a/src/tests/antunit/types/resources/selectors/readwrite-test.xml
+++ b/src/tests/antunit/types/resources/selectors/readwrite-test.xml
@@ -70,13 +70,10 @@
     </au:assertTrue>
   </target>
 
-  <target name="makeFileUnwritable"
-          depends="createTestdir,makeFileUnwritable-Unix,makeFileUnwritable-Windows"/>
-  <target name="makeFileUnwritable-Unix" id="unix">
-    <chmod file="${output}/${file}" perm="444"/>
-  </target>
-  <target name="makeFileUnwritable-Windows" unless="unix">
-    <attrib file="${output}/${file}" readonly="true"/>
+  <target name="makeFileUnwritable" depends="createTestdir">
+    <setpermissions mode="444" nonPosixMode="tryDosOrFail">
+      <file file="${output}/${file}"/>
+    </setpermissions>
   </target>
 
   <target name="testUnwritable" depends="makeFileUnwritable">
diff --git a/src/tests/antunit/types/selectors/executable-test.xml b/src/tests/antunit/types/selectors/executable-test.xml
new file mode 100644
index 0000000..45cbeeb
--- /dev/null
+++ b/src/tests/antunit/types/selectors/executable-test.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<!--
+  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 xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+  <import file="../../antunit-base.xml" />
+
+  <property name="file" value="testfile"/>
+
+  <condition property="unix">
+    <os family="unix"/>
+  </condition>
+
+  <target name="createTestdir">
+    <mkdir dir="${output}"/>
+    <touch file="${output}/${file}"/>
+  </target>
+
+  <target name="testExecutable" depends="makeFileExecutable" if="unix">
+    <au:assertTrue>
+      <resourcecount when="equal" count="1">
+        <fileset dir="${output}">
+          <executable/>
+        </fileset>
+      </resourcecount>
+    </au:assertTrue>
+    <au:assertTrue>
+      <resourcecount when="equal" count="0">
+        <fileset dir="${output}" excludes="${file}">
+          <executable/>
+        </fileset>
+      </resourcecount>
+    </au:assertTrue>
+  </target>
+
+  <target name="makeFileExecutable" depends="createTestdir">
+    <setpermissions mode="755" nonPosixMode="pass">
+      <file file="${output}/${file}"/>
+    </setpermissions>
+  </target>
+
+  <target name="testNotexecutable" depends="createTestdir" if="unix">
+    <au:assertTrue>
+      <resourcecount when="equal" count="0">
+        <fileset dir="${output}">
+          <executable/>
+        </fileset>
+      </resourcecount>
+    </au:assertTrue>
+  </target>
+
+  <target name="testAsFalseConditions" depends="createTestdir" if="unix">
+    <au:assertFalse>
+      <isfileselected file="${output}/${file}">
+        <executable/>
+      </isfileselected>
+    </au:assertFalse>
+  </target>
+
+  <target name="testAsTrueConditions" depends="makeFileExecutable" if="unix">
+    <au:assertTrue>
+      <isfileselected file="${output}/${file}">
+        <executable/>
+      </isfileselected>
+    </au:assertTrue>
+  </target>
+
+</project>
diff --git a/src/tests/antunit/types/selectors/ownedby-test.xml b/src/tests/antunit/types/selectors/ownedby-test.xml
new file mode 100644
index 0000000..5ec4381
--- /dev/null
+++ b/src/tests/antunit/types/selectors/ownedby-test.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0"?>
+<!--
+  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 xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+  <import file="../../antunit-base.xml" />
+
+  <property name="file" value="testfile"/>
+
+  <condition property="unix">
+    <os family="unix"/>
+  </condition>
+
+  <target name="createTestdir">
+    <mkdir dir="${output}"/>
+    <touch file="${output}/${file}"/>
+  </target>
+
+  <target name="testRequiresOwner" depends="createTestdir">
+    <au:expectfailure expectedMessage="the owner attribute is required">
+      <au:assertTrue>
+        <isfileselected file="${output}/${file}">
+          <ownedBy/>
+        </isfileselected>
+      </au:assertTrue>
+    </au:expectfailure>
+  </target>
+
+  <!-- at least on Jenkins the file is owned by BUILTIN\Administrators -->
+  <target name="testOwnedBy" depends="createTestdir" if="unix">
+    <au:assertTrue>
+      <resourcecount when="equal" count="1">
+        <fileset dir="${output}">
+          <ownedBy owner="${user.name}"/>
+        </fileset>
+      </resourcecount>
+    </au:assertTrue>
+    <au:assertTrue>
+      <resourcecount when="equal" count="0">
+        <fileset dir="${output}" excludes="${file}">
+          <ownedBy owner="${user.name}"/>
+        </fileset>
+      </resourcecount>
+    </au:assertTrue>
+  </target>
+
+  <target name="testAsTrueConditions" depends="createTestdir" if="unix">
+    <au:assertTrue>
+      <isfileselected file="${output}/${file}">
+        <ownedBy owner="${user.name}"/>
+      </isfileselected>
+    </au:assertTrue>
+  </target>
+
+</project>
diff --git a/src/tests/antunit/types/selectors/readwrite-test.xml b/src/tests/antunit/types/selectors/readwrite-test.xml
index bd4ac8d..62dc052 100644
--- a/src/tests/antunit/types/selectors/readwrite-test.xml
+++ b/src/tests/antunit/types/selectors/readwrite-test.xml
@@ -64,13 +64,10 @@
     </au:assertTrue>
   </target>
 
-  <target name="makeFileUnwritable"
-          depends="createTestdir,makeFileUnwritable-Unix,makeFileUnwritable-Windows"/>
-  <target name="makeFileUnwritable-Unix" id="unix">
-    <chmod file="${output}/${file}" perm="444"/>
-  </target>
-  <target name="makeFileUnwritable-Windows" unless="unix">
-    <attrib file="${output}/${file}" readonly="true"/>
+  <target name="makeFileUnwritable" depends="createTestdir">
+    <setpermissions mode="444" nonPosixMode="tryDosOrFail">
+      <file file="${output}/${file}"/>
+    </setpermissions>
   </target>
 
   <target name="testUnwritable" depends="makeFileUnwritable">
diff --git a/src/tests/antunit/types/selectors/symlink-test.xml b/src/tests/antunit/types/selectors/symlink-test.xml
new file mode 100644
index 0000000..0c47326
--- /dev/null
+++ b/src/tests/antunit/types/selectors/symlink-test.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<!--
+  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 xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+  <import file="../../antunit-base.xml" />
+
+  <property name="file" value="testfile"/>
+  <property name="link" value="testlink"/>
+
+  <condition property="unix">
+    <os family="unix"/>
+  </condition>
+
+  <target name="createTestdir">
+    <mkdir dir="${output}"/>
+    <touch file="${output}/${file}"/>
+  </target>
+
+  <target name="testSymlink" depends="makeSymlink" if="unix">
+    <au:assertTrue>
+      <resourcecount when="equal" count="1">
+        <fileset dir="${output}">
+          <symlink/>
+        </fileset>
+      </resourcecount>
+    </au:assertTrue>
+    <au:assertTrue>
+      <resourcecount when="equal" count="0">
+        <fileset dir="${output}" excludes="${link}">
+          <symlink/>
+        </fileset>
+      </resourcecount>
+    </au:assertTrue>
+  </target>
+
+  <target name="makeSymlink"
+          depends="createTestdir,makeSymlink-Unix,makeSymlink-Windows"/>
+  <target name="makeSymlink-Unix" if="unix">
+    <symlink link="${output}/${link}" resource="${output}/${file}"/>
+  </target>
+  <target name="makeSymlink-Windows" unless="unix">
+    <!-- no idea how to do this -->
+  </target>
+
+  <target name="testNoSymlink" depends="createTestdir">
+    <au:assertTrue>
+      <resourcecount when="equal" count="0">
+        <fileset dir="${output}">
+          <symlink/>
+        </fileset>
+      </resourcecount>
+    </au:assertTrue>
+  </target>
+
+  <target name="testAsFalseConditions" depends="createTestdir">
+    <au:assertFalse>
+      <isfileselected file="${output}/${link}">
+        <symlink/>
+      </isfileselected>
+    </au:assertFalse>
+  </target>
+
+  <target name="testAsTrueConditions" depends="makeSymlink" if="unix">
+    <au:assertTrue>
+      <isfileselected file="${output}/${link}">
+        <symlink/>
+      </isfileselected>
+    </au:assertTrue>
+  </target>
+
+</project>
diff --git a/src/tests/junit/org/apache/tools/ant/IntrospectionHelperTest.java b/src/tests/junit/org/apache/tools/ant/IntrospectionHelperTest.java
index b76ef1d..48acf79 100644
--- a/src/tests/junit/org/apache/tools/ant/IntrospectionHelperTest.java
+++ b/src/tests/junit/org/apache/tools/ant/IntrospectionHelperTest.java
@@ -21,6 +21,8 @@
 import java.io.File;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
@@ -475,6 +477,7 @@
         attrMap.put("seventeen", Byte.TYPE);
         attrMap.put("eightteen", Short.TYPE);
         attrMap.put("nineteen", Double.TYPE);
+        attrMap.put("twenty", Path.class);
 
         /*
          * JUnit 3.7 adds a getName method to TestCase - so we now
@@ -556,6 +559,8 @@
                          Short.valueOf((short) 18), Short.valueOf((short) 10));
         assertAttrMethod("nineteen", "setNineteen", Double.TYPE,
                          Double.valueOf(19), Double.valueOf((short) 10));
+        assertAttrMethod("twenty", "setTwenty", Path.class,
+                         new File(projectBasedir + 20).toPath(), Paths.get("toto"));
 
         try {
             assertAttrMethod("onehundred", null, null, null, null);
@@ -648,6 +653,18 @@
         assertTrue("Expected 19, received " + d, diff > -1e-6 && diff < 1e-6);
     }
 
+    public void setTwenty(Path p) {
+        String path = p.toAbsolutePath().toString();
+        if (Os.isFamily("unix") || Os.isFamily("openvms")) {
+            assertEquals(projectBasedir + "20", path);
+        } else if (Os.isFamily("netware")) {
+            assertEquals(projectBasedir + "20", path.toLowerCase(Locale.US));
+        } else {
+            assertEquals(":" + projectBasedir + "20",
+                         path.toLowerCase(Locale.US).substring(1));
+        }
+    }
+
     @Test
     public void testGetExtensionPoints() {
         List extensions = ih.getExtensionPoints();
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/CopyTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/CopyTest.java
index f7780e3..24c5e15 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/CopyTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/CopyTest.java
@@ -222,15 +222,13 @@
         buildRule.executeTarget("testFileResourceWithFilter");
         File file1 = new File(buildRule.getProject().getProperty("to.dir") + "/fileNR.txt");
         assertTrue(file1.exists());
-        FileReader f = null;
         try {
-            f = new FileReader(file1);
-            String file1Content = FileUtils.readFully(f);
-            assertEquals("This is file 42", file1Content);
+            try (FileReader f = new FileReader(file1)) {
+                String file1Content = FileUtils.readFully(f);
+                assertEquals("This is file 42", file1Content);
+            }
         } catch (IOException e) {
             // no-op: not a real business error
-        } finally {
-            FileUtils.close(f);
         }
     }
 
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/GetTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/GetTest.java
index 3e1157d..fb78937 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/GetTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/GetTest.java
@@ -18,6 +18,7 @@
 
 package org.apache.tools.ant.taskdefs;
 
+import org.apache.tools.ant.AntAssert;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.BuildFileRule;
 import org.junit.After;
@@ -25,6 +26,7 @@
 import org.junit.Rule;
 import org.junit.Test;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
 /**
@@ -103,6 +105,8 @@
     public void test7() {
         try {
             buildRule.executeTarget("test7");
+            AntAssert.assertNotContains("Adding header", buildRule.getLog());
+
             fail("userAgent may not be null or empty");
         } catch (BuildException ex) {
             //TODO assert value
@@ -119,4 +123,35 @@
         buildRule.executeTarget("testUseTomorrow");
     }
 
+    @Test
+    public void testTwoHeadersAreAddedOK() {
+        buildRule.executeTarget("testTwoHeadersAreAddedOK");
+        String log = buildRule.getLog();
+        AntAssert.assertContains("Adding header 'header1'", log);
+        AntAssert.assertContains("Adding header 'header2'", log);
+    }
+
+    @Test
+    public void testEmptyHeadersAreNeverAdded() {
+        buildRule.executeTarget("testEmptyHeadersAreNeverAdded");
+        AntAssert.assertNotContains("Adding header", buildRule.getLog());
+    }
+
+    @Test
+    public void testThatWhenMoreThanOneHeaderHaveSameNameOnlyLastOneIsAdded() {
+        buildRule.executeTarget("testThatWhenMoreThanOneHeaderHaveSameNameOnlyLastOneIsAdded");
+        String log = buildRule.getLog();
+        AntAssert.assertContains("Adding header 'header1'", log);
+
+        int actualHeaderCount = log.split("Adding header ").length - 1;
+
+        assertEquals("Only one header has been added", 1, actualHeaderCount);
+    }
+
+    @Test
+    public void testHeaderSpaceTrimmed() {
+        buildRule.executeTarget("testHeaderSpaceTrimmed");
+        AntAssert.assertContains("Adding header 'header1'", buildRule.getLog());
+    }
+
 }
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/JavacTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/JavacTest.java
index 845393d..ce302dc 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/JavacTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/JavacTest.java
@@ -35,7 +35,6 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
 /**
  * Testcase for <javac>.
@@ -249,46 +248,31 @@
         assertEquals("1.5", javac.getTarget());
     }
 
-    @Test
+    @Test(expected = BuildException.class)
     public void testModulesourcepathOrSrcDirRequired() {
-        try {
-            javac.checkParameters();
-            fail("Build exception should have been thrown - neither srcDir nor modulesourcepath");
-        } catch (BuildException e) {
-            //pass
-        }
+        javac.checkParameters();
     }
 
-    @Test
+    @Test(expected = BuildException.class)
     public void testModulesourcepathAndSrcDirForbidden() {
-        try {
-            javac.checkParameters();
-            final Path p = new Path(project);
-            p.setPath("src");
-            javac.setSrcdir(p);
-            final Path mp = new Path(project);
-            p.setPath("modsrc");
-            javac.setModulesourcepath(mp);
-            fail("Build exception should have been thrown - neither srcDir nor modulesourcepath");
-        } catch (BuildException e) {
-            //pass
-        }
+        javac.checkParameters();
+        final Path p = new Path(project);
+        p.setPath("src");
+        javac.setSrcdir(p);
+        final Path mp = new Path(project);
+        p.setPath("modsrc");
+        javac.setModulesourcepath(mp);
     }
 
-    @Test
+    @Test(expected = BuildException.class)
     public void testModulesourcepathAndSourcepathForbidden() {
-        try {
-            javac.checkParameters();
-            final Path p = new Path(project);
-            p.setPath("src");
-            javac.setSourcepath(p);
-            final Path mp = new Path(project);
-            p.setPath("modsrc");
-            javac.setModulesourcepath(mp);
-            fail("Build exception should have been thrown - neither srcDir nor modulesourcepath");
-        } catch (BuildException e) {
-            //pass
-        }
+        javac.checkParameters();
+        final Path p = new Path(project);
+        p.setPath("src");
+        javac.setSourcepath(p);
+        final Path mp = new Path(project);
+        p.setPath("modsrc");
+        javac.setModulesourcepath(mp);
     }
 
     @Test
@@ -317,16 +301,11 @@
         }
     }
 
-    @Test
+    @Test(expected = BuildException.class)
     public void testModulesourcepathRequiresDestdir() {
-        try {
-            final Path p = new Path(project);
-            p.setPath("src");
-            javac.setModulesourcepath(p);
-            javac.checkParameters();
-            fail("Build exception should have been thrown - modulesourcepath requires destdir");
-        } catch (BuildException e) {
-            //pass
-        }
+        final Path p = new Path(project);
+        p.setPath("src");
+        javac.setModulesourcepath(p);
+        javac.checkParameters();
     }
 }
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/ProtectedJarMethodsTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/ProtectedJarMethodsTest.java
index c83a772..1d1a670 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/ProtectedJarMethodsTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/ProtectedJarMethodsTest.java
@@ -21,6 +21,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.tools.ant.BuildFileRule;
 import org.junit.Before;
@@ -50,8 +51,8 @@
     public void testGrabFilesAndDirs() throws IOException {
         buildRule.executeTarget("testIndexTests");
         String archive = buildRule.getProject().getProperty(tempJar);
-        ArrayList dirs = new ArrayList();
-        ArrayList files = new ArrayList();
+        List<String> dirs = new ArrayList<>();
+        List<String> files = new ArrayList<>();
         String[] expectedDirs = new String[] {
             "META-INF/",
             "sub/",
@@ -61,14 +62,14 @@
         };
         Jar.grabFilesAndDirs(archive, dirs, files);
         assertEquals(expectedDirs.length, dirs.size());
-        for (int i = 0; i < expectedDirs.length; i++) {
-            assertTrue("Found " + expectedDirs[i],
-                       dirs.contains(expectedDirs[i]));
+        for (String expectedDir : expectedDirs) {
+            assertTrue("Found " + expectedDir,
+                       dirs.contains(expectedDir));
         }
         assertEquals(expectedFiles.length, files.size());
-        for (int i = 0; i < expectedFiles.length; i++) {
-            assertTrue("Found " + expectedFiles[i],
-                       files.contains(expectedFiles[i]));
+        for (String expectedFile : expectedFiles) {
+            assertTrue("Found " + expectedFile,
+                       files.contains(expectedFile));
         }
     }
 
@@ -81,26 +82,23 @@
 
     @Test
     public void testFindJarNameNoMatch() {
-        assertNull(Jar.findJarName("foo", new String[] {"bar"}));
+        assertNull(Jar.findJarName("foo", new String[] { "bar" }));
     }
 
     @Test
     public void testFindJarNameSimpleMatches() {
-        assertEquals("foo", Jar.findJarName("foo", new String[] {"foo"}));
-        assertEquals("lib/foo", Jar.findJarName("foo",
-                                                new String[] {"lib/foo"}));
-        assertEquals("foo", Jar.findJarName("bar" + File.separatorChar + "foo",
-                                            new String[] {"foo"}));
+        assertEquals("foo", Jar.findJarName("foo", new String[] { "foo" }));
         assertEquals("lib/foo",
-                     Jar.findJarName("bar" + File.separatorChar + "foo",
-                                     new String[] {"lib/foo"}));
+            Jar.findJarName("foo", new String[] { "lib/foo" }));
+        assertEquals("foo", Jar.findJarName("bar" + File.separatorChar + "foo",
+            new String[] { "foo" }));
+        assertEquals("lib/foo", Jar.findJarName(
+            "bar" + File.separatorChar + "foo", new String[] { "lib/foo" }));
     }
 
     @Test
     public void testFindJarNameLongestMatchWins() {
-        assertEquals("lib/foo",
-                     Jar.findJarName("lib/foo",
-                                     new String[] {"foo", "lib/foo",
-                                                   "lib/bar/foo"}));
+        assertEquals("lib/foo", Jar.findJarName("lib/foo",
+            new String[] { "foo", "lib/foo", "lib/bar/foo" }));
     }
 }
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/RmicAdvancedTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/RmicAdvancedTest.java
index 138712d..139ff68 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/RmicAdvancedTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/RmicAdvancedTest.java
@@ -343,28 +343,6 @@
     }
 
     /**
-     * test that passes -Xnew to sun's rmic.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testXnew() throws Exception {
-        // skipped via unless attribute for JDK > 6
-        buildRule.executeTarget("testXnew");
-    }
-
-    /**
-     * test that passes -Xnew to sun's rmic.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testXnewDest() throws Exception {
-        // skipped via unless attribute for JDK > 6
-        buildRule.executeTarget("testXnewDest");
-    }
-
-    /**
      * test that passes -Xnew to sun's rmic running in a different VM.
      *
      * @throws Exception if something goes wrong
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/SignJarTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/SignJarTest.java
index 95585fd..91073bd 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/SignJarTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/SignJarTest.java
@@ -22,7 +22,6 @@
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.BuildFileRule;
-import org.apache.tools.ant.util.JavaEnvUtils;
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Rule;
@@ -106,7 +105,6 @@
 
     @Test
     public void testTsaLocalhost() {
-        Assume.assumeTrue("Only runs on Java 1.5+", JavaEnvUtils.getJavaVersionNumber()>=15);
         try {
             buildRule.executeTarget("testTsaLocalhost");
             fail("Should have thrown exception - no TSA at localhost:0");
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapterTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapterTest.java
index 4ea079c..2791e7d 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapterTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapterTest.java
@@ -248,6 +248,7 @@
             javac.setProject(prj);
             final Commandline[] cmd = new Commandline[1];
             final DefaultCompilerAdapter impl = new DefaultCompilerAdapter() {
+                @Override
                 public boolean execute() throws BuildException {
                     cmd[0] = setupModernJavacCommand();
                     return true;
@@ -303,6 +304,7 @@
             javac.setProject(prj);
             final Commandline[] cmd = new Commandline[1];
             final DefaultCompilerAdapter impl = new DefaultCompilerAdapter() {
+                @Override
                 public boolean execute() throws BuildException {
                     cmd[0] = setupModernJavacCommand();
                     return true;
@@ -366,6 +368,7 @@
             final LogCapturingJavac javac = new LogCapturingJavac();
             javac.setProject(prj);
             final DefaultCompilerAdapter impl = new DefaultCompilerAdapter() {
+                @Override
                 public boolean execute() throws BuildException {
                     setupModernJavacCommand();
                     return true;
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ReplaceRegExpTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ReplaceRegExpTest.java
index b7ab748..be1685b 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ReplaceRegExpTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ReplaceRegExpTest.java
@@ -129,4 +129,4 @@
         assertEquals(ts1, testFile.lastModified());
     }
 
-}// ReplaceRegExpTest
+}
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RhinoScriptTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RhinoScriptTest.java
index 3ca428e..4a2aeda 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RhinoScriptTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RhinoScriptTest.java
@@ -17,12 +17,14 @@
  */
 package org.apache.tools.ant.taskdefs.optional;
 
+import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.BuildFileRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 /**
  * Tests the examples of the &lt;script&gt; task docs.
@@ -64,4 +66,24 @@
         assertTrue(index > -1);
     }
 
+    @Test
+    public void testUseSrcAndEncoding() {
+        final String readerEncoding = "UTF-8";
+        buildRule.getProject().setProperty("useSrcAndEncoding.reader.encoding", readerEncoding);
+        buildRule.executeTarget("useSrcAndEncoding");
+    }
+
+    @Test
+    public void testUseSrcAndEncodingFailure() {
+        final String readerEncoding = "ISO-8859-1";
+        buildRule.getProject().setProperty("useSrcAndEncoding.reader.encoding", readerEncoding);
+        try {
+            buildRule.executeTarget("useSrcAndEncoding");
+            fail("should have failed with reader's encoding [" + readerEncoding
+                    + "] different from the writer's encoding ["
+                    + buildRule.getProject().getProperty("useSrcAndEncoding.encoding") + "]");
+        } catch (BuildException e) {
+            assertTrue(e.getMessage().matches("expected <eacute \\[\u00e9]> but was <eacute \\[\u00c3\u00a9]>"));
+        }
+    }
 }
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/image/ImageTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/image/ImageTest.java
index b39832b..40d0caa 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/image/ImageTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/image/ImageTest.java
@@ -21,6 +21,7 @@
 import org.apache.tools.ant.AntAssert;
 import org.apache.tools.ant.BuildFileRule;
 import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Rule;
@@ -29,6 +30,7 @@
 import java.io.File;
 
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
 
 
@@ -48,6 +50,8 @@
 
     @Before
     public void setUp() {
+        /* JAI depends on internal API removed in Java 9 */
+        assumeFalse(JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_9));
         buildRule.configureProject(TASKDEFS_DIR + "image.xml");
     }
 
@@ -72,7 +76,7 @@
         buildRule.executeTarget("testSimpleScale");
         AntAssert.assertContains("Processing File", buildRule.getLog());
         File f = new File(buildRule.getOutputDir(), LARGEIMAGE);
-        assumeTrue("Could not change file modificaiton date",
+        assumeTrue("Could not change file modification date",
                 f.setLastModified(f.lastModified() - FILE_UTILS.getFileTimestampGranularity() * 2));
         long lastModified = f.lastModified();
         buildRule.executeTarget("testOverwriteTrue");
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java
index 28d7f9c..6d88c6c 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java
@@ -497,7 +497,7 @@
             assertNotNull(mockProcLauncher.cmd);
             String resCp = null;
             String resMp = null;
-            Set<String> resExports = new TreeSet<String>();
+            Set<String> resExports = new TreeSet<>();
             for (int i = 1; i < mockProcLauncher.cmd.length; i++) {
                 if ("-classpath".equals(mockProcLauncher.cmd[i])) { //NOI18N
                     resCp = mockProcLauncher.cmd[++i];
@@ -554,7 +554,7 @@
             assertNotNull(mockProcLauncher.cmd);
             String resCp = null;
             String resMp = null;
-            Set<String> resExports = new TreeSet<String>();
+            Set<String> resExports = new TreeSet<>();
             for (int i = 1; i < mockProcLauncher.cmd.length; i++) {
                 if ("-classpath".equals(mockProcLauncher.cmd[i])) { //NOI18N
                     resCp = mockProcLauncher.cmd[++i];
@@ -594,8 +594,7 @@
 
         @Override
         public Process exec(Project project, String[] cmd, String[] env, File workingDir) throws IOException {
-            this.cmd = new String[cmd.length];
-            System.arraycopy(cmd, 0, this.cmd, 0, cmd.length);
+            this.cmd = Arrays.copyOf(cmd, cmd.length);
             return new MockProcess();
         }
 
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunnerTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunnerTest.java
index e8544ce..7ea41e8 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunnerTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunnerTest.java
@@ -254,9 +254,7 @@
     public static class AssertionErrorTest {
         @Test
         public void throwsAssertionError() {
-            AssertionError assertionError = new AssertionError("failure message");
-            assertionError.initCause(new RuntimeException("cause message"));
-            throw assertionError;
+            throw new AssertionError("failure message", new RuntimeException("cause message"));
         }
     }
 }
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/ScriptDefTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/ScriptDefTest.java
index 66e6567..89aa385 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/ScriptDefTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/ScriptDefTest.java
@@ -140,5 +140,45 @@
             log.indexOf("Attribute value = test") != -1);
     }
 
+    @Test
+    public void testUseSrcAndEncoding() {
+        final String readerEncoding = "UTF-8";
+        buildRule.getProject().setProperty("useSrcAndEncoding.reader.encoding", readerEncoding);
+        buildRule.executeTarget("useSrcAndEncoding");
+    }
 
+    @Test
+    public void testUseSrcAndEncodingFailure() {
+        final String readerEncoding = "ISO-8859-1";
+        buildRule.getProject().setProperty("useSrcAndEncoding.reader.encoding", readerEncoding);
+        try {
+            buildRule.executeTarget("useSrcAndEncoding");
+            fail("should have failed with reader's encoding [" + readerEncoding +
+                "] different from the writer's encoding [" +
+                buildRule.getProject().getProperty("useSrcAndEncoding.encoding") + "]");
+        } catch(BuildException e) {
+            assertTrue(e.getMessage().matches(
+                    "expected <eacute \\[\u00e9]> but was <eacute \\[\u00c3\u00a9]>"));
+        }
+    }
+
+    @Test
+    public void testUseCompiled() {
+
+        final long duration;
+        {
+            long start = System.nanoTime();
+            buildRule.executeTarget("useCompiled");
+            duration = System.nanoTime() - start;
+        }
+
+        final long notCompiledDuration;
+        {
+            long start = System.nanoTime();
+            buildRule.executeTarget("useNotCompiled");
+            notCompiledDuration = System.nanoTime() - start;
+        }
+
+        assertTrue(duration < notCompiledDuration);
+    }
 }
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ssh/ScpTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ssh/ScpTest.java
index f32b4ff..7f9bdda 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ssh/ScpTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ssh/ScpTest.java
@@ -150,7 +150,7 @@
     @Test
     public void testMultiResourceCollectionUpload() throws IOException {
         assertNotNull("system property scp.tmp must be set", tempDir);
-        List uploadList = new ArrayList();
+        List<File> uploadList = new ArrayList<>();
         for (int i = 0; i < 5; i++) {
             uploadList.add(createTemporaryFile());
         }
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/unix/SymlinkTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/unix/SymlinkTest.java
index b5f4bbf..257a8ee 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/unix/SymlinkTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/unix/SymlinkTest.java
@@ -35,6 +35,7 @@
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.util.SymbolicLinkUtils;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Rule;
@@ -46,6 +47,9 @@
 import static org.junit.Assert.fail;
 
 import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 
 /**
  * Test cases for the Symlink task. Link creation, link deletion, recording
@@ -167,6 +171,7 @@
         if (dirlinkRem != null) {
             fail(dirlinkRem);
         }
+
         assertNotNull("Failed to recreate link1",
                       p.getProperty("test.recreate.link1.recreated"));
         assertNotNull("Failed to recreate link2",
@@ -287,6 +292,26 @@
 
     }
 
+    /**
+     * Tests that when {@code symlink} task is used to create a symbolic link and {@code overwrite} option
+     * is {@code false}, then any existing symbolic link at the {@code link} location (whose target is a directory)
+     * doesn't end up create a new symbolic link within the target directory.
+     *
+     *
+     * @throws Exception
+     * @see <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=58683">BZ-58683</a> for more details
+     */
+    @Test
+    public void testOverwriteExistingLink() throws Exception {
+        buildRule.executeTarget("test-overwrite-link");
+        final Project p = buildRule.getProject();
+        final String linkTargetResource = p.getProperty("test.overwrite.link.target.dir");
+        Assert.assertNotNull("Property test.overwrite.link.target.dir is not set", linkTargetResource);
+        final Path targetResourcePath = Paths.get(linkTargetResource);
+        Assert.assertTrue(targetResourcePath + " is not a directory", Files.isDirectory(targetResourcePath));
+        Assert.assertEquals(targetResourcePath + " directory was expected to be empty", 0, Files.list(targetResourcePath).count());
+    }
+
     @After
     public void tearDown() {
         if (buildRule.getProject() != null) {
diff --git a/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java b/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java
index 3a2a7ec..34a4f09 100644
--- a/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java
+++ b/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java
@@ -18,7 +18,6 @@
 package org.apache.tools.ant.types.resources;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
@@ -34,33 +33,36 @@
 public class LazyResourceCollectionTest {
 
     private class StringResourceCollection implements ResourceCollection {
-        List resources = Arrays.<Resource>asList();
+        List<StringResourceIterator> createdIterators = new ArrayList<>();
 
-        List createdIterators = new ArrayList();
-
+        @Override
         public int size() {
-            return resources.size();
+            return 3;
         }
 
+        @Override
         public Iterator<Resource> iterator() {
             StringResourceIterator it = new StringResourceIterator();
             createdIterators.add(it);
             return it;
         }
 
+        @Override
         public boolean isFilesystemOnly() {
             return false;
         }
     }
 
-    private class StringResourceIterator implements Iterator {
+    private class StringResourceIterator implements Iterator<Resource> {
         int cursor = 0;
 
+        @Override
         public void remove() {
             throw new UnsupportedOperationException();
         }
 
-        public Object next() {
+        @Override
+        public StringResource next() {
             if (cursor < 3) {
                 cursor++;
                 return new StringResource("r" + cursor);
@@ -68,6 +70,7 @@
             return null;
         }
 
+        @Override
         public boolean hasNext() {
             return cursor < 3;
         }
@@ -81,27 +84,24 @@
 
         Iterator<Resource> it = lazyCollection.iterator();
         assertOneCreatedIterator(collectionTest);
-        StringResourceIterator stringResourceIterator = (StringResourceIterator) collectionTest.createdIterators.get(0);
+        StringResourceIterator stringResourceIterator = collectionTest.createdIterators.get(0);
         assertEquals("A resource was loaded without iterating", 1,
-                stringResourceIterator.cursor);
+            stringResourceIterator.cursor);
 
-        StringResource r = (StringResource) it.next();
+        assertStringValue("r1", it.next());
         assertOneCreatedIterator(collectionTest);
-        assertEquals("r1", r.getValue());
         assertEquals("Iterating once load more than 1 resource", 2,
-                stringResourceIterator.cursor);
+            stringResourceIterator.cursor);
 
-        r = (StringResource) it.next();
+        assertStringValue("r2", it.next());
         assertOneCreatedIterator(collectionTest);
-        assertEquals("r2", r.getValue());
         assertEquals("Iterating twice load more than 2 resources", 3,
-                stringResourceIterator.cursor);
+            stringResourceIterator.cursor);
 
-        r = (StringResource) it.next();
+        assertStringValue("r3", it.next());
         assertOneCreatedIterator(collectionTest);
-        assertEquals("r3", r.getValue());
         assertEquals("Iterating 3 times load more than 3 resources", 3,
-                stringResourceIterator.cursor);
+            stringResourceIterator.cursor);
 
         try {
             it.next();
@@ -129,39 +129,36 @@
         Iterator<Resource> it2 = lazyCollection.iterator();
         assertOneCreatedIterator(collectionTest);
 
-        StringResourceIterator stringResourceIterator = (StringResourceIterator) collectionTest.createdIterators.get(0);
+        StringResourceIterator stringResourceIterator = collectionTest.createdIterators.get(0);
         assertEquals("A resource was loaded without iterating", 1,
-                stringResourceIterator.cursor);
+            stringResourceIterator.cursor);
 
-        StringResource r = (StringResource) it1.next();
-        assertEquals("r1", r.getValue());
+        assertStringValue("r1", it1.next());
         assertEquals("Iterating once load more than 1 resource", 2,
-                stringResourceIterator.cursor);
+            stringResourceIterator.cursor);
 
-        r = (StringResource) it2.next();
-        assertEquals("r1", r.getValue());
-        assertEquals("The second iterator did not lookup in the cache for a resource",
-                2, stringResourceIterator.cursor);
+        assertStringValue("r1", it2.next());
+        assertEquals(
+            "The second iterator did not lookup in the cache for a resource", 2,
+            stringResourceIterator.cursor);
 
-        r = (StringResource) it2.next();
-        assertEquals("r2", r.getValue());
+        assertStringValue("r2", it2.next());
         assertEquals("Iterating twice load more than 2 resources", 3,
-                stringResourceIterator.cursor);
+            stringResourceIterator.cursor);
 
-        r = (StringResource) it1.next();
-        assertEquals("r2", r.getValue());
-        assertEquals("The first iterator did not lookup in the cache for a resource",
-                3, stringResourceIterator.cursor);
+        assertStringValue("r2", it1.next());
+        assertEquals(
+            "The first iterator did not lookup in the cache for a resource", 3,
+            stringResourceIterator.cursor);
 
-        r = (StringResource) it2.next();
-        assertEquals("r3", r.getValue());
+        assertStringValue("r3", it2.next());
         assertEquals("Iterating 3 times load more than 3 resources", 3,
-                stringResourceIterator.cursor);
+            stringResourceIterator.cursor);
 
-        r = (StringResource) it1.next();
-        assertEquals("r3", r.getValue());
-        assertEquals("The first iterator did not lookup in the cache for a resource",
-                3, stringResourceIterator.cursor);
+        assertStringValue("r3", it1.next());
+        assertEquals(
+            "The first iterator did not lookup in the cache for a resource", 3,
+            stringResourceIterator.cursor);
 
         try {
             it1.next();
@@ -177,4 +174,8 @@
             // ok
         }
     }
+
+    private void assertStringValue(String expected, Resource r) {
+        assertEquals(expected, r.as(StringResource.class).getValue());
+    }
 }
diff --git a/src/tests/junit/org/apache/tools/ant/types/selectors/OwnedBySelectorTest.java b/src/tests/junit/org/apache/tools/ant/types/selectors/OwnedBySelectorTest.java
new file mode 100644
index 0000000..389923f
--- /dev/null
+++ b/src/tests/junit/org/apache/tools/ant/types/selectors/OwnedBySelectorTest.java
@@ -0,0 +1,53 @@
+/*
+ *  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.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.attribute.UserPrincipal;
+
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.junit.Assume;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class OwnedBySelectorTest {
+
+    @Rule
+    public TemporaryFolder folder = new TemporaryFolder();
+
+    @Test
+    public void ownedByIsTrueForSelf() throws Exception {
+        // at least on Jenkins the file is owned by "BUILTIN\Administrators"
+        Assume.assumeFalse(Os.isFamily("windows"));
+        String self = System.getProperty("user.name");
+        File file = folder.newFile("f.txt");
+        UserPrincipal user = Files.getOwner(file.toPath());
+        assertEquals(self, user.getName());
+
+        OwnedBySelector s = new OwnedBySelector();
+        s.setOwner(self);
+        assertTrue(s.isSelected(null, null, file));
+    }
+
+}
diff --git a/src/tests/junit/org/apache/tools/ant/util/JavaEnvUtilsTest.java b/src/tests/junit/org/apache/tools/ant/util/JavaEnvUtilsTest.java
index aa71b0b..ec8e75e 100644
--- a/src/tests/junit/org/apache/tools/ant/util/JavaEnvUtilsTest.java
+++ b/src/tests/junit/org/apache/tools/ant/util/JavaEnvUtilsTest.java
@@ -106,8 +106,7 @@
         String javaHomeParent = FILE_UTILS.normalize(javaHome + "/..").getAbsolutePath();
         assertTrue(j + " is normalized and in the JDK dir", j.startsWith(javaHomeParent));
 
-        if ((Os.isFamily("mac") && JavaEnvUtils.getJavaVersionNumber() <= JavaEnvUtils.VERSION_1_6)
-            || JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_9)) {
+        if (JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_9)) {
             assertTrue(j + " is normalized and in the JRE dir", j.startsWith(javaHome));
         } else {
             assertTrue(j + " is normalized and not in the JRE dir", !j.startsWith(javaHome));
@@ -139,4 +138,5 @@
         assertTrue(JavaEnvUtils.isJavaVersion("10"));
         assertTrue(JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_9));
     }
+
 }
diff --git a/src/tests/junit/org/apache/tools/ant/util/PermissionUtilsTest.java b/src/tests/junit/org/apache/tools/ant/util/PermissionUtilsTest.java
new file mode 100644
index 0000000..c4dd8fc
--- /dev/null
+++ b/src/tests/junit/org/apache/tools/ant/util/PermissionUtilsTest.java
@@ -0,0 +1,160 @@
+/*
+ *  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.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.attribute.PosixFileAttributeView;
+import java.nio.file.attribute.PosixFilePermission;
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.TarResource;
+import org.apache.tools.ant.types.resources.ZipResource;
+import org.apache.tools.tar.TarEntry;
+import org.apache.tools.tar.TarOutputStream;
+import org.apache.tools.zip.ZipEntry;
+import org.apache.tools.zip.ZipOutputStream;
+import org.junit.Assume;
+import org.junit.Test;
+
+public class PermissionUtilsTest {
+
+    @Test
+    public void modeFromPermissionsReturnsExpectedResult() {
+        int mode = PermissionUtils.modeFromPermissions(EnumSet.of(PosixFilePermission.OWNER_READ,
+                                                                  PosixFilePermission.OWNER_WRITE,
+                                                                  PosixFilePermission.OWNER_EXECUTE),
+                                                       PermissionUtils.FileType.REGULAR_FILE);
+        assertEquals("100700", Integer.toString(mode, 8));
+    }
+
+    @Test
+    public void permissionsFromModeReturnsExpectedResult() {
+        Set<PosixFilePermission> s = PermissionUtils.permissionsFromMode(0100753);
+        assertEquals(EnumSet.of(PosixFilePermission.OWNER_READ,
+                                PosixFilePermission.OWNER_WRITE,
+                                PosixFilePermission.OWNER_EXECUTE,
+                                PosixFilePermission.GROUP_READ,
+                                PosixFilePermission.GROUP_EXECUTE,
+                                PosixFilePermission.OTHERS_WRITE,
+                                PosixFilePermission.OTHERS_EXECUTE),
+                     s);
+    }
+
+    @Test
+    public void detectsFileTypeOfRegularFileFromPath() throws IOException {
+        File f = File.createTempFile("ant", ".tst");
+        f.deleteOnExit();
+        assertEquals(PermissionUtils.FileType.REGULAR_FILE,
+                     PermissionUtils.FileType.of(f.toPath()));
+    }
+
+    @Test
+    public void detectsFileTypeOfRegularFileFromResource() throws IOException {
+        File f = File.createTempFile("ant", ".tst");
+        f.deleteOnExit();
+        assertEquals(PermissionUtils.FileType.REGULAR_FILE,
+                     PermissionUtils.FileType.of(new FileResource(f)));
+    }
+
+    @Test
+    public void detectsFileTypeOfDirectoryFromPath() throws IOException {
+        File f = File.createTempFile("ant", ".dir");
+        f.delete();
+        f.mkdirs();
+        f.deleteOnExit();
+        assertEquals(PermissionUtils.FileType.DIR,
+                     PermissionUtils.FileType.of(f.toPath()));
+    }
+
+    @Test
+    public void detectsFileTypeOfDirectoryFromResource() throws IOException {
+        File f = File.createTempFile("ant", ".tst");
+        f.delete();
+        f.mkdirs();
+        f.deleteOnExit();
+        assertEquals(PermissionUtils.FileType.DIR,
+                     PermissionUtils.FileType.of(new FileResource(f)));
+    }
+
+    @Test
+    public void getSetPermissionsWorksForFiles() throws IOException {
+        File f = File.createTempFile("ant", ".tst");
+        f.deleteOnExit();
+        Assume.assumeNotNull(Files.getFileAttributeView(f.toPath(),
+                                                        PosixFileAttributeView.class));
+        Set<PosixFilePermission> s =
+            EnumSet.of(PosixFilePermission.OWNER_READ,
+                       PosixFilePermission.OWNER_WRITE,
+                       PosixFilePermission.OWNER_EXECUTE,
+                       PosixFilePermission.GROUP_READ);
+        PermissionUtils.setPermissions(new FileResource(f), s, null);
+        assertEquals(s, PermissionUtils.getPermissions(new FileResource(f), null));
+    }
+
+    @Test
+    public void getSetPermissionsWorksForZipResources() throws IOException {
+        File f = File.createTempFile("ant", ".zip");
+        f.deleteOnExit();
+        try (ZipOutputStream os = new ZipOutputStream(f)) {
+            ZipEntry e = new ZipEntry("foo");
+            os.putNextEntry(e);
+            os.closeEntry();
+        }
+
+        ZipResource r = new ZipResource();
+        r.setName("foo");
+        r.setArchive(f);
+        Set<PosixFilePermission> s =
+            EnumSet.of(PosixFilePermission.OWNER_READ,
+                       PosixFilePermission.OWNER_WRITE,
+                       PosixFilePermission.OWNER_EXECUTE,
+                       PosixFilePermission.GROUP_READ);
+        PermissionUtils.setPermissions(r, s, null);
+        assertEquals(s, PermissionUtils.getPermissions(r, null));
+    }
+
+    @Test
+    public void getSetPermissionsWorksForTarResources() throws IOException {
+        File f = File.createTempFile("ant", ".zip");
+        f.deleteOnExit();
+        try (TarOutputStream os = new TarOutputStream(new FileOutputStream(f))) {
+            TarEntry e = new TarEntry("foo");
+            os.putNextEntry(e);
+            os.closeEntry();
+        }
+
+        TarResource r = new TarResource();
+        r.setName("foo");
+        r.setArchive(f);
+        Set<PosixFilePermission> s =
+            EnumSet.of(PosixFilePermission.OWNER_READ,
+                       PosixFilePermission.OWNER_WRITE,
+                       PosixFilePermission.OWNER_EXECUTE,
+                       PosixFilePermission.GROUP_READ);
+        PermissionUtils.setPermissions(r, s, null);
+        assertEquals(s, PermissionUtils.getPermissions(r, null));
+    }
+}
diff --git a/src/tests/junit/org/apache/tools/ant/util/ReaderInputStreamTest.java b/src/tests/junit/org/apache/tools/ant/util/ReaderInputStreamTest.java
index 1951a8a..0e4f009 100644
--- a/src/tests/junit/org/apache/tools/ant/util/ReaderInputStreamTest.java
+++ b/src/tests/junit/org/apache/tools/ant/util/ReaderInputStreamTest.java
@@ -127,9 +127,7 @@
     @SuppressWarnings("resource")
     private void compareBytes(String s, String encoding) throws Exception {
         byte[] expected = s.getBytes(encoding);
-
-        ReaderInputStream r = new ReaderInputStream(
-            new StringReader(s), encoding);
+        ReaderInputStream r = new ReaderInputStream(new StringReader(s), encoding);
         for (int i = 0; i < expected.length; ++i) {
             int expect = expected[i] & 0xFF;
             int read = r.read();
diff --git a/src/tests/junit/org/apache/tools/ant/util/StringUtilsTest.java b/src/tests/junit/org/apache/tools/ant/util/StringUtilsTest.java
index 59d3ec6..4c3220a 100644
--- a/src/tests/junit/org/apache/tools/ant/util/StringUtilsTest.java
+++ b/src/tests/junit/org/apache/tools/ant/util/StringUtilsTest.java
@@ -17,14 +17,17 @@
  */
 package org.apache.tools.ant.util;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Vector;
 
 import org.junit.Test;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
 /**
  * Test for StringUtils
  */
@@ -33,7 +36,7 @@
     @Test
     public void testSplit() {
         final String data = "a,b,,";
-        Vector res = StringUtils.split(data, ',');
+        Vector<String> res = StringUtils.split(data, ',');
         assertEquals(4, res.size());
         assertEquals("a", res.elementAt(0));
         assertEquals("b", res.elementAt(1));
@@ -44,7 +47,7 @@
     @Test
     public void testSplitLines() {
         final String data = "a\r\nb\nc\nd\ne";
-        Vector res = StringUtils.lineSplit(data);
+        Vector<String> res = StringUtils.lineSplit(data);
         assertEquals(5, res.size());
         assertEquals("a\r", res.elementAt(0));
         assertEquals("b", res.elementAt(1));
@@ -53,6 +56,7 @@
         assertEquals("e", res.elementAt(4));
     }
 
+    @SuppressWarnings("deprecation")
     @Test
     public void testReplace() {
         final String data = "abcabcabca";
@@ -143,13 +147,11 @@
         assertEquals(
             "Does not remove the suffix right.",
             prefix + name,
-            StringUtils.removeSuffix(input, suffix)
-        );
+            StringUtils.removeSuffix(input, suffix));
         assertEquals(
             "Should leave the string unattended.",
             prefix + name + suffix,
-            StringUtils.removeSuffix(input, "bla")
-        );
+            StringUtils.removeSuffix(input, "bla"));
     }
 
     @Test
@@ -158,15 +160,56 @@
         String name = "Name";
         String suffix = "Suffix";
         String input = prefix + name + suffix;
-        assertEquals(
-            "Does not remove the prefix right.",
+        assertEquals("Does not remove the prefix right.",
             name + suffix,
-            StringUtils.removePrefix(input, prefix)
-        );
-        assertEquals(
-            "Should leave the string unattended.",
+            StringUtils.removePrefix(input, prefix));
+        assertEquals("Should leave the string unattended.",
             prefix + name + suffix,
-            StringUtils.removePrefix(input, "bla")
-        );
+            StringUtils.removePrefix(input, "bla"));
+    }
+
+    @Test
+    public void testJoin() {
+        assertEquals("a, b, c", StringUtils.join(Arrays.asList("a", "b", "c"), ", "));
+    }
+
+    @Test
+    public void testJoinEmptyArray() {
+        assertEquals("", StringUtils.join(new String[] {}, ", "));
+    }
+
+    @Test
+    public void testJoinNullCollection() {
+        assertEquals("", StringUtils.join((Collection<String>) null, ", "));
+    }
+
+    @Test
+    public void testJoinNullArray() {
+        assertEquals("", StringUtils.join((String[]) null, ", "));
+    }
+
+    @Test
+    public void testJoinNullSeparator() {
+        assertEquals("abc", StringUtils.join(Arrays.asList("a", "b", "c"), null));
+    }
+
+    @Test
+    public void testTrimToNullWithNullInput() {
+        assertNull(StringUtils.trimToNull(null));
+    }
+
+    @Test
+    public void testTrimToNullWithEmptyInput() {
+        assertNull(StringUtils.trimToNull(""));
+    }
+
+    @Test
+    public void testTrimToNullWithBlankSpaceInput() {
+        assertNull(StringUtils.trimToNull("   "));
+    }
+
+    @Test
+    public void testTrimToNullWithInputPaddedWithSpace() {
+        assertEquals("aaBcDeF", StringUtils.trimToNull(" aaBcDeF  "));
     }
 }