java 5-8
diff --git a/src/main/org/apache/tools/ant/AntClassLoader.java b/src/main/org/apache/tools/ant/AntClassLoader.java
index 22c4b29..5f313e2 100644
--- a/src/main/org/apache/tools/ant/AntClassLoader.java
+++ b/src/main/org/apache/tools/ant/AntClassLoader.java
@@ -178,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.
@@ -196,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
@@ -221,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 =
@@ -293,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);
@@ -315,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);
     }
 
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..6729744 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
+     * @see String#format(String, Object...)
+     * @since Ant 1.11
+     */
+    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 4942d24..c772d1b 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 restrictredDefinition
      */
     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 e69c3a4..7d08fa8 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 735b349..f93fd5a 100644
--- a/src/main/org/apache/tools/ant/Diagnostics.java
+++ b/src/main/org/apache/tools/ant/Diagnostics.java
@@ -54,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.
@@ -113,8 +110,7 @@
         if (home == null) {
             return null;
         }
-        File libDir = new File(home, "lib");
-        return listJarFiles(libDir);
+        return listJarFiles(new File(home, "lib"));
 
     }
 
@@ -124,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"));
     }
 
     /**
@@ -173,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();
     }
 
     /**
@@ -187,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();
     }
 
     /**
@@ -216,17 +205,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;
     }
 
     /**
diff --git a/src/main/org/apache/tools/ant/DirectoryScanner.java b/src/main/org/apache/tools/ant/DirectoryScanner.java
index 6b52897..f4c26f6 100644
--- a/src/main/org/apache/tools/ant/DirectoryScanner.java
+++ b/src/main/org/apache/tools/ant/DirectoryScanner.java
@@ -22,13 +22,17 @@
 import java.io.IOException;
 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,7 +43,6 @@
 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;
@@ -217,7 +220,7 @@
      *
      * @see #addDefaultExcludes()
      */
-    private static final Set<String> defaultExcludes = new HashSet<String>();
+    private static final Set<String> defaultExcludes = new HashSet<>();
     static {
         resetDefaultExcludes();
     }
@@ -310,7 +313,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
@@ -327,7 +330,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
@@ -344,7 +347,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.
@@ -423,13 +426,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
@@ -605,8 +602,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);
             }
         }
     }
@@ -619,8 +616,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)));
     }
@@ -631,6 +629,7 @@
      *
      * @param basedir The base directory for scanning.
      */
+    @Override
     public synchronized void setBasedir(final File basedir) {
         this.basedir = basedir;
     }
@@ -641,6 +640,7 @@
      *
      * @return the base directory to be scanned.
      */
+    @Override
     public synchronized File getBasedir() {
         return basedir;
     }
@@ -662,6 +662,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;
     }
@@ -720,14 +721,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);
         }
     }
 
@@ -743,14 +743,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);
         }
     }
 
@@ -769,18 +768,14 @@
      */
     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);
             }
         }
     }
@@ -808,6 +803,7 @@
      *
      * @param selectors specifies the selectors to be invoked on a scan.
      */
+    @Override
     public synchronized void setSelectors(final FileSelector[] selectors) {
         this.selectors = selectors;
     }
@@ -833,6 +829,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) {
@@ -857,10 +854,10 @@
                 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);
+                    ? new String[] { SelectorUtils.DEEP_TREE_MATCH } : includes;
+                final boolean nullExcludes = excludes == null;
                 excludes = nullExcludes ? new String[0] : excludes;
 
                 if (basedir != null && !followSymlinks
@@ -887,22 +884,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("");
@@ -930,18 +924,19 @@
      */
     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(),
+                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);
@@ -1046,10 +1041,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) {
@@ -1063,14 +1057,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();
@@ -1135,10 +1129,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);
             }
         }
     }
@@ -1196,17 +1190,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;
@@ -1217,12 +1211,12 @@
             return;
         }
         if (!followSymlinks) {
-            final ArrayList<String> noLinks = new ArrayList<String>();
-            for (int i = 0; i < newfiles.length; i++) {
+            final ArrayList<String> noLinks = new ArrayList<>();
+            for (String newfile : newfiles) {
                 try {
-                    if (SYMLINK_UTILS.isSymbolicLink(dir, newfiles[i])) {
-                        final String name = vpath + newfiles[i];
-                        final File file = new File(dir, newfiles[i]);
+                    if (SYMLINK_UTILS.isSymbolicLink(dir, newfile)) {
+                        final String name = vpath + newfile;
+                        final File file = new File(dir, newfile);
                         if (file.isDirectory()) {
                             dirsExcluded.addElement(name);
                         } else if (file.isFile()) {
@@ -1230,17 +1224,17 @@
                         }
                         accountForNotFollowedSymlink(name, file);
                     } else {
-                        noLinks.add(newfiles[i]);
+                        noLinks.add(newfile);
                     }
                 } 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]);
+                    noLinks.add(newfile);
                 }
             }
-            newfiles = (noLinks.toArray(new String[noLinks.size()]));
+            newfiles = noLinks.toArray(new String[noLinks.size()]);
         } else {
             directoryNamesFollowed.addFirst(dir.getName());
         }
@@ -1322,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);
@@ -1343,13 +1337,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);
@@ -1385,17 +1378,13 @@
     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()));
     }
 
     /**
@@ -1419,19 +1408,11 @@
      *         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));
     }
 
     /**
@@ -1481,12 +1462,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));
     }
 
     /**
@@ -1495,14 +1472,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()));
     }
 
     /**
@@ -1528,17 +1501,13 @@
     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()));
     }
 
     /**
@@ -1550,14 +1519,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));
     }
 
     /**
@@ -1568,14 +1531,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;
@@ -1603,11 +1566,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()]);
     }
 
     /**
@@ -1621,11 +1583,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()]);
     }
 
     /**
@@ -1639,11 +1600,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()]);
     }
 
     /**
@@ -1654,14 +1614,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;
@@ -1689,11 +1649,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()]);
     }
 
     /**
@@ -1707,11 +1666,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()]);
     }
 
     /**
@@ -1725,11 +1683,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()]);
     }
 
     /**
@@ -1754,20 +1711,15 @@
     /**
      * 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);
     }
 
     /**
@@ -1777,6 +1729,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);
     }
@@ -1838,14 +1791,14 @@
      * @since Ant 1.8.0
      */
     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()]);
@@ -1863,14 +1816,14 @@
      * @since Ant 1.8.0
      */
     private boolean causesIllegalSymlinkLoop(final String dirName, final File parent,
-                                             final LinkedList<String> directoryNamesFollowed) {
+                                             final Deque<String> directoryNamesFollowed) {
         try {
             if (directoryNamesFollowed.size() >= maxLevelsOfSymlinks
-                && CollectionUtils.frequency(directoryNamesFollowed, dirName)
+                && Collections.frequency(directoryNamesFollowed, dirName)
                    >= maxLevelsOfSymlinks
                 && SYMLINK_UTILS.isSymbolicLink(parent, dirName)) {
 
-                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);
@@ -1882,18 +1835,17 @@
                         f = FILE_UTILS.resolveFile(parent, relPath + dir);
                         files.add(f.getCanonicalPath());
                         if (files.size() > maxLevelsOfSymlinks
-                            && CollectionUtils.frequency(files, target)
+                            && 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 2b31e43..5368042 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());
     }
 
     /**
@@ -1533,7 +1533,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 +1602,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/Main.java b/src/main/org/apache/tools/ant/Main.java
index bbaadd0..1ad6277 100644
--- a/src/main/org/apache/tools/ant/Main.java
+++ b/src/main/org/apache/tools/ant/Main.java
@@ -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
@@ -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);
@@ -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 17f2467..23799bc 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]);
             }
@@ -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[] root, 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 < root.length; i++) {
-            final String st = (state.get(root[i]));
+            final String st = state.get(root[i]);
             if (st == null) {
                 tsort(root[i], targetTable, state, visiting, ret);
             } else if (st == VISITING) {
@@ -1840,7 +1834,7 @@
                     + root[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 < root.length; j++) {
             buf.append((j == 0) ? " `" : ", `").append(root[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);
@@ -2035,7 +2029,7 @@
      * @since Ant 1.8.1
      */
     public Map<String, Object> getCopyOfReferences() {
-        return new HashMap<String, Object>(references);
+        return new HashMap<>(references);
     }
 
     /**
@@ -2488,6 +2482,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 ad92a31..451dbed 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 ab39368..0b51946 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.
@@ -292,7 +288,7 @@
      * @see org.apache.tools.ant.ProjectHelperRepository#getHelpers()
      */
     public static ProjectHelper getProjectHelper() {
-        return (ProjectHelper) ProjectHelperRepository.getInstance().getHelpers().next();
+        return ProjectHelperRepository.getInstance().getHelpers().next();
     }
 
     /**
@@ -496,7 +492,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 e370a54..a11c05a 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;
 
@@ -298,40 +299,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 1dbb280..84121c9 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);
@@ -1129,7 +1116,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 0aafccb..8e54d8c 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.
@@ -303,17 +302,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();
             }
         }
@@ -335,7 +334,7 @@
      */
     public synchronized Hashtable<String, Object> getAttributeMap() {
         return (attributeMap == null)
-            ? EMPTY_HASHTABLE : new Hashtable<String, Object>(attributeMap);
+            ? EMPTY_HASHTABLE : new Hashtable<>(attributeMap);
     }
 
     /**
@@ -356,7 +355,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);
     }
 
@@ -378,7 +377,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);
     }
 
@@ -497,7 +496,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);
@@ -509,8 +508,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());
                 }
@@ -528,7 +527,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;
@@ -538,7 +537,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 dymanic attribute task
                         // Do nothing
@@ -590,7 +589,7 @@
 
         // Children (this is a shadow of UnknownElement#children)
         if (r.children != null) {
-            ArrayList<RuntimeConfigurable> newChildren = new ArrayList<RuntimeConfigurable>();
+            List<RuntimeConfigurable> newChildren = new ArrayList<>();
             newChildren.addAll(r.children);
             if (children != null) {
                 newChildren.addAll(children);
@@ -601,7 +600,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 796b7e1..dba7e25 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);
+        });
     }
 
     /**
@@ -331,7 +336,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);
+        });
     }
 
     /**
@@ -390,6 +400,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;
     }
@@ -491,42 +502,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 3a3001f..8a22f35 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 e8e7444..70ccd80 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("Configurationerror on <");
+            StringBuilder sb = new StringBuilder("Configurationerror 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 15770c2..7a4a60a 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>();
+            List<UnknownElement> newChildren = new ArrayList<>();
             newChildren.addAll(u.children);
             if (children != null) {
                 newChildren.addAll(children);
@@ -506,7 +504,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();
@@ -612,7 +609,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)) {
@@ -637,7 +634,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;
@@ -655,10 +652,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 086123e..3a9848e 100644
--- a/src/main/org/apache/tools/ant/XmlLogger.java
+++ b/src/main/org/apache/tools/ant/XmlLogger.java
@@ -32,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;
@@ -109,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.
@@ -134,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();
@@ -164,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));
@@ -180,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 = Files.newOutputStream(Paths.get(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;
     }
@@ -218,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:
@@ -236,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();
@@ -253,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);
@@ -290,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();
@@ -313,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);
@@ -355,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;
@@ -372,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) {
@@ -379,7 +374,7 @@
         }
         Element messageElement = doc.createElement(MESSAGE_TAG);
 
-        String name = "debug";
+        String name;
         switch (priority) {
             case Project.MSG_ERR:
                 name = "error";
@@ -433,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;
     }
@@ -443,6 +439,7 @@
      *
      * @param output the output PrintStream.
      */
+    @Override
     public void setOutputPrintStream(PrintStream output) {
         this.outStream = new PrintStream(output, true);
     }
@@ -453,6 +450,7 @@
      * @param emacsMode true if logger should produce emacs compatible
      *        output
      */
+    @Override
     public void setEmacsMode(boolean emacsMode) {
     }
 
@@ -463,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 a848ed1..66eb96f 100644
--- a/src/main/org/apache/tools/ant/dispatch/DispatchTask.java
+++ b/src/main/org/apache/tools/ant/dispatch/DispatchTask.java
@@ -37,6 +37,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 1a7c1f9..852a920 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/util/ChainReaderHelper.java b/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
index f176c33..9ad2f3d 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
+     * @param primaryReader
+     * @param filterChains
+     */
+    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
+     * @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
+     * @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
+     * @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
+     * @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
+     * @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 int filtersCount = finalFilters.size();
-
-        if (filtersCount > 0) {
+        final List<Object> finalFilters =
+            filterChains.stream().map(FilterChain::getFilterReaders)
+                .flatMap(Collection::stream).collect(Collectors.toList());
+        
+        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/ProjectHelper2.java b/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
index 1fce8bc..313763a 100644
--- a/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
+++ b/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
@@ -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;
@@ -256,7 +259,7 @@
                     zf = new ZipFile(org.apache.tools.ant.launch.Locator
                                      .fromJarURI(uri), "UTF-8");
                     inputStream =
-                        zf.getInputStream(zf.getEntry(uri.substring(pling + 1)));
+                        zf.getInputStream(zf.getEntry(uri.substring(pling + 2)));
                 } else {
                     URLConnection conn = url.openConnection();
                     conn.setUseCaches(false);
@@ -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);
@@ -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,6 +664,7 @@
          * @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 (name.equals("project")
@@ -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;
@@ -849,6 +861,7 @@
          *            <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"))
@@ -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;
@@ -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();
@@ -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/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/launch/Launcher.java b/src/main/org/apache/tools/ant/launch/Launcher.java
index 534bbfb..e41628b 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}
@@ -127,6 +116,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.
@@ -156,7 +152,7 @@
                 }
             }
 
-            final URL url = Locator.fileToURL(element);
+            final URL url = new URL(element.toURI().toASCIIString());
             if (launchDiag) {
                 System.out.println("adding library URL: " + url);
             }
@@ -193,44 +189,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 {
@@ -262,8 +259,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);
@@ -278,12 +275,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(
@@ -320,7 +317,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);
@@ -389,7 +386,7 @@
             systemJars.length);
 
         if (toolsJar != null) {
-            jars[jars.length - 1] = Locator.fileToURL(toolsJar);
+            jars[jars.length - 1] = new URL(toolsJar.toURI().toASCIIString());
         }
         return jars;
     }
@@ -407,8 +404,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 2e8c37d..436d5f0 100644
--- a/src/main/org/apache/tools/ant/launch/Locator.java
+++ b/src/main/org/apache/tools/ant/launch/Locator.java
@@ -19,7 +19,6 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FilenameFilter;
 import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -27,6 +26,7 @@
 import java.text.CharacterIterator;
 import java.text.StringCharacterIterator;
 import java.util.Locale;
+import java.util.stream.Stream;
 
 // CheckStyle:LineLengthCheck OFF - urls are long!
 /**
@@ -95,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.
@@ -130,7 +125,7 @@
         if (c == null) {
             c = Locator.class.getClassLoader();
         }
-        URL url = null;
+        URL url;
         if (c == null) {
             url = ClassLoader.getSystemResource(resource);
         } else {
@@ -141,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.
      *
@@ -234,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);
         }
@@ -330,7 +323,7 @@
         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
@@ -339,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]);
@@ -353,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(StandardCharsets.UTF_8);
+            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;
@@ -466,7 +457,7 @@
      */
     public static URL[] getLocationURLs(File location)
          throws MalformedURLException {
-        return getLocationURLs(location, new String[]{".jar"});
+        return getLocationURLs(location, ".jar");
     }
 
     /**
@@ -484,7 +475,7 @@
      *            formed.
      */
     public static URL[] getLocationURLs(File location,
-                                        final String[] extensions)
+                                        final String... extensions)
          throws MalformedURLException {
         URL[] urls = new URL[0];
 
@@ -503,22 +494,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 0e29b40..9370f87 100644
--- a/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java
+++ b/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java
@@ -213,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 32474ee..2890b82 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 String categoryString = PROJECT_LOG;
         final Log log = getLog(categoryString, null);
@@ -112,6 +113,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void buildFinished(final BuildEvent event) {
         if (initialized) {
             final String categoryString = PROJECT_LOG;
@@ -130,6 +132,7 @@
      * @see BuildListener#targetStarted
      */
     /** {@inheritDoc}. */
+    @Override
     public void targetStarted(final BuildEvent event) {
         if (initialized) {
             final Log log = getLog(TARGET_LOG,
@@ -145,6 +148,7 @@
      * @see BuildListener#targetFinished
      */
     /** {@inheritDoc}. */
+    @Override
     public void targetFinished(final BuildEvent event) {
         if (initialized) {
             final String targetName = event.getTarget().getName();
@@ -164,6 +168,7 @@
      * @see BuildListener#taskStarted
      */
     /** {@inheritDoc}. */
+    @Override
     public void taskStarted(final BuildEvent event) {
         if (initialized) {
             final Task task = event.getTask();
@@ -186,6 +191,7 @@
      * @see BuildListener#taskFinished
      */
     /** {@inheritDoc}. */
+    @Override
     public void taskFinished(final BuildEvent event) {
         if (initialized) {
             final Task task = event.getTask();
@@ -215,16 +221,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 {
@@ -300,6 +306,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
     }
@@ -308,6 +315,7 @@
      * Set the output print stream.
      * @param output the output stream
      */
+    @Override
     public void setOutputPrintStream(final PrintStream output) {
         this.out = output;
     }
@@ -317,6 +325,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
     }
@@ -325,6 +334,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 829f118..8210228 100644
--- a/src/main/org/apache/tools/ant/listener/Log4jListener.java
+++ b/src/main/org/apache/tools/ant/listener/Log4jListener.java
@@ -33,14 +33,14 @@
  */
 public class Log4jListener implements BuildListener {
 
-    /** Indicates if the listener was initialized. */
-    private final boolean initialized;
-
     /**
      * log category we log into
      */
     public static final String LOG_ANT = "org.apache.tools.ant";
 
+    /** Indicates if the listener was initialized. */
+    private final boolean initialized;
+
     /**
      * Construct the listener and make sure there is a valid appender.
      */
@@ -57,6 +57,7 @@
      * @see BuildListener#buildStarted
      */
     /** {@inheritDoc}. */
+    @Override
     public void buildStarted(final BuildEvent event) {
         if (initialized) {
             final Logger log = Logger.getLogger(Project.class.getName());
@@ -68,6 +69,7 @@
      * @see BuildListener#buildFinished
      */
     /** {@inheritDoc}. */
+    @Override
     public void buildFinished(final BuildEvent event) {
         if (initialized) {
             final Logger log = Logger.getLogger(Project.class.getName());
@@ -83,6 +85,7 @@
      * @see BuildListener#targetStarted
      */
     /** {@inheritDoc}. */
+    @Override
     public void targetStarted(final BuildEvent event) {
         if (initialized) {
             final Logger log = Logger.getLogger(Target.class.getName());
@@ -94,6 +97,7 @@
      * @see BuildListener#targetFinished
      */
     /** {@inheritDoc}. */
+    @Override
     public void targetFinished(final BuildEvent event) {
         if (initialized) {
             final String targetName = event.getTarget().getName();
@@ -111,6 +115,7 @@
      * @see BuildListener#taskStarted
      */
     /** {@inheritDoc}. */
+    @Override
     public void taskStarted(final BuildEvent event) {
         if (initialized) {
             final Task task = event.getTask();
@@ -123,6 +128,7 @@
      * @see BuildListener#taskFinished
      */
     /** {@inheritDoc}. */
+    @Override
     public void taskFinished(final BuildEvent event) {
         if (initialized) {
             final Task task = event.getTask();
@@ -140,6 +146,7 @@
      * @see BuildListener#messageLogged
      */
     /** {@inheritDoc}. */
+    @Override
     public void messageLogged(final BuildEvent event) {
         if (initialized) {
             Object categoryObject = event.getTask();
diff --git a/src/main/org/apache/tools/ant/listener/MailLogger.java b/src/main/org/apache/tools/ant/listener/MailLogger.java
index 25f5bab..cff2073 100644
--- a/src/main/org/apache/tools/ant/listener/MailLogger.java
+++ b/src/main/org/apache/tools/ant/listener/MailLogger.java
@@ -24,10 +24,12 @@
 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;
@@ -97,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
@@ -168,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 {
@@ -310,6 +313,7 @@
      *
      * @param message the message being logger
      */
+    @Override
     protected void log(String message) {
         buffer.append(message).append(StringUtils.LINE_SEP);
     }
@@ -327,7 +331,7 @@
      * @exception  Exception  thrown if no default value is specified and the
      *      property is not present in properties.
      */
-    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);
@@ -356,7 +360,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()) {
@@ -391,7 +395,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) {
@@ -400,7 +404,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());
@@ -417,25 +421,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/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 8762ddc..e5fa4dd 100644
--- a/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java
@@ -55,10 +55,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.
@@ -149,11 +149,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
@@ -385,11 +380,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);
         }
@@ -397,16 +393,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);
@@ -421,24 +414,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();
     }
 
     /**
@@ -449,24 +442,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;
     }
 
     /**
@@ -478,10 +471,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;
@@ -502,11 +493,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;
@@ -535,7 +523,6 @@
      * @return the port of CVS
      */
     public int getPort() {
-
         return this.port;
     }
 
@@ -553,7 +540,6 @@
      * @return password file
      */
     public File getPassFile() {
-
         return this.passFile;
     }
 
@@ -576,7 +562,6 @@
      * @return directory where the checked out files should be placed
      */
     public File getDest() {
-
         return this.dest;
     }
 
@@ -595,7 +580,6 @@
      * @return package/module
      */
     public String getPackage() {
-
         return this.cvsPackage;
     }
     /**
@@ -613,7 +597,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);
         }
@@ -649,7 +633,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);
         }
@@ -695,7 +679,6 @@
         reallyquiet = q;
     }
 
-
     /**
      * If true, report only and don't change any files.
      *
@@ -794,7 +777,7 @@
      * @param c command line which should be removed
      */
     protected void removeCommandline(Commandline c) {
-        vecCommandlines.removeElement(c);
+        commandlines.remove(c);
     }
 
     /**
@@ -818,9 +801,9 @@
         }
         this.configureCommandline(c);
         if (insertAtStart) {
-            vecCommandlines.insertElementAt(c, 0);
+            commandlines.add(0, c);
         } else {
-            vecCommandlines.addElement(c);
+            commandlines.add(c);
         }
     }
 
@@ -854,13 +837,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 c93173b..6fda283 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 88fddf8..b121ade 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Ant.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Ant.java
@@ -22,11 +22,13 @@
 import java.io.IOException;
 import java.io.PrintStream;
 import java.lang.reflect.Method;
+import java.util.HashMap;
 import java.nio.file.Files;
-import java.util.Enumeration;
 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;
@@ -164,6 +166,7 @@
     /**
      * Creates a Project instance for the project to call.
      */
+    @Override
     public void init() {
         newProject = getProject().createSubProject();
         newProject.setJavaVersionProperty();
@@ -195,11 +198,11 @@
 
         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 {
@@ -246,6 +249,7 @@
      * @see Task#handleOutput(String)
      * @since Ant 1.5
      */
+    @Override
     public void handleOutput(String outputToHandle) {
         if (newProject != null) {
             newProject.demuxOutput(outputToHandle, false);
@@ -268,6 +272,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) {
@@ -284,6 +289,7 @@
      * @see Task#handleFlush(String)
      * @since Ant 1.5.2
      */
+    @Override
     public void handleFlush(String toFlush) {
         if (newProject != null) {
             newProject.demuxFlush(toFlush, false);
@@ -301,6 +307,7 @@
      * @see Task#handleErrorOutput(String)
      * @since Ant 1.5
      */
+    @Override
     public void handleErrorOutput(String errorOutputToHandle) {
         if (newProject != null) {
             newProject.demuxOutput(errorOutputToHandle, true);
@@ -317,6 +324,7 @@
      * @see Task#handleErrorFlush(String)
      * @since Ant 1.5.2
      */
+    @Override
     public void handleErrorFlush(String errorOutputToFlush) {
         if (newProject != null) {
             newProject.demuxFlush(errorOutputToFlush, true);
@@ -330,10 +338,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();
 
@@ -366,7 +375,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);
 
@@ -377,14 +386,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());
                 }
             }
 
@@ -395,7 +404,7 @@
                     ex, getLocation());
             }
 
-            if (locals.size() == 0) {
+            if (locals.isEmpty()) {
                 String defaultTarget = newProject.getDefaultTarget();
                 if (defaultTarget != null) {
                     locals.add(defaultTarget);
@@ -409,30 +418,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 {
@@ -484,10 +488,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 {
@@ -495,12 +499,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);
@@ -517,14 +518,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 '"
@@ -544,7 +544,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;
@@ -576,32 +576,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);
@@ -617,29 +617,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;
             }
-        }
+        });
     }
 
     /**
@@ -671,7 +673,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);
@@ -697,7 +699,7 @@
         Property p = new Property(true, getProject());
         p.setProject(getNewProject());
         p.setTaskName("property");
-        properties.addElement(p);
+        properties.add(p);
         return p;
     }
 
@@ -707,7 +709,7 @@
      * @param ref <code>Reference</code> to add.
      */
     public void addReference(Reference ref) {
-        references.addElement(ref);
+        references.add(ref);
     }
 
     /**
@@ -721,7 +723,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);
@@ -734,7 +736,7 @@
      * @since Ant 1.6
      */
     public void addPropertyset(PropertySet ps) {
-        propertySets.addElement(ps);
+        propertySets.add(ps);
     }
 
     /**
@@ -760,14 +762,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;
 
         /**
@@ -823,10 +821,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 eeaab53..8dd7ff1 100644
--- a/src/main/org/apache/tools/ant/taskdefs/AntStructure.java
+++ b/src/main/org/apache/tools/ant/taskdefs/AntStructure.java
@@ -25,10 +25,15 @@
 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;
@@ -122,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 "
@@ -187,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());
         }
 
 
@@ -203,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(tasks.stream().collect(
+                Collectors.joining(" | ", "<!ENTITY % tasks \"", "\">")));
 
-            out.println("");
+            out.println(types.stream().collect(
+                Collectors.joining(" | ", "<!ENTITY % types \"", "\">")));
+
+            out.println();
 
             out.print("<!ELEMENT project (target | extension-point | ");
             out.print(TASKS);
@@ -249,6 +238,7 @@
         /**
          * Prints the definition for the target element.
          */
+        @Override
         public void printTargetDecl(final PrintWriter out) {
             out.print("<!ELEMENT target (");
             out.print(TASKS);
@@ -282,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) {
 
@@ -290,7 +281,7 @@
             }
             visited.put(name, "");
 
-            IntrospectionHelper ih = null;
+            IntrospectionHelper ih;
             try {
                 ih = IntrospectionHelper.getHelper(p, element);
             } catch (final Throwable t) {
@@ -302,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");
@@ -315,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");
 
@@ -362,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 ");
@@ -393,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 ");
@@ -419,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..24489cd 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/Available.java b/src/main/org/apache/tools/ant/taskdefs/Available.java
index f4919a1..6b37116 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);
                 }
@@ -488,12 +494,13 @@
      */
     public static class FileDir extends EnumeratedAttribute {
 
-        private static final String[] VALUES = {"file", "dir"};
+        private static final String[] VALUES = { "file", "dir" };
 
         /**
          * @see EnumeratedAttribute#getValues
          */
         /** {@inheritDoc}. */
+        @Override
         public String[] getValues() {
             return VALUES;
         }
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 45ad9ae..a78729d 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,11 +76,9 @@
         final ProjectHelper helper = (ProjectHelper) getProject().getReference(
                 ProjectHelper.PROJECTHELPER_REFERENCE);
 
-        for (final Iterator<String> itTarget = targets.iterator(); itTarget.hasNext();) {
-            helper.getExtensionStack().add(
-                    new String[] {extensionPoint, itTarget.next(),
-                                            onMissingExtensionPoint.name()});
+        for (String target : targets) {
+            helper.getExtensionStack().add(new String[] { extensionPoint,
+                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 30552f7..226ba7a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/BuildNumber.java
+++ b/src/main/org/apache/tools/ant/taskdefs/BuildNumber.java
@@ -25,7 +25,6 @@
 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;
 
@@ -40,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.
      */
@@ -55,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.
@@ -66,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();
@@ -85,26 +81,12 @@
             String.valueOf(buildNumber + 1));
 
         // Write the properties file back out
-        OutputStream output = null;
 
-        try {
-            output = Files.newOutputStream(myFile.toPath());
-
-            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;
         }
 
@@ -113,7 +95,6 @@
             String.valueOf(buildNumber));
     }
 
-
     /**
      * Utility method to retrieve build number from properties object.
      *
@@ -130,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
      */
-    private Properties loadProperties()
-         throws BuildException {
-        InputStream input = null;
-
-        try {
+    private Properties loadProperties() throws BuildException {
+        try (InputStream input = Files.newInputStream(myFile.toPath())) {
             final Properties properties = new Properties();
-
-            input = Files.newInputStream(myFile.toPath());
             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.
      *
@@ -182,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 af24504..b15c55d 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 f30d8d7..3531b20 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Checksum.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Checksum.java
@@ -71,6 +71,7 @@
             super.add(u);
             super.add(Type.FILE);
         }
+        @Override
         public void add(ResourceCollection rc) {
             u.add(rc);
         }
@@ -110,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.
      */
@@ -138,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
      */
@@ -294,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));
         }
     }
 
@@ -311,6 +312,7 @@
      * false otherwise.
      * @throws BuildException on error
      */
+    @Override
     public boolean eval() throws BuildException {
         isCondition = true;
         return validateAndExecute();
@@ -386,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 {
@@ -463,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);
     }
 
     /**
@@ -498,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
@@ -506,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()) {
@@ -550,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) {
@@ -582,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);
         }
@@ -630,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);
         }
     }
 
@@ -651,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;
     }
@@ -679,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.
@@ -699,15 +684,16 @@
          * @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};
+            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 99d47a1..e13d111 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 afffcef..27b3132 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Concat.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Concat.java
@@ -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;
@@ -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;
     }
@@ -752,11 +759,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";
         }
     }
@@ -785,6 +792,7 @@
     /**
      * Execute the concat task.
      */
+    @Override
     public void execute() {
         validate();
         if (binary && dest == null) {
@@ -796,7 +804,7 @@
             log(dest + " is up-to-date.", Project.MSG_VERBOSE);
             return;
         }
-        if (c.size() == 0 && ignoreEmpty) {
+        if (c.isEmpty() && ignoreEmpty) {
             return;
         }
         try {
@@ -815,15 +823,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;
     }
@@ -832,6 +844,7 @@
      * Implement ResourceCollection.
      * @return false.
      */
+    @Override
     public boolean isFilesystemOnly() {
         return false;
     }
@@ -852,8 +865,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(
@@ -899,8 +911,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();
@@ -919,12 +932,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()));
     }
 
     /**
@@ -934,7 +943,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 2394b8f..3c08279 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;
@@ -474,18 +475,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) {
@@ -493,12 +493,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());
 
@@ -574,7 +573,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
@@ -645,8 +644,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);
@@ -672,7 +672,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.");
         }
@@ -686,36 +686,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) {
@@ -811,34 +811,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.");
                 }
             }
 
@@ -861,7 +855,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());
@@ -870,9 +864,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;
@@ -916,8 +908,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 "
@@ -947,7 +939,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());
@@ -1026,7 +1018,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));
@@ -1085,7 +1077,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 e4e3ea3..de4c118 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,8 +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};
+            return new String[] { POLICY_FAIL, POLICY_REPORT, POLICY_IGNORE,
+                POLICY_FAILALL };
         }
     }
 
@@ -138,8 +141,9 @@
          * get the values
          * @return an array of the allowed values for this attribute.
          */
+        @Override
         public String[] getValues() {
-            return new String[] {"properties", "xml"};
+            return new String[] { "properties", "xml" };
         }
     }
 
@@ -202,6 +206,7 @@
      *
      * @exception BuildException if an error occurs
      */
+    @Override
     public void execute() throws BuildException {
         ClassLoader al = createLoader();
 
@@ -223,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) {
@@ -263,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);
                     }
                 }
             }
@@ -290,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;
@@ -391,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);
@@ -401,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);
         }
     }
 
@@ -559,7 +555,6 @@
         this.adaptToClass = adaptToClass;
     }
 
-
     /**
      * Add a definition using the attributes of Definer
      *
@@ -601,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) {
@@ -633,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 6c34ccf..ffdf9a8 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Delete.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Delete.java
@@ -19,6 +19,7 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Iterator;
@@ -79,33 +80,43 @@
 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 SymbolicLinkUtils SYMLINK_UTILS =
+        SymbolicLinkUtils.getSymbolicLinkUtils();
 
     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 +128,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 +183,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 +193,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.
@@ -212,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);
     }
@@ -239,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();
@@ -248,6 +256,7 @@
      * add a name entry on the include files list
      * @return an NameEntry object to be configured
      */
+    @Override
     public PatternSet.NameEntry createIncludesFile() {
         usedMatchingTask = true;
         return super.createIncludesFile();
@@ -257,6 +266,7 @@
      * add a name entry on the exclude list
      * @return an NameEntry object to be configured
      */
+    @Override
     public PatternSet.NameEntry createExclude() {
         usedMatchingTask = true;
         return super.createExclude();
@@ -266,6 +276,7 @@
      * add a name entry on the include files list
      * @return an NameEntry object to be configured
      */
+    @Override
     public PatternSet.NameEntry createExcludesFile() {
         usedMatchingTask = true;
         return super.createExcludesFile();
@@ -275,6 +286,7 @@
      * add a set of patterns
      * @return PatternSet object to be configured
      */
+    @Override
     public PatternSet createPatternSet() {
         usedMatchingTask = true;
         return super.createPatternSet();
@@ -286,6 +298,7 @@
      *
      * @param includes the string containing the include patterns
      */
+    @Override
     public void setIncludes(String includes) {
         usedMatchingTask = true;
         super.setIncludes(includes);
@@ -297,6 +310,7 @@
      *
      * @param excludes the string containing the exclude patterns
      */
+    @Override
     public void setExcludes(String excludes) {
         usedMatchingTask = true;
         super.setExcludes(excludes);
@@ -309,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);
@@ -320,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);
@@ -331,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);
@@ -342,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);
@@ -352,6 +370,7 @@
      *
      * @param followSymlinks whether or not symbolic links should be followed
      */
+    @Override
     public void setFollowSymlinks(boolean followSymlinks) {
         usedMatchingTask = true;
         super.setFollowSymlinks(followSymlinks);
@@ -371,6 +390,7 @@
      * add a "Select" selector entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addSelector(SelectSelector selector) {
         usedMatchingTask = true;
         super.addSelector(selector);
@@ -380,6 +400,7 @@
      * add an "And" selector entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addAnd(AndSelector selector) {
         usedMatchingTask = true;
         super.addAnd(selector);
@@ -389,6 +410,7 @@
      * add an "Or" selector entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addOr(OrSelector selector) {
         usedMatchingTask = true;
         super.addOr(selector);
@@ -398,6 +420,7 @@
      * add a "Not" selector entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addNot(NotSelector selector) {
         usedMatchingTask = true;
         super.addNot(selector);
@@ -407,6 +430,7 @@
      * add a "None" selector entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addNone(NoneSelector selector) {
         usedMatchingTask = true;
         super.addNone(selector);
@@ -416,6 +440,7 @@
      * add a majority selector entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addMajority(MajoritySelector selector) {
         usedMatchingTask = true;
         super.addMajority(selector);
@@ -425,6 +450,7 @@
      * add a selector date entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addDate(DateSelector selector) {
         usedMatchingTask = true;
         super.addDate(selector);
@@ -434,6 +460,7 @@
      * add a selector size entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addSize(SizeSelector selector) {
         usedMatchingTask = true;
         super.addSize(selector);
@@ -443,6 +470,7 @@
      * add a selector filename entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addFilename(FilenameSelector selector) {
         usedMatchingTask = true;
         super.addFilename(selector);
@@ -452,6 +480,7 @@
      * add an extended selector entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addCustom(ExtendSelector selector) {
         usedMatchingTask = true;
         super.addCustom(selector);
@@ -461,6 +490,7 @@
      * add a contains selector entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addContains(ContainsSelector selector) {
         usedMatchingTask = true;
         super.addContains(selector);
@@ -470,6 +500,7 @@
      * add a present selector entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addPresent(PresentSelector selector) {
         usedMatchingTask = true;
         super.addPresent(selector);
@@ -479,6 +510,7 @@
      * add a depth selector entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addDepth(DepthSelector selector) {
         usedMatchingTask = true;
         super.addDepth(selector);
@@ -488,6 +520,7 @@
      * add a depends selector entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addDepend(DependSelector selector) {
         usedMatchingTask = true;
         super.addDepend(selector);
@@ -497,6 +530,7 @@
      * add a regular expression selector entry on the selector list
      * @param selector the selector to be added
      */
+    @Override
     public void addContainsRegexp(ContainsRegexpSelector selector) {
         usedMatchingTask = true;
         super.addContainsRegexp(selector);
@@ -507,6 +541,7 @@
      * @param selector the selector to add
      * @since ant 1.6
      */
+    @Override
     public void addModified(ModifiedSelector selector) {
         usedMatchingTask = true;
         super.addModified(selector);
@@ -517,6 +552,7 @@
      * @param selector the selector to be added
      * @since Ant 1.6
      */
+    @Override
     public void add(FileSelector selector) {
         usedMatchingTask = true;
         super.add(selector);
@@ -526,21 +562,22 @@
      * Delete the file(s).
      * @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
@@ -548,8 +585,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());
 
@@ -610,11 +647,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();
@@ -634,12 +671,15 @@
                 // iterating, capture the results now and store them
                 final String[] files = ds.getIncludedFiles();
                 resourcesToDelete.add(new ResourceCollection() {
+                        @Override
                         public boolean isFilesystemOnly() {
                             return true;
                         }
+                        @Override
                         public int size() {
                             return files.length;
                         }
+                        @Override
                         public Iterator<Resource> iterator() {
                             return new FileResourceIterator(getProject(),
                                                             fsDir, files);
@@ -656,7 +696,7 @@
                     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
@@ -826,7 +866,7 @@
     private boolean isDanglingSymlink(File f) {
         try {
             return SYMLINK_UTILS.isDanglingSymbolicLink(f);
-        } catch (java.io.IOException e) {
+        } catch (IOException e) {
             log("Error while trying to detect " + f.getAbsolutePath()
                 + " as broken symbolic link. " + e.getMessage(),
                 quiet ? Project.MSG_VERBOSE : verbosity);
diff --git a/src/main/org/apache/tools/ant/taskdefs/DependSet.java b/src/main/org/apache/tools/ant/taskdefs/DependSet.java
index dc42beb..ecc8ac3 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;
         }
@@ -190,6 +193,7 @@
      * Execute the task.
      * @throws BuildException if errors occur.
      */
+    @Override
     public void execute() throws BuildException {
         if (sources == null) {
           throw new BuildException(
@@ -200,12 +204,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();
@@ -244,7 +247,7 @@
             logMissing(missingSources, "source");
             return false;
         }
-        Resource newestSource = (Resource) getNewest(sources);
+        Resource newestSource = getNewest(sources);
         logWithModificationTime(newestSource, "newest source");
         return oldestTarget.getLastModified() >= newestSource.getLastModified();
     }
@@ -262,7 +265,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 5873ab7..fa0e457 100644
--- a/src/main/org/apache/tools/ant/taskdefs/EchoXML.java
+++ b/src/main/org/apache/tools/ant/taskdefs/EchoXML.java
@@ -113,24 +113,26 @@
         public NamespacePolicy(String s) {
             setValue(s);
         }
+
         /** {@inheritDoc}. */
         @Override
         public String[] getValues() {
-            return new String[] {IGNORE, ELEMENTS, ALL};
+            return new String[] { IGNORE, ELEMENTS, ALL };
         }
 
         public DOMElementWriter.XmlNamespacePolicy getPolicy() {
             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 dd93978..6ed6d90 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()));
     }
 
     /**
@@ -167,8 +167,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;
     }
@@ -191,8 +190,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;
@@ -205,8 +204,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;
@@ -484,6 +483,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()) {
@@ -633,9 +633,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();
@@ -643,9 +642,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();
@@ -672,9 +670,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 956309a..7bf9d04 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());
         }
@@ -194,17 +194,18 @@
     private static String[] getProcEnvCommand() {
         if (Os.isFamily("os/2")) {
             // OS/2 - use same mechanism as Windows 2000
-            return new String[] {"cmd", "/c", "set"};
-        } else if (Os.isFamily("windows")) {
+            return new String[] { "cmd", "/c", "set" };
+        }
+        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"};
+                return new String[] { "command.com", "/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")) {
-            // 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("netware") || Os.isFamily("os/400")) {
+            // rely on PATH
+            return new String[] { "env" };
+        }
+        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 casiness 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 b36f2fe..e034cea 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;
@@ -318,7 +321,7 @@
         exe.setVMLauncher(true);
         File vmsJavaOptionFile = null;
         try {
-            String [] args = new String[command.length - 1];
+            String[] args = new String[command.length - 1];
             System.arraycopy(command, 1, args, 0, command.length - 1);
             vmsJavaOptionFile = JavaEnvUtils.createVmsJavaOptionFile(args);
             //we mark the file to be deleted on exit.
@@ -326,7 +329,7 @@
             //after execution finished, which is much better for long-lived runtimes
             //though spawning complicates things...
             vmsJavaOptionFile.deleteOnExit();
-            String [] vmsCmd = {command[0], "-V", vmsJavaOptionFile.getPath()};
+            String[] vmsCmd = { command[0], "-V", vmsJavaOptionFile.getPath() };
             exe.setCommandline(vmsCmd);
         } catch (IOException e) {
             throw new BuildException("Failed to create a temporary file for \"-V\" switch");
diff --git a/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java b/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java
index 18cbd29..b9decc3 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)
@@ -335,6 +341,7 @@
     /**
      * Set up the I/O Redirector.
      */
+    @Override
     protected void setupRedirector() {
         super.setupRedirector();
         redirector.setAppendProperties(true);
@@ -345,23 +352,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;
                     }
                 }
@@ -373,34 +378,32 @@
                     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
@@ -411,8 +414,8 @@
                         runExecute(exe);
                         haveExecuted = true;
                     }
-                    fileNames.removeAllElements();
-                    baseDirs.removeAllElements();
+                    fileNames.clear();
+                    baseDirs.clear();
                 }
             }
 
@@ -469,12 +472,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;
             }
@@ -524,31 +527,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];
@@ -642,7 +645,7 @@
      * @return the command line in the form of a String[].
      */
     protected String[] getCommandline(String srcFile, File baseDir) {
-        return getCommandline(new String[] {srcFile}, new File[] {baseDir});
+        return getCommandline(new String[] { srcFile }, new File[] { baseDir });
     }
 
     /**
@@ -697,10 +700,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 */) {
@@ -752,7 +753,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 {
@@ -772,12 +773,14 @@
         public static final String FILE = "file";
         /** Dir value */
         public static final String DIR = "dir";
+
         /**
+         * {@inheritDoc}
          * @see EnumeratedAttribute#getValues
          */
-        /** {@inheritDoc}. */
-       public String[] getValues() {
-            return new String[] {FILE, DIR, "both"};
+        @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 f48f248..7d7bfbe 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 6dd3c92..62fc196 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Expand.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Expand.java
@@ -28,6 +28,7 @@
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 import java.util.Vector;
 
@@ -59,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.
@@ -118,14 +120,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) {
@@ -141,13 +144,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()) {
@@ -173,7 +177,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 "
@@ -181,8 +184,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()) {
@@ -200,7 +204,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) {
@@ -208,8 +212,6 @@
                 "Error while expanding " + srcF.getPath()
                 + "\n" + ioe.toString(),
                 ioe);
-        } finally {
-            ZipFile.closeQuietly(zf);
         }
     }
 
@@ -220,8 +222,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.");
     }
 
     /**
@@ -229,13 +231,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
@@ -257,7 +256,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) == '\\')) {
@@ -266,16 +265,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="**"
@@ -350,20 +349,11 @@
                 f.mkdirs();
             } else {
                 byte[] buffer = new byte[BUFFER_SIZE];
-                int length = 0;
-                OutputStream fos = null;
-                try {
-                    fos = Files.newOutputStream(f.toPath());
-
-                    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);
                 }
             }
 
@@ -410,7 +400,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 af2a21f..806c814 100644
--- a/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java
+++ b/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java
@@ -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;
@@ -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"};
+            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"};
+            return new String[] { "asis", "cr", "lf", "crlf", "mac", "unix",
+                "dos" };
         }
     }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/GUnzip.java b/src/main/org/apache/tools/ant/taskdefs/GUnzip.java
index 94f08d7..d0fe4b0 100644
--- a/src/main/org/apache/tools/ant/taskdefs/GUnzip.java
+++ b/src/main/org/apache/tools/ant/taskdefs/GUnzip.java
@@ -19,13 +19,11 @@
 package org.apache.tools.ant.taskdefs;
 
 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
@@ -45,6 +43,7 @@
      * Get the default extension.
      * @return the value ".gz"
      */
+    @Override
     protected String getDefaultExtension() {
         return DEFAULT_EXTENSION;
     }
@@ -52,18 +51,14 @@
     /**
      * Implement the gunzipping.
      */
+    @Override
     protected void extract() {
         if (srcResource.getLastModified() > dest.lastModified()) {
             log("Expanding " + srcResource.getName() + " to "
                         + dest.getAbsolutePath());
-
-            OutputStream out = null;
-            GZIPInputStream zIn = null;
-            InputStream fis = null;
-            try {
-                out = Files.newOutputStream(dest.toPath());
-                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 {
@@ -73,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);
             }
         }
     }
@@ -92,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 4d7be1f..8803647 100644
--- a/src/main/org/apache/tools/ant/taskdefs/GZip.java
+++ b/src/main/org/apache/tools/ant/taskdefs/GZip.java
@@ -19,12 +19,10 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.IOException;
-import java.io.OutputStream;
 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
@@ -39,16 +37,14 @@
     /**
      * perform the GZip compression operation.
      */
+    @Override
     protected void pack() {
-        GZIPOutputStream zOut = null;
-        try {
-            zOut = new GZIPOutputStream(Files.newOutputStream(zipFile.toPath()));
+        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);
         }
     }
 
@@ -63,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 9b92f00..7e79128 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Get.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Get.java
@@ -96,7 +96,7 @@
                            + Main.getShortAntVersion());
 
     // Store headers as key/value pair without duplicate in keyz
-    private Map<String, String> headers = new LinkedHashMap<String, String>();
+    private Map<String, String> headers = new LinkedHashMap<>();
 
     /**
      * Does the work.
@@ -118,7 +118,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);
                     }
@@ -130,11 +130,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;
@@ -288,8 +290,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());
             }
         }
 
@@ -299,9 +301,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()) {
@@ -391,7 +392,6 @@
         useTimestamp = v;
     }
 
-
     /**
      * Username for basic auth.
      *
@@ -566,6 +566,7 @@
         /**
          * begin a download
          */
+        @Override
         public void beginDownload() {
         }
 
@@ -573,12 +574,14 @@
          * tick handler
          *
          */
+        @Override
         public void onTick() {
         }
 
         /**
          * end a download
          */
+        @Override
         public void endDownload() {
         }
     }
@@ -603,6 +606,7 @@
         /**
          * begin a download
          */
+        @Override
         public void beginDownload() {
             dots = 0;
         }
@@ -611,6 +615,7 @@
          * tick handler
          *
          */
+        @Override
         public void onTick() {
             out.print(".");
             if (dots++ > DOTS_PER_LINE) {
@@ -622,6 +627,7 @@
         /**
          * end a download
          */
+        @Override
         public void endDownload() {
             out.println();
             out.flush();
@@ -699,9 +705,8 @@
                 if (ignoreErrors) {
                     log(message, logLevel);
                     return false;
-                } else {
-                    throw new BuildException(message);
                 }
+                throw new BuildException(message);
             }
 
             redirections++;
@@ -711,12 +716,9 @@
                 if (ignoreErrors) {
                     log(message, logLevel);
                     return false;
-                } else {
-                    throw new BuildException(message);
                 }
+                throw new BuildException(message);
             }
-
-
             return true;
         }
 
@@ -749,14 +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);
@@ -804,9 +804,8 @@
                     if (ignoreErrors) {
                         log(message, logLevel);
                         return null;
-                    } else {
-                        throw new BuildException(message);
                     }
+                    throw new BuildException(message);
                 }
             }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/HostInfo.java b/src/main/org/apache/tools/ant/taskdefs/HostInfo.java
index 43a1211..af36afc 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 63adf71..98bf4b3 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);
@@ -123,18 +124,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) {
@@ -142,9 +143,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");
@@ -166,8 +165,6 @@
 
     private void importResource(ProjectHelper helper,
                                 Resource importedResource) {
-        Vector<Object> importStack = helper.getImportStack();
-
         getProject().log("Importing file " + importedResource + " from "
                          + getLocation().getFileName(), Project.MSG_VERBOSE);
 
@@ -178,13 +175,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);
@@ -203,10 +199,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());
@@ -260,9 +256,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;
     }
@@ -274,22 +269,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 ed05131..c7a5ec8 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");
@@ -120,19 +125,21 @@
      * "default", "propertyfile", "greedy", "secure" (since Ant 1.8).
      */
     public static class HandlerType extends EnumeratedAttribute {
-        private static final String[] VALUES = {"default", "propertyfile", "greedy", "secure"};
+        private static final String[] VALUES =
+            { "default", "propertyfile", "greedy", "secure" };
 
         private static final InputHandler[] HANDLERS
-            = {new DefaultInputHandler(),
-               new PropertyFileInputHandler(),
-               new GreedyInputHandler(),
-               new SecureInputHandler()};
+            = { new DefaultInputHandler(),
+                new PropertyFileInputHandler(),
+                new GreedyInputHandler(),
+                new SecureInputHandler() };
 
         /** {@inheritDoc} */
         @Override
         public String[] getValues() {
             return VALUES;
         }
+
         private InputHandler getInputHandler() {
             return HANDLERS[getIndex()];
         }
@@ -193,19 +200,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
      */
@@ -220,7 +221,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);
@@ -234,7 +235,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 2ca6e22..3674586 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.
@@ -342,20 +341,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);
@@ -374,14 +370,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;
         }
-
     }
 
     /**
@@ -395,9 +389,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
@@ -423,13 +417,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",
@@ -449,7 +443,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 7902075..26f844c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Jar.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Jar.java
@@ -28,6 +28,7 @@
 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;
@@ -35,6 +36,8 @@
 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;
-        InputStream fis = null;
-        InputStreamReader isr = null;
-        try {
-            fis = Files.newInputStream(manifestFile.toPath());
-            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,32 +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 {
-            FileUtils.close(zf);
         }
     }
 
     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,
@@ -366,23 +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 {
-            FileUtils.close(zf);
         }
     }
 
@@ -404,7 +383,7 @@
         mergeManifestsMain = config != null && "merge".equals(config.getValue());
 
         if (filesetManifestConfig != null
-            && !filesetManifestConfig.getValue().equals("skip")) {
+            && !"skip".equals(filesetManifestConfig.getValue())) {
 
             doubleFilePass = true;
         }
@@ -449,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);
            }
         }
     }
@@ -491,6 +463,7 @@
      * @throws IOException on I/O errors
      * @throws BuildException on other errors
      */
+    @Override
     protected void initZipOutputStream(ZipOutputStream zOut)
         throws IOException, BuildException {
 
@@ -504,12 +477,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
@@ -598,6 +569,7 @@
      * @throws IOException on I/O errors
      * @throws BuildException on other errors
      */
+    @Override
     protected void finalizeZipOutputStream(ZipOutputStream zOut)
         throws IOException, BuildException {
 
@@ -667,14 +639,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);
         }
     }
 
@@ -690,6 +658,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 {
@@ -703,8 +672,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);
         }
@@ -715,40 +684,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) {
@@ -804,6 +762,7 @@
      *
      * @exception BuildException if it likes
      */
+    @Override
     protected ArchiveState getResourcesToAdd(ResourceCollection[] rcs,
                                              File zipFile,
                                              boolean needsUpdate)
@@ -874,33 +833,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()) {
@@ -915,8 +873,6 @@
                                      + " (" + ioe.getMessage() + ")", ioe,
                                      getLocation());
         } finally {
-            // Close the output stream.
-            FileUtils.close(zOut);
             createEmpty = false;
         }
         return true;
@@ -928,6 +884,7 @@
      *
      * @see Zip#cleanUp
      */
+    @Override
     protected void cleanUp() {
         super.cleanUp();
         checkJarSpec();
@@ -939,7 +896,7 @@
             filesetManifest = null;
             originalManifest = null;
         }
-        rootEntries.removeAllElements();
+        rootEntries.clear();
     }
 
     // CheckStyle:LineLength OFF - Link is too long.
@@ -950,7 +907,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();
@@ -975,11 +932,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());
         }
     }
 
@@ -990,6 +946,7 @@
      *
      * @since 1.44, Ant 1.5
      */
+    @Override
     public void reset() {
         super.reset();
         emptyBehavior = "create";
@@ -1008,8 +965,9 @@
          * 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"};
+            return new String[] { "skip", "merge", "mergewithoutmain" };
         }
     }
 
@@ -1056,9 +1014,7 @@
             writer.println(dir);
         }
 
-        for (String file : files) {
-            writer.println(file);
-        }
+        files.forEach(writer::println);
     }
 
     /**
@@ -1084,39 +1040,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());
     }
 
     /**
@@ -1133,21 +1077,21 @@
         throws IOException {
         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);
@@ -1157,13 +1101,12 @@
     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]});
+                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('\\', '/');
@@ -1179,7 +1122,7 @@
                         name = prefix + name;
                     }
                 }
-                if (name.equalsIgnoreCase(MANIFEST_NAME)) {
+                if (MANIFEST_NAME.equalsIgnoreCase(name)) {
                     manifests[i] = new Resource[] {resources[0][j]};
                     break;
                 }
@@ -1191,11 +1134,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.
@@ -1203,18 +1161,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 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 6e7cee3..0e97f0a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Javac.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Javac.java
@@ -19,7 +19,6 @@
 package org.apache.tools.ant.taskdefs;
 
 import java.io.File;
-import java.io.FileFilter;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.file.Files;
@@ -28,7 +27,6 @@
 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;
@@ -138,7 +136,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;
@@ -162,19 +160,23 @@
     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.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.isJavaVersion(JavaEnvUtils.JAVA_9)) {
+            return JAVAC9;
+        }
+        return CLASSIC;
     }
 
     /**
@@ -1083,8 +1085,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;
     }
@@ -1131,7 +1133,7 @@
      */
     protected void resetFileLists() {
         compileList = new File[0];
-        packageInfos = new HashMap<String, Long>();
+        packageInfos = new HashMap<>();
     }
 
     /**
@@ -1146,8 +1148,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);
@@ -1186,7 +1188,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()) {
@@ -1218,7 +1221,7 @@
         }
 
         if (extensions == null) {
-            extensions = new String[] {"java"};
+            extensions = new String[] { "java" };
         }
 
         // now process the extensions to ensure that they are the
@@ -1297,8 +1300,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;
@@ -1353,13 +1356,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);
         }
     }
 
@@ -1377,9 +1379,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());
                 }
             }
 
@@ -1414,9 +1415,8 @@
                 }
                 if (failOnError) {
                     throw new BuildException(FAIL_MSG, getLocation());
-                } else {
-                    log(FAIL_MSG, Project.MSG_ERR);
                 }
+                log(FAIL_MSG, Project.MSG_ERR);
             }
         }
     }
@@ -1438,9 +1438,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).
@@ -1451,7 +1450,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()));
         }
     }
 
@@ -1461,7 +1460,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));
@@ -1490,7 +1489,7 @@
      * @since 1.9.7
      */
     private static boolean hasPath(final Path path) {
-        return path != null && path.size() > 0;
+        return path != null && !path.isEmpty();
     }
 
     /**
@@ -1524,7 +1523,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++) {
@@ -1547,7 +1546,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));
@@ -1574,7 +1573,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++) {
@@ -1643,26 +1642,26 @@
         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);
     }
 
     /**
@@ -1683,19 +1682,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 ccf1548..62366ad 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Javadoc.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Javadoc.java
@@ -23,22 +23,24 @@
 import java.io.FileNotFoundException;
 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.OutputStream;
 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);
         }
     }
 
@@ -367,7 +368,7 @@
         public String[] getValues() {
             // Protected first so if any GUI tool offers a default
             // based on enum #0, it will be right.
-            return new String[] {"protected", "public", "package", "private"};
+            return new String[] { "protected", "public", "package", "private" };
         }
     }
 
@@ -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);
     }
 
     /**
@@ -1705,7 +1698,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();
@@ -1717,15 +1710,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 {
@@ -1846,25 +1838,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);
         }
@@ -1889,7 +1880,7 @@
         }
 
         if (classpath == null) {
-            classpath = (new Path(getProject())).concatSystemClasspath("last");
+            classpath = new Path(getProject()).concatSystemClasspath("last");
         } else {
             classpath = classpath.concatSystemClasspath("ignore");
         }
@@ -1914,32 +1905,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());
                 }
             }
         }
@@ -1948,7 +1938,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);
@@ -1956,23 +1945,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();
@@ -1980,8 +1966,6 @@
             throw new BuildException(
                 "Error creating or writing temporary file for javadoc options",
                 ex, getLocation());
-        } finally {
-            FileUtils.close(optionsListWriter);
         }
     }
 
@@ -1998,85 +1982,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);
             }
         }
     }
@@ -2098,7 +2075,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);
@@ -2112,36 +2089,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
@@ -2149,26 +2120,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);
                         }
                     }
                 }
@@ -2180,7 +2147,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);
@@ -2208,8 +2175,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);
             }
@@ -2218,10 +2185,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) {
@@ -2238,7 +2205,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, '/');
@@ -2268,9 +2235,8 @@
         }
         if (str.indexOf('\'') == -1) {
             return quoteString(str, '\'');
-        } else {
-            return quoteString(str, '"');
         }
+        return quoteString(str, '"');
     }
 
     private boolean containsWhitespace(final String s) {
@@ -2284,7 +2250,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;
@@ -2332,18 +2298,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");
@@ -2352,7 +2316,7 @@
                 }
             }
             for (final Resource r : rc) {
-                sf.addElement(new SourceFile(r.as(FileProvider.class).getFile()));
+                sf.add(new SourceFile(r.as(FileProvider.class).getFile()));
             }
         }
     }
@@ -2365,10 +2329,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
@@ -2377,51 +2340,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());
@@ -2430,20 +2377,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;
@@ -2451,7 +2392,7 @@
                             dirs[i].replace(File.separatorChar, '.');
                         if (!addedPackages.contains(packageName)) {
                             addedPackages.add(packageName);
-                            pn.addElement(packageName);
+                            pn.add(packageName);
                         }
                     }
                 }
@@ -2476,14 +2417,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
@@ -2516,14 +2456,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 = Files.newInputStream(file.toPath());
         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
@@ -2532,14 +2468,11 @@
             // we need to patch the file!
             final String patchedFileContents = patchContent(fileContents, fixData);
             if (!patchedFileContents.equals(fileContents)) {
-                final OutputStream fos = Files.newOutputStream(file.toPath());
-                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);
                 }
             }
         }
@@ -2598,7 +2531,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..e776b59 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");
         }
     }
 
@@ -247,12 +255,13 @@
 
     /** EnumeratedAttribute operation mode */
     public static class FileMode extends EnumeratedAttribute {
-        static final String[] MODES = new String[] {EACH, ALL}; //NOSONAR
+        static final String[] MODES = new String[] { EACH, ALL }; //NOSONAR
 
         /**
          * 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 4c20c7c..9ff4e6e 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.
@@ -158,6 +158,7 @@
      *
      * @exception BuildException if something goes wrong with the build
      */
+    @Override
     public final void execute() throws BuildException {
         //validation
         if (src == null) {
@@ -171,30 +172,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);
 
@@ -206,9 +198,6 @@
             }
         } catch (final IOException ioe) {
             throw new BuildException("Unable to load file: " + ioe, ioe, getLocation());
-        } finally {
-            FileUtils.close(bis);
-            FileUtils.close(tis);
         }
     }
 
@@ -217,7 +206,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 bc69c06..d25ecb2 100644
--- a/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java
+++ b/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java
@@ -18,9 +18,6 @@
 
 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;
@@ -58,6 +55,7 @@
     /**
      * Stop the log stream handler.
      */
+    @Override
     public void stop() {
         super.stop();
         FileUtils.close(getErr());
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 e23c025..09e252b 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 0d7c05e..f47f461 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 f605bd5..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,8 +108,8 @@
             // 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("/")) {
@@ -146,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;
     }
@@ -159,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 8b459be..85dfd8a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java
@@ -20,11 +20,10 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
+import java.nio.charset.Charset;
 import java.nio.file.Files;
 import java.util.Enumeration;
 
@@ -33,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
@@ -92,8 +90,9 @@
          *
          * @return a String array of the allowed values.
          */
+        @Override
         public String[] getValues() {
-            return new String[] {"update", "replace"};
+            return new String[] { "update", "replace" };
         }
     }
 
@@ -158,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);
             }
         }
     }
@@ -218,6 +219,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");
@@ -228,15 +230,9 @@
         BuildException error = null;
 
         if (manifestFile.exists()) {
-            InputStream fis = null;
-            InputStreamReader isr = null;
-            try {
-                fis = Files.newInputStream(manifestFile.toPath());
-                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
@@ -244,8 +240,6 @@
             } catch (IOException e) {
                 error = new BuildException("Failed to read " + manifestFile,
                                            e, getLocation());
-            } finally {
-                FileUtils.close(isr);
             }
         }
 
@@ -256,7 +250,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) {
@@ -275,11 +269,8 @@
             return;
         }
 
-        PrintWriter w = null;
-        try {
-            OutputStream fos = Files.newOutputStream(manifestFile.toPath());
-            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");
@@ -287,8 +278,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 113ff5e..414a89a 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 7f5d968..47d40e0 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Move.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Move.java
@@ -19,14 +19,12 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.util.Iterator;
 
 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;
 
 /**
@@ -79,6 +77,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     protected void validateAttributes() throws BuildException {
         if (file != null && file.isDirectory()) {
             if ((destFile != null && destDir != null)
@@ -102,12 +101,12 @@
     /**
      * 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 (File fromDir : completeDirMap.keySet()) {
+                File toDir = completeDirMap.get(fromDir);
                 boolean renamed = false;
                 try {
                     log("Attempting to rename dir: " + fromDir + " to " + toDir, verbosity);
@@ -134,14 +133,13 @@
             log("Moving " + moveCount + " file" + ((moveCount == 1) ? "" : "s")
                     + " to " + destDir.getAbsolutePath());
 
-            for (Iterator fromFiles = fileCopyMap.keySet().iterator(); fromFiles.hasNext();) {
-                String fromFile = (String) fromFiles.next();
+            for (String fromFile : fileCopyMap.keySet()) {
                 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 = fileCopyMap.get(fromFile);
                     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);
@@ -166,9 +164,8 @@
 
         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 (String fromDirName : dirCopyMap.keySet()) {
+                String[] toDirNames = dirCopyMap.get(fromDirName);
                 boolean selfMove = false;
                 for (int i = 0; i < toDirNames.length; i++) {
                     if (fromDirName.equals(toDirNames[i])) {
@@ -213,16 +210,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());
             }
         }
     }
@@ -242,9 +238,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,
@@ -254,9 +248,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());
         }
     }
 
@@ -271,8 +264,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)) {
@@ -304,22 +296,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());
         }
     }
 
@@ -343,19 +337,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));
             }
         }
 
@@ -374,7 +370,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 59a998f..67a2dd8 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();
 
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 abbc5fd..3adb05e 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
@@ -170,7 +163,8 @@
          */
         @Override
         public String[] getValues() {
-            return new String[]{"windows", "unix", "netware", "os/2", "tandem"};
+            return new String[] { "windows", "unix", "netware", "os/2",
+                "tandem" };
         }
     }
 
@@ -213,7 +207,7 @@
      */
     public MapEntry createMap() {
         MapEntry entry = new MapEntry();
-        prefixMap.addElement(entry);
+        prefixMap.add(entry);
         return entry;
     }
 
@@ -251,7 +245,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 +287,6 @@
         pathSep = sep;
     }
 
-
     /**
      * Set the default directory separator string;
      * defaults to current JVM {@link java.io.File#separator File.separator}.
@@ -344,8 +337,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 +355,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 +367,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 +412,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 +489,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 c8f33be..ebe73de 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Property.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Property.java
@@ -23,7 +23,6 @@
 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");
         }
     }
 
@@ -460,27 +458,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);
@@ -575,12 +577,8 @@
         log("Loading " + file.getAbsolutePath(), Project.MSG_VERBOSE);
         try {
             if (file.exists()) {
-                InputStream  fis = null;
-                try {
-                    fis = Files.newInputStream(file.toPath());
+                try (InputStream fis = Files.newInputStream(file.toPath())) {
                     loadProperties(props, fis, file.getName().endsWith(".xml"));
-                } finally {
-                    FileUtils.close(fis);
                 }
                 addProperties(props);
             } else {
@@ -599,17 +597,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 {
@@ -642,9 +639,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);
@@ -656,18 +652,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);
+        });
     }
 
     /**
@@ -702,7 +697,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/Replace.java b/src/main/org/apache/tools/ant/taskdefs/Replace.java
index 5090345..4213ef8 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Replace.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Replace.java
@@ -34,6 +34,7 @@
 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;
@@ -69,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;
 
@@ -144,39 +145,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());
                 }
             }
 
@@ -190,14 +186,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 "";
         }
 
         /**
@@ -354,11 +351,12 @@
      * @since 1.7
      */
     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,7 +368,9 @@
             buffer = new char[BUFF_SIZE];
             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();
@@ -393,8 +393,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;
             }
@@ -406,6 +405,7 @@
          * Closes the file.
          * @throws IOException When the file cannot be closed.
          */
+        @Override
         public void close() throws IOException {
             is.close();
         }
@@ -430,7 +430,9 @@
         FileOutput(File out) throws IOException {
             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();
@@ -476,6 +478,7 @@
          * Closes the file.
          * @throws IOException When the file cannot be closed.
          */
+        @Override
         public void close() throws IOException {
             os.close();
         }
@@ -486,9 +489,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();
 
@@ -496,10 +499,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();
@@ -510,7 +513,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();
@@ -535,19 +538,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());
                 }
             }
 
@@ -573,23 +572,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());
         }
     }
 
@@ -601,12 +601,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);
     }
 
     /**
@@ -630,18 +625,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;
     }
 
@@ -705,11 +696,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);
     }
 
     /**
@@ -717,14 +704,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);
     }
 
     /**
@@ -737,7 +717,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();
         }
@@ -749,13 +729,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>.
@@ -937,7 +918,7 @@
     /**
      * Replace occurrences of str1 in StringBuffer str with str2.
      */
-    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();
@@ -952,17 +933,9 @@
      * strings are tried later.
      */
     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 6935f9e..c24adfb 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;
@@ -90,6 +91,23 @@
     /** rmic failed message */
     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;
@@ -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);
         }
     }
@@ -645,9 +646,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!!
@@ -668,11 +667,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 {
@@ -704,16 +700,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()) {
@@ -732,10 +726,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());
             }
         }
     }
@@ -759,11 +752,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);
     }
 
     /**
@@ -773,7 +764,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;
@@ -801,26 +792,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);
     }
 
     /**
@@ -837,7 +819,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 3ef604d..daf4c21 100644
--- a/src/main/org/apache/tools/ant/taskdefs/SQLExec.java
+++ b/src/main/org/apache/tools/ant/taskdefs/SQLExec.java
@@ -21,12 +21,12 @@
 import java.io.BufferedReader;
 import java.io.File;
 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;
@@ -35,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;
@@ -91,7 +91,7 @@
         /** @return the enumerated strings */
         @Override
         public String[] getValues() {
-            return new String[] {NORMAL, ROW};
+            return new String[] { NORMAL, ROW };
         }
     }
 
@@ -127,7 +127,7 @@
     /**
      * SQL transactions to perform
      */
-    private Vector transactions = new Vector();
+    private List<Transaction> transactions = new Vector<>();
 
     /**
      * SQL Statement delimiter
@@ -351,7 +351,7 @@
      */
     public Transaction createTransaction() {
         Transaction t = new Transaction();
-        transactions.addElement(t);
+        transactions.add(t);
         return t;
     }
 
@@ -553,8 +553,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;
     }
@@ -603,17 +603,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());
                 }
             }
 
@@ -677,10 +677,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();
@@ -689,16 +687,10 @@
                 } 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 {
@@ -727,10 +719,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();
@@ -782,7 +774,7 @@
      */
     protected void execSQL(String sql, PrintStream out) throws SQLException {
         // Check and ignore empty statements
-        if ("".equals(sql.trim())) {
+        if (sql.trim().isEmpty()) {
             return;
         }
 
@@ -830,10 +822,10 @@
         } 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 {
@@ -907,7 +899,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++) {
@@ -926,7 +918,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) {
@@ -935,7 +927,6 @@
         }
     }
 
-
     /**
      * Caches the connection returned by the base class's getConnection method.
      *
@@ -972,7 +963,6 @@
             statement = getConnection().createStatement();
             statement.setEscapeProcessing(escapeProcessing);
         }
-
         return statement;
     }
 
@@ -984,7 +974,7 @@
         /** @return the enumerated values */
         @Override
         public String[] getValues() {
-            return new String[] {"continue", "stop", "abort"};
+            return new String[] { "continue", "stop", "abort" };
         }
     }
 
@@ -1039,18 +1029,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);
             }
@@ -1058,16 +1045,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);
                 }
             }
         }
@@ -1083,35 +1065,33 @@
             }
             // 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 468ac14..7d9787b 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,7 +41,7 @@
 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.
@@ -49,8 +49,9 @@
      * @param nestedTask  Nested task to execute Sequential
      * <p>
      */
+    @Override
     public void addTask(Task nestedTask) {
-        nestedTasks.addElement(nestedTask);
+        nestedTasks.add(nestedTask);
     }
 
     /**
@@ -58,15 +59,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
index 052c569..632b900 100644
--- a/src/main/org/apache/tools/ant/taskdefs/SetPermissions.java
+++ b/src/main/org/apache/tools/ant/taskdefs/SetPermissions.java
@@ -137,6 +137,7 @@
         resources.add(rc);
     }
 
+    @Override
     public void execute() {
         if (resources == null) {
             throw new BuildException("At least one resource-collection is required");
@@ -169,18 +170,17 @@
         String msg = String.format(msgFormat, msgArgs);
         if (failonerror) {
             if (exc instanceof BuildException) {
-                throw (BuildException)exc;
-            } else {
-                throw new BuildException(msg, exc);
-            }              
-        } else {
-            log("Warning: " + msg, Project.MSG_ERR);
+                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);
+        String msg = String.format(
+            "the associated path '%s' does not support the PosixFileAttributeView",
+            p);
         switch (nonPosixMode) {
         case fail:
             throw new BuildException(msg);
@@ -207,19 +207,18 @@
                 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);
+                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);
+            String msg = String.format(
+                "the associated path '%s' does not support the DosFileAttributeView",
+                p);
             if (failIfDosIsNotSupported) {
                 throw new BuildException(msg);
-            } else {
-                log("Warning: " + msg, Project.MSG_ERR);
             }
+            log("Warning: " + msg, Project.MSG_ERR);
         }
     }
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/SignJar.java b/src/main/org/apache/tools/ant/taskdefs/SignJar.java
index ed271d8..14b7073 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;
@@ -133,37 +165,6 @@
      */
     private String tsaDigestAlg;
 
-    /**
-     * 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";
     // CheckStyle:VisibilityModifier ON
 
     /**
@@ -441,14 +442,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
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 59d886b..0b91d5b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java
+++ b/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java
@@ -55,7 +55,6 @@
         this(is, os, closeWhenExhausted, false);
     }
 
-
     /**
      * Create a new StreamPumper.
      *
@@ -112,6 +111,7 @@
      *
      * Terminates as soon as the input stream is closed or an error occurs.
      */
+    @Override
     public void run() {
         synchronized (this) {
             started = true;
@@ -120,8 +120,8 @@
 
         final byte[] buf = new byte[bufferSize];
 
-        int length;
         try {
+            int length;
             while (true) {
                 waitForInput(is);
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/SubAnt.java b/src/main/org/apache/tools/ant/taskdefs/SubAnt.java
index c374d83..17351b5 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.
@@ -296,11 +296,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) {
@@ -331,13 +327,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;
     }
 
     /**
@@ -392,8 +390,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);
@@ -445,7 +442,7 @@
      * @param  p the property to pass on explicitly to the sub-build.
      */
     public void addProperty(Property p) {
-        properties.addElement(p);
+        properties.add(p);
     }
 
     /**
@@ -455,7 +452,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);
     }
 
     /**
@@ -464,7 +461,7 @@
      * @param ps the propertyset
      */
     public void addPropertyset(PropertySet ps) {
-        propertySets.addElement(ps);
+        propertySets.add(ps);
     }
 
     /**
@@ -591,18 +588,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 bcdfd52..cadb342 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) {
-        int[] removedCount = new int[] {0, 0};
+    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");
         }
 
         /**
@@ -586,8 +576,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 653cc5b..f51a056 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Tar.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Tar.java
@@ -29,7 +29,6 @@
 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;
@@ -111,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
 
@@ -200,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);
     }
@@ -275,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()) {
@@ -290,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);
             }
 
@@ -316,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(
-                            Files.newOutputStream(tarFile.toPath()))),
-                    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);
@@ -352,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;
@@ -603,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));
@@ -615,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) {
@@ -630,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);
             }
         }
@@ -654,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;
@@ -695,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()) {
@@ -745,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);
@@ -762,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 {
@@ -840,7 +827,6 @@
             if (files == null) {
                 files = getFileNames(this);
             }
-
             return files;
         }
 
@@ -894,7 +880,7 @@
             POSIX = "posix",
             OMIT = "omit";
 
-        private final String[] validModes = {
+        private static final String[] VALID_MODES = {
             WARN, FAIL, TRUNCATE, GNU, POSIX, OMIT
         };
 
@@ -909,7 +895,7 @@
          */
         @Override
         public String[] getValues() {
-            return validModes;
+            return VALID_MODES;
         }
 
         /**
@@ -994,7 +980,7 @@
          */
         @Override
         public String[] getValues() {
-            return new String[] {NONE, GZIP, BZIP2, XZ };
+            return new String[] { NONE, GZIP, BZIP2, XZ };
         }
 
         /**
@@ -1010,14 +996,14 @@
             final String v = getValue();
             if (GZIP.equals(v)) {
                 return new GZIPOutputStream(ostream);
-            } else if (XZ.equals(v)) {
+            }
+            if (XZ.equals(v)) {
                 return newXZOutputStream(ostream);
-            } else {
-                if (BZIP2.equals(v)) {
-                    ostream.write('B');
-                    ostream.write('Z');
-                    return new CBZip2OutputStream(ostream);
-                }
+            }
+            if (BZIP2.equals(v)) {
+                ostream.write('B');
+                ostream.write('Z');
+                return new CBZip2OutputStream(ostream);
             }
             return ostream;
         }
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 5f55a37..1247cf1 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 c6d79b7..c2de10e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Touch.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Touch.java
@@ -23,6 +23,7 @@
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.util.List;
 import java.util.Locale;
 import java.util.Vector;
 
@@ -79,9 +80,11 @@
                 }
             };
 
+        @Override
         public DateFormat getPrimaryFormat() {
             return primary.get();
         }
+        @Override
         public DateFormat getFallbackFormat() {
             return fallback.get();
         }
@@ -91,7 +94,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;
@@ -100,12 +103,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.
@@ -165,9 +162,11 @@
      */
     public void setPattern(final String pattern) {
         dfFactory = new DateFormatFactory() {
+            @Override
             public DateFormat getPrimaryFormat() {
                 return new SimpleDateFormat(pattern);
             }
+            @Override
             public DateFormat getFallbackFormat() {
                 return null;
             }
@@ -191,8 +190,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;
     }
@@ -231,8 +230,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.");
@@ -262,10 +261,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",
@@ -282,6 +280,7 @@
      * @throws BuildException
      *             if an error occurs.
      */
+    @Override
     public void execute() throws BuildException {
         checkConfiguration();
         touch();
@@ -313,16 +312,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);
             }
         }
     }
@@ -335,6 +330,7 @@
      * @throws BuildException on error
      * @deprecated since 1.6.x.
      */
+    @Deprecated
     protected void touch(File file) {
         touch(file, getTimestamp());
     }
@@ -378,8 +374,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 805427a..0610c39 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
@@ -21,8 +21,8 @@
 import java.text.SimpleDateFormat;
 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;
@@ -45,7 +45,7 @@
  */
 public class Tstamp extends Task {
 
-    private Vector customFormats = new Vector();
+    private List<CustomFormat> customFormats = new Vector<>();
     private String prefix = "";
 
     /**
@@ -66,15 +66,12 @@
      * the standard ones, to get their retaliation in early.
      * @throws BuildException on error.
      */
+    @Override
     public void execute() throws BuildException {
         try {
             Date d = new Date();
 
-            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));
@@ -97,7 +94,7 @@
      */
     public CustomFormat createFormat() {
         CustomFormat cts = new CustomFormat();
-        customFormats.addElement(cts);
+        customFormats.add(cts);
         return cts;
     }
 
@@ -129,12 +126,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.
          */
@@ -211,9 +202,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();
@@ -305,19 +296,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));
         }
 
         /**
@@ -326,14 +317,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 430aa54..fa26c35 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Untar.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Untar.java
@@ -37,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
@@ -86,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) {
-        InputStream fis = null;
         if (!srcF.exists()) {
             throw new BuildException("Unable to untar "
                     + srcF
                     + " as the file does not exist",
                     getLocation());
         }
-        try {
-            fis = Files.newInputStream(srcF.toPath());
+        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);
         }
     }
 
@@ -123,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 "
@@ -131,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);
         }
     }
 
@@ -148,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,
@@ -165,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);
         }
     }
 
@@ -213,8 +202,9 @@
          *
          * @return valid values
          */
+        @Override
         public String[] getValues() {
-            return new String[] {NONE, GZIP, BZIP2, XZ};
+            return new String[] { NONE, GZIP, BZIP2, XZ };
         }
 
         /**
@@ -234,19 +224,18 @@
             final String v = getValue();
             if (GZIP.equals(v)) {
                 return new GZIPInputStream(istream);
-            } else if (XZ.equals(v)) {
+            }
+            if (XZ.equals(v)) {
                 return newXZInputStream(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 (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;
         }
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 d23beab..4bcc0e9 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 d19918a..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) {
@@ -154,8 +152,7 @@
             }
 
             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();
diff --git a/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java b/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java
index 8fce71e..0902e55 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 {
@@ -678,8 +663,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;
@@ -703,12 +687,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();
         }
     }
 
@@ -721,7 +705,7 @@
      * @return the requested class.
      * @exception Exception if the class could not be loaded.
      */
-    private Class loadClass(final String classname) throws ClassNotFoundException {
+    private Class<?> loadClass(final String classname) throws ClassNotFoundException {
         setupLoader();
         if (loader == null) {
             return Class.forName(classname);
@@ -811,29 +795,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]);
@@ -931,8 +911,8 @@
      * Get an enumeration on the outputproperties.
      * @return the outputproperties
      */
-    public Enumeration getOutputProperties() {
-        return outputProperties.elements();
+    public Enumeration<OutputProperty> getOutputProperties() {
+        return Collections.enumeration(outputProperties);
     }
 
     /**
@@ -1175,7 +1155,7 @@
      */
     public OutputProperty createOutputProperty() {
         final OutputProperty p = new OutputProperty();
-        outputProperties.addElement(p);
+        outputProperties.add(p);
         return p;
     }
 
@@ -1236,11 +1216,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()));
     }
 
     /**
@@ -1300,16 +1277,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));
                     }
                 }
             }
@@ -1336,7 +1312,7 @@
 
         ParamType type;
 
-        if (typeName == null || "".equals(typeName)) {
+        if (typeName == null || typeName.isEmpty()) {
             type = ParamType.STRING; // String is default
         } else {
             try {
@@ -1361,11 +1337,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);
         }
     }
 
@@ -1432,9 +1407,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);
     }
 
     /**
@@ -1447,10 +1421,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);
     }
 
     /**
@@ -1465,12 +1438,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.
@@ -1499,7 +1472,7 @@
          * return the attribute elements.
          * @return the enumeration of attributes
          */
-        public Enumeration getAttributes() {
+        public Enumeration<Attribute> getAttributes() {
             return Collections.enumeration(attributes);
         }
 
@@ -1528,8 +1501,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 */
@@ -1558,6 +1530,7 @@
              * @return null
              * @throws BuildException never
              */
+            @Override
             public Object createDynamicElement(final String name) throws BuildException {
                 return null;
             }
@@ -1569,6 +1542,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)) {
@@ -1582,7 +1556,7 @@
                         this.value = Boolean.FALSE;
                     } else {
                         try {
-                            this.value = new Integer(value);
+                            this.value = Integer.valueOf(value);
                         } catch (final NumberFormatException e) {
                             this.value = value;
                         }
@@ -1595,7 +1569,7 @@
                                                              new Reference(getProject(),
                                                                            value));
                 } else {
-                    throw new BuildException("Unsupported attribute: " + name);
+                    throw new BuildException("Unsupported attribute: %s", name);
                 }
             }
         } // -- class Attribute
@@ -1608,7 +1582,9 @@
             private String name;
             private boolean value;
 
-            public Feature() { }
+            public Feature() {
+            }
+
             public Feature(String name, boolean value) {
                 this.name = name;
                 this.value = value;
@@ -1654,10 +1630,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) {
@@ -1758,7 +1739,7 @@
         /**
          * The stream to write traces to.
          */
-        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 ffd89d1..9ebfc83 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 1a17bfc..ff72014 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Zip.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Zip.java
@@ -28,12 +28,13 @@
 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;
@@ -43,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;
@@ -84,13 +84,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;
@@ -99,27 +110,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<>();
 
     /**
      * If this flag is true, execute() will run most operations twice,
@@ -152,8 +146,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
@@ -363,7 +355,7 @@
      * @param set the group (a fileset) to add
      */
     public void addZipGroupFileset(final FileSet set) {
-        groupfilesets.addElement(set);
+        groupfilesets.add(set);
     }
 
     /**
@@ -390,7 +382,7 @@
          */
         @Override
         public String[] getValues() {
-            return new String[] {"fail", "skip", "create"};
+            return new String[] { "fail", "skip", "create" };
         }
     }
 
@@ -627,20 +619,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
@@ -654,8 +643,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;
@@ -706,32 +696,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) {
@@ -783,16 +766,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;
     }
@@ -823,24 +800,23 @@
 
     /** 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 (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);
         }
     }
 
@@ -858,23 +834,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);
             }
         }
     }
@@ -918,17 +889,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 += "/";
             }
@@ -947,26 +917,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);
 
@@ -976,14 +946,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()));
@@ -1011,7 +981,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);
@@ -1057,25 +1027,18 @@
                 if (keepCompression) {
                     doCompress = (ze.getMethod() == ZipEntry.DEFLATED);
                 }
-                InputStream is = null;
-                try {
-                    is = zf.getInputStream(ze);
+                try (InputStream is = 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 = r.getInputStream();
+            try (InputStream is = r.getInputStream()) {
                 zipFile(is, zOut, prefix + name, r.getLastModified(),
                         fromArchive, mode, r instanceof ZipResource
                         ? ((ZipResource) r).getExtraFields() : null);
-            } finally {
-                FileUtils.close(is);
             }
         }
     }
@@ -1099,15 +1062,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) {
@@ -1174,9 +1136,7 @@
             log("Note: creating empty " + archiveType + " archive " + zipFile,
                 Project.MSG_INFO);
         }
-        OutputStream os = null;
-        try {
-            os = Files.newOutputStream(zipFile.toPath());
+        try (OutputStream os = Files.newOutputStream(zipFile.toPath())) {
             // CheckStyle:MagicNumber OFF
             // Cf. PKZIP specification.
             final byte[] empty = new byte[22];
@@ -1191,8 +1151,6 @@
             throw new BuildException("Could not create empty ZIP archive "
                                      + "(" + ioe.getMessage() + ")", ioe,
                                      getLocation());
-        } finally {
-            FileUtils.close(os);
         }
         return true;
     }
@@ -1241,13 +1199,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 =
@@ -1349,7 +1307,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"
@@ -1360,7 +1318,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.",
@@ -1521,8 +1479,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());
                 }
             }
 
@@ -1559,8 +1517,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);
@@ -1583,32 +1541,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;
     }
@@ -1624,25 +1578,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()]);
         }
@@ -1677,8 +1625,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);
     }
 
     /**
@@ -1739,7 +1687,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
@@ -1781,19 +1729,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);
         }
@@ -1861,7 +1809,7 @@
                 count = in.read(buffer, 0, buffer.length);
             } while (count != -1);
         }
-        addedFiles.addElement(vPath);
+        addedFiles.add(vPath);
     }
 
     /**
@@ -1937,7 +1885,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) {
@@ -1950,7 +1898,7 @@
 
             while (!directories.isEmpty()) {
                 final String dir = directories.pop();
-                File f = null;
+                File f;
                 if (baseDir != null) {
                     f = new File(baseDir, dir);
                 } else {
@@ -1977,16 +1925,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();
+        filesetsFromGroupfilesets.forEach(resources::remove);
+        filesetsFromGroupfilesets.clear();
         HAVE_NON_FILE_SET_RESOURCES_TO_ADD.set(Boolean.FALSE);
     }
 
@@ -1999,10 +1943,10 @@
      * @see #cleanUp
      */
     public void reset() {
-        resources.removeAllElements();
+        resources.clear();
         zipFile = null;
         baseDir = null;
-        groupfilesets.removeAllElements();
+        groupfilesets.clear();
         duplicate = "add";
         archiveType = "zip";
         doCompress = true;
@@ -2020,8 +1964,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;
             }
         }
@@ -2036,19 +1980,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;
                                });
     }
 
@@ -2059,12 +2002,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);
     }
 
     /**
@@ -2078,18 +2016,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;
     }
 
     /**
@@ -2115,7 +2044,7 @@
         /** {@inheritDoc} */
         @Override
         public String[] getValues() {
-            return new String[] {"add", "preserve", "fail"};
+            return new String[] { "add", "preserve", "fail" };
         }
     }
 
@@ -2158,11 +2087,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;
@@ -2176,7 +2103,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";
@@ -2210,7 +2137,6 @@
         }
     }
 
-
     /**
      * The choices for Zip64 extensions.
      *
@@ -2238,7 +2164,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";
@@ -2251,7 +2177,7 @@
 
         @Override
         public String[] getValues() {
-            return new String[] {NEVER_KEY, ALWAYS_KEY, A_N_KEY};
+            return new String[] { NEVER_KEY, ALWAYS_KEY, A_N_KEY };
         }
 
         public static final Zip64ModeAttribute NEVER =
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 8712715..a1fe5c8 100644
--- a/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java
@@ -96,69 +96,59 @@
      * @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")) {
-                // 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)) {
+            // 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
@@ -194,7 +184,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 82373a9..f33c4a5 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,8 +148,9 @@
      * but specialized compilers can recognize multiple kinds
      * of files.
      */
+    @Override
     public String[] getSupportedFileExtensions() {
-        return new String[] {"java"};
+        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 || !assumeJava19()) {
                 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());
@@ -486,25 +485,19 @@
      */
     protected void logAndAddFilesToCompile(final Commandline cmd) {
         attributes.log("Compilation " + cmd.describeArguments(),
-                       Project.MSG_VERBOSE);
+            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);
     }
 
     /**
@@ -554,29 +547,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;
@@ -705,6 +699,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);
@@ -814,24 +809,22 @@
         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"))
+        return "1".equals(t) || "2".equals(t) || "3".equals(t) || "4".equals(t)
+            || (("5".equals(t) || "6".equals(t))
                 && !assumeJava15() && !assumeJava16())
-            || (t.equals("7") && !assumeJava17())
-            || (t.equals("8") && !assumeJava18())
-            || (t.equals("9") && !assumeJava9());
+            || ("7".equals(t) && !assumeJava17())
+            || ("8".equals(t) && !assumeJava18())
+            || ("9".equals(t) && !assumeJava9());
     }
 
-
     /**
-     * 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 3167cc2..b1c60a2 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,19 @@
  * @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 +63,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 +92,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.");
             }
         }
 
@@ -153,8 +156,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 acb6a7f..913fefa 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 ab28454..6a03709 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 4c04278..a475e07 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.URL;
@@ -43,6 +44,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
@@ -51,8 +54,6 @@
         spec = url;
     }
 
-    private int errorsBeginAt = ERROR_BEGINS;
-
     /**
      * Set the errorsBeginAt attribute
      * @param errorsBeginAt number at which errors begin at, default is
@@ -92,6 +93,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");
@@ -116,7 +118,7 @@
             } catch (java.net.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 ddacd99..51471c8 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 compoarison mode and the time of the resource
      * @throws BuildException
      */
+    @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 e699da1..de3f811 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/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 974c396..07ccb59 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 43a40e0..6801b5c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/condition/Socket.java
+++ b/src/main/org/apache/tools/ant/taskdefs/condition/Socket.java
@@ -23,7 +23,6 @@
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.ProjectComponent;
-import org.apache.tools.ant.util.FileUtils;
 
 /**
  * Condition to wait for a TCP/IP socket to have a listener. Its attributes are:
@@ -58,25 +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 {
-            FileUtils.close(s);
         }
-        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 63cf657..6ef730e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogTask.java
@@ -19,14 +19,14 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.io.OutputStream;
 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.
@@ -82,7 +81,7 @@
     private File usersFile;
 
     /** User list */
-    private Vector cvsUsers = new Vector();
+    private List<CvsUser> cvsUsers = new Vector<>();
 
     /** Input dir */
     private File inputDir;
@@ -110,8 +109,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.
@@ -122,7 +120,6 @@
         this.inputDir = inputDir;
     }
 
-
     /**
      * Set the output file for the log.
      *
@@ -132,7 +129,6 @@
         this.destFile = destFile;
     }
 
-
     /**
      * Set a lookup list of user names &amp; addresses
      *
@@ -142,17 +138,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.
      *
@@ -162,7 +156,6 @@
         this.startDate = start;
     }
 
-
     /**
      * Set the date at which the changelog should stop.
      *
@@ -172,7 +165,6 @@
         this.endDate = endDate;
     }
 
-
     /**
      * Set the number of days worth of log entries to process.
      *
@@ -206,7 +198,6 @@
         this.startTag = start;
     }
 
-
     /**
      * Set the tag at which the changelog should stop.
      *
@@ -222,29 +213,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());
             }
@@ -294,18 +282,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);
                 }
             }
 
@@ -351,27 +332,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");
         }
     }
 
@@ -400,10 +374,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
@@ -431,13 +404,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()]);
     }
 
     /**
@@ -445,9 +415,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()));
             }
@@ -462,17 +430,11 @@
      */
     private void writeChangeLog(final CVSEntry[] entrySet)
          throws BuildException {
-        OutputStream output = null;
 
-        try {
-            output = Files.newOutputStream(destFile.toPath());
+        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");
@@ -481,9 +443,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 9fbc3fd..83ec607 100644
--- a/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagDiff.java
+++ b/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagDiff.java
@@ -21,17 +21,13 @@
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
-import java.io.OutputStream;
 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;
@@ -152,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.
@@ -229,7 +225,6 @@
         ignoreRemoved = b;
     }
 
-
     /**
      * Execute task.
      *
@@ -297,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
@@ -316,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();
 
@@ -325,6 +319,7 @@
                                          packageNamePrefixLengths);
                 if (line != null) {
                     // use || in a perl like fashion
+                    @SuppressWarnings("unused")
                     boolean processed
                         =  doFileIsNew(entries, line)
                         || doFileHasChanged(entries, line)
@@ -333,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;
@@ -364,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;
@@ -385,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;
         }
@@ -406,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;
     }
@@ -418,11 +402,8 @@
      * @exception BuildException if an error occurs
      */
     private void writeTagDiff(CvsTagEntry[] entries) throws BuildException {
-        OutputStream output = null;
-        try {
-            output = Files.newOutputStream(mydestfile.toPath());
-            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");
@@ -455,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);
-                }
-            }
         }
     }
 
@@ -508,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) {
@@ -517,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.");
         }
     }
 
@@ -536,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()
         }
@@ -549,7 +521,6 @@
         }
     }
 
-
     /**
      * removes a "File: module/" prefix if present.
      *
@@ -561,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 e9b755d..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,9 +18,7 @@
 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;
 
@@ -35,7 +33,6 @@
             new ByteArrayOutputStream());
     }
 
-
     String getErrors() {
         try {
             final ByteArrayOutputStream error
@@ -47,11 +44,10 @@
         }
     }
 
-
+    @Override
     public void stop() {
         super.stop();
         FileUtils.close(getErr());
         FileUtils.close(getOut());
     }
 }
-
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 edc9c9d..a515478 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 0a5bc68..207a2e3 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,8 +59,9 @@
          *
          * @return a list of valid entries
          */
+        @Override
         public String[] getValues() {
-            return new String[] {AUTO, MIME, UU, PLAIN};
+            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;
@@ -189,8 +189,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());
@@ -203,8 +203,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());
@@ -284,7 +284,7 @@
      * @param address An email address.
      */
     public void addTo(EmailAddress address) {
-        toList.addElement(address);
+        toList.add(address);
     }
 
     /**
@@ -296,7 +296,7 @@
         StringTokenizer tokens = new StringTokenizer(list, ",");
 
         while (tokens.hasMoreTokens()) {
-            toList.addElement(new EmailAddress(tokens.nextToken()));
+            toList.add(new EmailAddress(tokens.nextToken()));
         }
     }
 
@@ -306,7 +306,7 @@
      * @param address The email address.
      */
     public void addCc(EmailAddress address) {
-        ccList.addElement(address);
+        ccList.add(address);
     }
 
     /**
@@ -318,7 +318,7 @@
         StringTokenizer tokens = new StringTokenizer(list, ",");
 
         while (tokens.hasMoreTokens()) {
-            ccList.addElement(new EmailAddress(tokens.nextToken()));
+            ccList.add(new EmailAddress(tokens.nextToken()));
         }
     }
 
@@ -328,7 +328,7 @@
      * @param address The email address.
      */
     public void addBcc(EmailAddress address) {
-        bccList.addElement(address);
+        bccList.add(address);
     }
 
     /**
@@ -340,7 +340,7 @@
         StringTokenizer tokens = new StringTokenizer(list, ",");
 
         while (tokens.hasMoreTokens()) {
-            bccList.addElement(new EmailAddress(tokens.nextToken()));
+            bccList.add(new EmailAddress(tokens.nextToken()));
         }
     }
 
@@ -434,6 +434,7 @@
     /**
      * Send an email.
      */
+    @Override
     public void execute() {
         Message savedMessage = message;
 
@@ -443,15 +444,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;
@@ -463,20 +464,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;
@@ -486,16 +487,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) {
@@ -508,33 +509,34 @@
             }
             // 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
@@ -631,4 +633,3 @@
     }
 
 }
-
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 4aaa982..4805177 100644
--- a/src/main/org/apache/tools/ant/taskdefs/email/Mailer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/email/Mailer.java
@@ -274,4 +274,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 a7551bb..2422e44 100644
--- a/src/main/org/apache/tools/ant/taskdefs/email/Message.java
+++ b/src/main/org/apache/tools/ant/taskdefs/email/Message.java
@@ -48,7 +48,6 @@
     public Message() {
     }
 
-
     /**
      * Creates a new message based on the given string
      *
@@ -58,7 +57,6 @@
         addText(text);
     }
 
-
     /**
      * Creates a new message using the contents of the given file.
      *
@@ -68,7 +66,6 @@
         messageSource = file;
     }
 
-
     /**
      * Adds a textual part of the message
      *
@@ -78,7 +75,6 @@
         buffer.append(text);
     }
 
-
     /**
      * Sets the source file of the message
      *
@@ -88,7 +84,6 @@
         this.messageSource = src;
     }
 
-
     /**
      * Sets the content type for the message
      *
@@ -99,7 +94,6 @@
         specified = true;
     }
 
-
     /**
      * Returns the content type
      *
@@ -109,7 +103,6 @@
         return mimeType;
     }
 
-
     /**
      * Prints the message onto an output stream
      *
@@ -129,7 +122,7 @@
                 // Read message from a file
                 try (Reader freader = getReader(messageSource);
                      BufferedReader in = new BufferedReader(freader)) {
-                    String line = null;
+                    String line;
                     while ((line = in.readLine()) != null) {
                         out.write(getProject().replaceProperties(line));
                         out.newLine();
@@ -145,7 +138,6 @@
         }
     }
 
-
     /**
      * Returns true if the mimeType has been set.
      *
@@ -164,6 +156,7 @@
     public void setCharset(String charset) {
       this.charset = charset;
     }
+
     /**
      * Returns the charset of mail message.
      *
@@ -197,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..e80d8d1 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 0ad57c6..1d0c378 100644
--- a/src/main/org/apache/tools/ant/taskdefs/email/PlainMailer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/email/PlainMailer.java
@@ -23,8 +23,6 @@
 import java.io.InputStream;
 import java.io.PrintStream;
 import java.nio.file.Files;
-import java.util.Enumeration;
-
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.mail.MailMessage;
@@ -40,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");
             }
@@ -97,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) {
@@ -127,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) {
@@ -145,20 +137,20 @@
             out.println();
         }
 
-        int length;
         final int maxBuf = 1024;
         byte[] buf = new byte[maxBuf];
 
         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);
             }
         }
     }
 
-    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 0b61ecd..9759601 100644
--- a/src/main/org/apache/tools/ant/taskdefs/email/UUMailer.java
+++ b/src/main/org/apache/tools/ant/taskdefs/email/UUMailer.java
@@ -33,19 +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());
         }
 
-        try (InputStream finstr = Files.newInputStream(file.toPath());
-             BufferedInputStream in = new BufferedInputStream(finstr)) {
-            UUEncoder encoder = new UUEncoder(file.getName());
-
-            encoder.encode(in, out);
+        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 f39fff0..5139ce9 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");
     }
 
     /**
@@ -157,37 +158,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 4c1b3f0..16b8042 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,9 +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;
     }
@@ -98,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) {
@@ -123,8 +117,6 @@
                 out.newLine();
                 out.write(cmd[i]);
             }
-        } finally {
-            FileUtils.close(out);
         }
         return script;
     }
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 2ed40e5..2ca2443 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);
         }
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 11c091a..43acdbe 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,21 +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
@@ -278,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();
@@ -306,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 {
@@ -349,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 f6681f8..8132f36 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java
@@ -17,7 +17,6 @@
  */
 package org.apache.tools.ant.taskdefs.optional;
 
-import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -31,25 +30,25 @@
 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;
@@ -127,7 +126,7 @@
      */
     private boolean failonerror = true;
 
-    private Vector propertySets = new Vector();
+    private List<PropertySet> propertySets = new Vector<>();
 
     private String format = "text";
 
@@ -157,7 +156,6 @@
         this.destfile = destfile;
     }
 
-
     /**
      * If true, the task will fail if an error occurs writing the properties
      * file, otherwise errors are just logged.
@@ -169,7 +167,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
@@ -209,7 +206,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());
@@ -224,7 +221,7 @@
      * @since Ant 1.6
      */
     public void addPropertyset(PropertySet ps) {
-        propertySets.addElement(ps);
+        propertySets.add(ps);
     }
 
     /**
@@ -240,12 +237,13 @@
      * The values are "xml" and "text".
      */
     public static class FormatAttribute extends EnumeratedAttribute {
-        private String [] formats = new String[]{"xml", "text"};
+        private String[] formats = new String[] { "xml", "text" };
 
         /**
          * @see EnumeratedAttribute#getValues()
          * @return accepted values
          */
+        @Override
         public String[] getValues() {
             return formats;
         }
@@ -256,27 +254,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;
             }
 
@@ -290,9 +289,7 @@
                 return;
             }
 
-            InputStream in = null;
-            try {
-                in = Files.newInputStream(inFile.toPath());
+            try (InputStream in = Files.newInputStream(inFile.toPath())) {
                 Properties props = new Properties();
                 props.load(in);
                 allProps.putAll(props);
@@ -301,72 +298,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 = Files.newOutputStream(this.destfile.toPath());
+        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
@@ -378,37 +338,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)) {
@@ -419,7 +379,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;
 
@@ -436,9 +396,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
@@ -450,26 +410,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());
     }
 
     /**
@@ -484,29 +439,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);
         }
     }
 
@@ -524,7 +472,6 @@
                                      String header) throws IOException {
        try {
            props.store(os, header);
-
        } catch (IOException ioe) {
            throw new BuildException(ioe, getLocation());
        } finally {
@@ -538,6 +485,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.
@@ -552,4 +522,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 06e1d11..dd3e107 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);
     }
 
     /**
@@ -423,8 +407,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;
     }
@@ -434,17 +417,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) {
@@ -459,7 +447,7 @@
         }
 
         if (classpath == null) {
-            classpath = (new Path(getProject())).concatSystemClasspath("last");
+            classpath = new Path(getProject()).concatSystemClasspath("last");
         } else {
             classpath = classpath.concatSystemClasspath("ignore");
         }
@@ -492,22 +480,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 81a386f..e761975 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java
@@ -192,8 +192,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;
     }
@@ -203,6 +203,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
@@ -222,11 +223,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();
@@ -270,8 +271,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
@@ -282,8 +282,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);
             }
         }
 
@@ -310,19 +310,22 @@
 
     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.substring(0, lastDot) + 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 21440f1..9c6da4a 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;
 
@@ -143,8 +146,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.
@@ -156,7 +159,6 @@
         this.binary = binary;
     }
 
-
     /**
      * Set the classpath used for NetRexx compilation.
      * @param classpath the classpath to use.
@@ -165,7 +167,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.
@@ -176,7 +177,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.
@@ -187,7 +187,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.
@@ -202,7 +201,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.
@@ -214,7 +212,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.
@@ -225,7 +222,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
@@ -238,7 +234,6 @@
         this.decimal = decimal;
     }
 
-
     /**
      * Set the destination directory into which the NetRexx source files
      * should be copied and then compiled.
@@ -248,7 +243,6 @@
         destDir = destDirName;
     }
 
-
     /**
      * Whether diagnostic information about the compile is generated
      * @param diag a <code>boolean</code> value.
@@ -257,7 +251,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.
@@ -268,7 +261,6 @@
         this.explicit = explicit;
     }
 
-
     /**
      * Whether the generated java code is formatted nicely or left to match
      * NetRexx line numbers for call stack debugging.
@@ -280,7 +272,6 @@
         this.format = format;
     }
 
-
     /**
      * Whether the generated java code is produced.
      * This is not implemented yet.
@@ -290,7 +281,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,
@@ -304,7 +294,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.
@@ -315,7 +304,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.
@@ -326,7 +314,6 @@
         this.replace = replace;
     }
 
-
     /**
      * Sets whether the compiler messages will be written to NetRexxC.log as
      * well as to the console.
@@ -338,7 +325,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.
@@ -350,7 +336,6 @@
         this.sourcedir = sourcedir;
     }
 
-
     /**
      * Set the source dir to find the source Java files.
      * @param srcDirName the source directory.
@@ -359,7 +344,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>
@@ -372,7 +356,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.
@@ -383,7 +366,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.
@@ -394,7 +376,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
@@ -407,7 +388,6 @@
         this.strictimport = strictimport;
     }
 
-
     /**
      * Sets whether local properties need to be qualified explicitly using
      * <code>this</code>.
@@ -419,7 +399,6 @@
         this.strictprops = strictprops;
     }
 
-
     /**
      * Whether the compiler should force catching of exceptions by explicitly
      * named types.
@@ -431,7 +410,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.
@@ -442,7 +420,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.
@@ -471,12 +448,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.
@@ -487,7 +462,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.
@@ -496,14 +470,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);
     }
@@ -518,7 +490,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
@@ -529,7 +500,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
@@ -540,7 +510,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
@@ -551,7 +520,6 @@
         this.suppressExceptionNotSignalled = suppressExceptionNotSignalled;
     }
 
-
     /**
      * Tells whether we should filter out any deprecation-messages
      * of the compiler out.
@@ -561,7 +529,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,113 +713,80 @@
                     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
         String currentClassPath = System.getProperty("java.class.path");
@@ -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,17 +937,16 @@
                     + 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"};
+            return new String[] { "trace", "trace1", "trace2", "notrace" };
         }
     }
 
@@ -1032,11 +955,10 @@
      */
     public static class VerboseAttr extends EnumeratedAttribute {
         /** {@inheritDoc}. */
+        @Override
         public String[] getValues() {
-            return new String[]{"verbose", "verbose0", "verbose1",
-                "verbose2", "verbose3", "verbose4",
-                "verbose5", "noverbose"};
+            return new String[] { "verbose", "verbose0", "verbose1", "verbose2",
+                "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 5a3c215..32239ce 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java
@@ -31,7 +31,6 @@
 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;
@@ -139,7 +138,7 @@
     private File                propertyfile;
     private boolean             useJDKProperties;
 
-    private Vector entries = new Vector();
+    private Vector<Entry> entries = new Vector<>();
 
     /* ========================================================================
      *
@@ -174,10 +173,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 {
@@ -266,7 +262,7 @@
     }
 
     private boolean checkParam(File param) {
-        return !(param == null);
+        return param != null;
     }
 
     /**
@@ -384,8 +380,8 @@
                 } 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
@@ -447,7 +443,6 @@
             newValue = fmt.format(currentValue.getTime());
         }
 
-
         /**
          * Handle operations for type <code>int</code>.
          *
@@ -459,7 +454,6 @@
             int currentValue = DEFAULT_INT_VALUE;
             int newV  = DEFAULT_INT_VALUE;
 
-
             DecimalFormat fmt = (pattern != null) ? new DecimalFormat(pattern)
                 : new DecimalFormat();
             try {
@@ -535,15 +529,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);
             }
         }
 
@@ -582,7 +578,7 @@
                     ret = defaultValue;
                 }
             } else {
-                ret = (oldValue == null) ? defaultValue : oldValue;
+                ret = oldValue == null ? defaultValue : oldValue;
             }
 
             return ret;
@@ -606,7 +602,7 @@
             /** {@inheritDoc}. */
             @Override
             public String[] getValues() {
-                return new String[] {"+", "-", "=", "del"};
+                return new String[] { "+", "-", "=", "del" };
             }
 
             /**
@@ -617,9 +613,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;
@@ -642,7 +640,7 @@
             /** {@inheritDoc} */
             @Override
             public String[] getValues() {
-                return new String[] {"int", "date", "string"};
+                return new String[] { "int", "date", "string" };
             }
 
             /**
@@ -653,7 +651,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;
@@ -677,23 +676,22 @@
         private static final String MONTH = "month";
         private static final String YEAR = "year";
 
-        private static final String[] UNITS
-            = {MILLISECOND, SECOND, MINUTE, HOUR,
-               DAY, WEEK, MONTH, YEAR };
+        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));
         }
 
         /**
@@ -701,9 +699,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 f5357bb..afc9a54 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java
@@ -27,6 +27,7 @@
 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;
@@ -143,7 +144,6 @@
         this.subs = null;
     }
 
-
     /**
      * file for which the regular expression should be replaced;
      * required unless a nested fileset is supplied.
@@ -153,7 +153,6 @@
         this.file = file;
     }
 
-
     /**
      * the regular expression pattern to match in the file(s);
      * required if no nested &lt;regexp&gt; is used
@@ -168,7 +167,6 @@
         regex.setPattern(match);
     }
 
-
     /**
      * The substitution pattern to place in the file(s) in place
      * of the regular expression.
@@ -178,8 +176,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();
@@ -205,7 +203,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
@@ -219,12 +216,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);
     }
 
     /**
@@ -297,8 +289,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();
@@ -341,7 +333,6 @@
         return res;
     }
 
-
     /**
      *  Perform the replacement on a file
      *
@@ -355,13 +346,14 @@
         try {
             boolean changes = false;
 
+            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 {
-                    r = encoding != null ? new InputStreamReader(is, encoding) : new InputStreamReader(is);
-                    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" : "")
@@ -372,7 +364,7 @@
                         r = new BufferedReader(r);
                         w = new BufferedWriter(w);
 
-                        StringBuffer linebuf = new StringBuffer();
+                        StringBuilder linebuf = new StringBuilder();
                         int c;
                         boolean hasCR = false;
 
@@ -386,7 +378,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
@@ -402,7 +394,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)
@@ -413,7 +405,7 @@
                                         hasCR = false;
                                     }
 
-                                    linebuf = new StringBuffer();
+                                    linebuf = new StringBuilder();
                                 }
 
                                 if (c >= 0) {
@@ -453,7 +445,6 @@
         }
     }
 
-
     /**
      * Execute the task
      *
@@ -469,9 +460,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);
@@ -491,9 +481,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 {
@@ -523,5 +511,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 d1e945c..7ecf35d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/Rpm.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/Rpm.java
@@ -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();
@@ -227,7 +228,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;
@@ -320,20 +321,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 e57d6d2..a5db991 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()) {
             //couldnt use the 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/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 350d673..a3d2d46 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 @@
         } // end of if ()
     }
 
-
     /**
      * 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);
+            } // end of if ()
+        }
     }
 
     /**
@@ -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 28f8064..a45f8bf 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 371d418..3e65848 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
@@ -78,6 +78,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;
@@ -92,10 +127,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) {
@@ -114,14 +149,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.
      */
@@ -272,7 +305,6 @@
         return mIdentical;
     }
 
-
     /**
      * Get the 'comment' command
      *
@@ -309,35 +341,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 0eaf09a..afcdcbc 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
@@ -94,6 +94,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;
@@ -111,10 +161,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) {
@@ -142,10 +192,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());
         }
     }
 
@@ -154,7 +204,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 ...]
@@ -167,12 +216,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.
      */
@@ -189,23 +237,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()) {
@@ -216,20 +258,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") );
     }
 
     /**
@@ -270,7 +307,6 @@
         return mNotco;
     }
 
-
     /**
      * Creates a writable file under a different filename.
      *
@@ -434,7 +470,6 @@
         }
     }
 
-
     /**
      * Get the 'comment' command
      *
@@ -471,46 +506,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 c273554..c2e36e9 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.
  *
@@ -85,6 +85,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;
@@ -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;
 
         // Default the viewpath to basedir if it is not specified
         if (getViewPath() == null) {
@@ -125,17 +150,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
@@ -150,15 +175,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.
@@ -289,15 +314,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());
     }
 
     /**
@@ -309,15 +333,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());
     }
 
     /**
@@ -329,15 +352,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());
     }
 
     /**
@@ -346,33 +368,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 128ea16..c428af0 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
@@ -83,6 +83,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;
@@ -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) {
@@ -131,10 +156,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());
         }
     }
 
@@ -161,13 +186,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) {
@@ -182,7 +205,6 @@
         cmd.createArgument().setValue(getViewPath());
     }
 
-
     /**
      * Set the replace flag
      *
@@ -309,7 +331,6 @@
         return mTypeValue;
     }
 
-
     /**
      * Get the 'version' command
      *
@@ -397,29 +418,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 82c9600..94cb5a1 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
@@ -80,6 +80,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;
@@ -88,7 +118,6 @@
     private boolean mFull = false;
     private boolean mNlabel = false;
 
-
     /**
      * Executes the task.
      * <p>
@@ -96,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) {
@@ -118,14 +147,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.
      */
@@ -133,13 +161,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()) {
@@ -162,10 +188,8 @@
 
        // baseline_root_name
         cmd.createArgument().setValue(getBaselineRootName());
-
     }
 
-
     /**
      * Set comment string
      *
@@ -221,8 +245,6 @@
     }
 
     /**
-
-    /**
      * Set the nowarn flag
      *
      * @param nwarn the status to set the flag to
@@ -294,7 +316,6 @@
         return mNlabel;
     }
 
-
     /**
      * Get the 'comment' command
      *
@@ -331,35 +352,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 4c89539..09af65e 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
@@ -63,6 +63,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;
@@ -74,10 +91,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) {
@@ -96,10 +113,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());
         }
     }
 
@@ -110,13 +127,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
@@ -180,7 +195,6 @@
         return mNoco;
     }
 
-
     /**
      * Get the 'comment' command
      *
@@ -217,21 +231,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 94faa5a..72a736a 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
@@ -88,6 +88,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;
@@ -104,10 +141,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,14 +163,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.
      */
@@ -141,13 +177,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()) {
@@ -329,7 +363,6 @@
         return mEltype;
     }
 
-
     /**
      * Get the 'comment' command
      *
@@ -384,41 +417,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 e3d288d..c75dc6d 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
@@ -82,6 +82,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;
@@ -97,10 +122,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) {
@@ -124,10 +149,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());
         }
     }
 
@@ -154,13 +179,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) {
@@ -172,7 +195,6 @@
         cmd.createArgument().setValue(getViewPath());
     }
 
-
     /**
      * Set the replace flag
      *
@@ -299,7 +321,6 @@
         return mVOB;
     }
 
-
     /**
      * Get the 'version' command
      *
@@ -361,10 +382,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();
             }
@@ -372,31 +392,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 7bb7192..87e2137 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
@@ -94,6 +94,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;
@@ -111,9 +144,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) {
@@ -132,14 +165,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.
      */
@@ -152,11 +184,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()) {
@@ -172,20 +202,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
      *
@@ -348,7 +375,6 @@
         return mCfile;
     }
 
-
     /**
      * Get the 'comment' command
      *
@@ -392,49 +418,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 cef0c3a..c699de1 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
@@ -86,6 +86,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;
@@ -101,9 +126,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) {
@@ -125,14 +150,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.
      */
@@ -149,13 +173,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
@@ -297,10 +319,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();
         }
@@ -343,31 +364,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 3c00e1a..266c098 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
@@ -53,6 +53,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;
 
     /**
@@ -62,10 +71,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) {
@@ -84,14 +93,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.
      */
@@ -127,15 +135,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 4ca3e89..dbb5f12 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
  */
@@ -68,6 +70,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;
 
@@ -78,10 +89,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) {
@@ -104,10 +115,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());
         }
     }
 
@@ -119,8 +130,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
@@ -203,15 +214,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());
     }
 
     /**
@@ -223,15 +233,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());
     }
 
     /**
@@ -240,21 +249,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 712efdc..96afe8d 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
@@ -80,6 +80,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;
@@ -94,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;
 
         // Default the viewpath to basedir if it is not specified
         if (getViewPath() == null) {
@@ -120,10 +149,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());
         }
     }
 
@@ -139,24 +168,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
@@ -278,7 +303,6 @@
         return mLog;
     }
 
-
     /**
      * Get the 'log' command
      *
@@ -287,45 +311,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 8f0a579..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
@@ -20,10 +20,11 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+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.Enumeration;
-import java.util.Hashtable;
 import java.util.Vector;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
@@ -37,11 +38,6 @@
  *
  */
 public class AntAnalyzer extends AbstractAnalyzer {
-    /**
-     * Default constructor
-     */
-    public AntAnalyzer() {
-    }
 
     /**
      * Determine the dependencies of the configured root classes.
@@ -51,31 +47,27 @@
      * @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;
@@ -93,7 +85,7 @@
                         ClassFile classFile = new ClassFile();
                         classFile.read(inStream);
                         for (String dependency : classFile.getClassRefs()) {
-                            analyzedDeps.put(dependency, dependency);
+                            analyzedDeps.add(dependency);
                         }
                     } finally {
                         FileUtils.close(inStream);
@@ -107,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);
     }
 
     /**
@@ -135,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..0af7579 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 f46af0a..c08b089 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;
         }
-
-        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);
+        Difference diff = new Difference();
+        diff.add(destPath);
+        diff.add(dependClasspath);
+        
+        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,21 +345,19 @@
         Path checkPath = getCheckClassPath();
         if (checkPath != null) {
             // now determine which jars each class depends upon
-            classpathDependencies = new Hashtable();
+            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);
@@ -405,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
@@ -437,7 +403,7 @@
                             File jarFile = (File) classpathFileObject;
                             log("Adding a classpath dependency on " + jarFile,
                                 Project.MSG_DEBUG);
-                            dependencies.put(jarFile, jarFile);
+                            dependencies.add(jarFile);
                         }
                     }
                 }
@@ -460,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);
@@ -487,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;
@@ -516,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 "
@@ -569,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;
     }
 
@@ -598,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);
@@ -683,6 +619,7 @@
      *
      * @exception BuildException Thrown in case of an unrecoverable error.
      */
+    @Override
     public void execute() throws BuildException {
         try {
             long start = System.currentTimeMillis();
@@ -691,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());
             }
@@ -702,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()) {
@@ -743,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;
     }
@@ -800,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);
     }
 
     /**
@@ -829,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.
      *
@@ -907,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 4401f1c..7137918 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
@@ -19,11 +19,14 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.List;
 import java.io.InputStream;
 import java.nio.file.Files;
-import java.util.Enumeration;
-import java.util.Stack;
-import java.util.Vector;
 
 /**
  * An iterator which iterates through the contents of a java directory. The
@@ -37,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
@@ -46,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
@@ -64,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();
     }
 
     /**
@@ -80,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);
     }
 
     /**
@@ -111,25 +101,25 @@
      *
      * @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
                         try (InputStream inFileStream
                              = Files.newInputStream(element.toPath())) {
@@ -145,13 +135,11 @@
                             }
                         }
                     }
+                } 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) {
@@ -162,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 9bec0ed..ec7ed64 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..4f7246c 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 e11e3aa..e304d41 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 4eefaeb..c1e5799 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);
 
@@ -266,6 +264,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);
     }
@@ -294,8 +293,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
@@ -315,9 +313,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);
         }
     }
 
@@ -354,7 +350,6 @@
         }
     }
 
-
     /**
      * Generate the client jar corresponding to the jar file passed as parameter
      * the method uses the BorlandGenerateClient task.
@@ -364,7 +359,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();
@@ -381,9 +376,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);
         }
     }
 
@@ -392,10 +385,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());
@@ -419,16 +410,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);
@@ -436,11 +425,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());
         }
@@ -456,13 +445,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);
@@ -471,7 +460,7 @@
             }
         }
 
-        buildBorlandStubs(homes.iterator());
+        buildBorlandStubs(homes);
 
         //add the gen files to the collection
         files.putAll(genfiles);
@@ -494,9 +483,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('/', '.');
     }
 
     /**
@@ -505,28 +493,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")) {
@@ -536,10 +531,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);
         }
     }
 
@@ -548,6 +541,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();
@@ -556,4 +550,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 a987b92..4e75eef 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
@@ -24,6 +24,7 @@
 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;
@@ -94,20 +95,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
 
     /**
@@ -174,7 +175,7 @@
 
     /**
      * Resolve the entity.
-     * @see org.xml.sax.EntityResolver#resolveEntity(String, String).
+     * @see org.xml.sax.EntityResolver#resolveEntity(String, String)
      * @param publicId The public identifier, or <code>null</code>
      *                 if none is available.
      * @param systemId The system identifier provided in the XML
@@ -182,11 +183,12 @@
      * @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 "
@@ -197,7 +199,7 @@
             }
         }
 
-        String dtdResourceName = (String) resourceDTDs.get(publicId);
+        String dtdResourceName = resourceDTDs.get(publicId);
         if (dtdResourceName != null) {
             InputStream is = this.getClass().getResourceAsStream(dtdResourceName);
             if (is != null) {
@@ -207,7 +209,7 @@
             }
         }
 
-        URL dtdUrl = (URL) urlDTDs.get(publicId);
+        URL dtdUrl = urlDTDs.get(publicId);
         if (dtdUrl != null) {
             try {
                 InputStream is = dtdUrl.openStream();
@@ -229,8 +231,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;
     }
 
     /**
@@ -254,13 +256,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
@@ -269,26 +271,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
@@ -299,6 +301,7 @@
      *        in this implementation.
      * @throws SAXException on error
      */
+    @Override
     public void endElement(String name) throws SAXException {
         processElement();
         currentText = "";
@@ -334,13 +337,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.
@@ -355,15 +357,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
@@ -374,8 +375,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 e9b7ed4..f582091 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,8 +161,10 @@
          *
          * @return an array of the values of this attribute class.
          */
+        @Override
         public String[] getValues() {
-            return new String[] {EJB_NAME, DIRECTORY, DESCRIPTOR, BASEJARNAME};
+            return new String[] { EJB_NAME, DIRECTORY, DESCRIPTOR,
+                BASEJARNAME };
         }
     }
 
@@ -178,20 +179,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 +209,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
@@ -348,7 +350,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
@@ -409,10 +410,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());
         }
     }
 
@@ -424,11 +425,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());
         }
     }
 
@@ -546,10 +547,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");
         }
     }
 
@@ -568,10 +569,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);
@@ -579,8 +581,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();
         }
@@ -591,7 +592,6 @@
             saxParserFactory.setValidating(true);
             SAXParser saxParser = saxParserFactory.newSAXParser();
 
-
             DirectoryScanner ds = getDirectoryScanner(config.descriptorDir);
             ds.scan();
             String[] files = ds.getIncludedFiles();
@@ -601,30 +601,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 7de0ba3..16bde5d 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
@@ -24,7 +24,6 @@
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.Set;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
@@ -37,9 +36,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;
@@ -118,7 +117,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
@@ -130,11 +129,6 @@
      */
     private DependencyAnalyzer dependencyAnalyzer;
 
-    /** No arg constructor */
-    public GenericDeploymentTool() {
-    }
-
-
     /**
      * Set the destination directory; required.
      * @param inDir the destination directory.
@@ -152,12 +146,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;
     }
@@ -234,7 +228,6 @@
                 combinedPath.append(config.classpath);
             }
         }
-
         return combinedPath;
     }
 
@@ -277,9 +270,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);
@@ -296,12 +290,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;
 
@@ -326,12 +320,11 @@
                                 File inputFile,
                                 String logicalFilename)
         throws BuildException {
-        InputStream iStream = null;
-        try {
-            if (!addedfiles.contains(logicalFilename)) {
-                iStream = Files.newInputStream(inputFile.toPath());
+        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
@@ -345,15 +338,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);
+            }
         }
     }
 
@@ -368,8 +358,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;
@@ -387,6 +376,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void processDescriptor(String descriptorFileName, SAXParser saxParser) {
 
         checkConfiguration(descriptorFileName, saxParser);
@@ -395,7 +385,7 @@
             handler = getDescriptorHandler(config.srcDir);
 
             // Retrive 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);
@@ -410,8 +400,6 @@
                 ejbFiles.put(MANIFEST, manifestFile);
             }
 
-
-
             // First the regular deployment descriptor
             ejbFiles.put(META_DIR + EJB_DD,
                          new File(config.descriptorDir, descriptorFileName));
@@ -436,7 +424,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...
@@ -450,27 +437,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);
         }
     }
 
@@ -488,7 +471,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
@@ -511,28 +493,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 {
-        InputStream 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
-                = Files.newInputStream(new File(config.descriptorDir, descriptorFileName).toPath());
+        /* 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;
     }
 
     /**
@@ -542,22 +513,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
@@ -573,14 +540,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) {
@@ -593,10 +560,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
@@ -609,9 +577,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;
@@ -651,11 +618,10 @@
      * @param ejbFiles a hashtable entryname -> 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.
@@ -680,16 +646,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);
@@ -698,7 +661,6 @@
             }
             return false;
         }
-
         return true;
     }
 
@@ -730,7 +692,6 @@
         if (manifestFile.exists()) {
             return manifestFile;
         }
-
         if (config.manifest != null) {
             return config.manifest;
         }
@@ -747,17 +708,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
@@ -773,18 +732,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 = 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());
@@ -796,46 +755,43 @@
 
             // Create the streams necessary to write the jarfile
 
-            jarStream = new JarOutputStream(Files.newOutputStream(jarfile.toPath()), 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 (String entryName : files.keySet()) {
+                    if (entryName.equals(MANIFEST)) {
+                        continue;
+                    }
+                    File entryFile = files.get(entryName);
+                    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);
+                        }
                     }
                 }
             }
@@ -845,8 +801,6 @@
                 + "'. Details: "
                 + ioe.getMessage();
             throw new BuildException(msg, ioe);
-        } finally {
-            FileUtils.close(jarStream);
         }
     } // end of writeJar
 
@@ -856,7 +810,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) {
@@ -865,9 +819,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());
@@ -878,10 +830,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);
@@ -893,7 +845,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
@@ -904,7 +855,6 @@
         if (classpathLoader != null) {
             return classpathLoader;
         }
-
         Path combinedClasspath = getCombinedClasspath();
 
         // only generate a new ClassLoader if we have a classpath
@@ -915,7 +865,6 @@
             classpathLoader
                 = getTask().getProject().createClassLoader(combinedClasspath);
         }
-
         return classpathLoader;
     }
 
@@ -925,11 +874,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 cbc8526..181720f 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;
 
 /**
@@ -107,7 +107,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
@@ -202,25 +202,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());
         }
     }
 
@@ -240,10 +241,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(
@@ -260,12 +261,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());
             }
         }
 
@@ -292,7 +290,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());
@@ -300,7 +298,6 @@
                 files.put(cmpDescriptors[i], cmpFile);
             }
         }
-
         return files;
     }
 
@@ -313,7 +310,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 5a6656f..c15a07a 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
@@ -23,10 +23,12 @@
 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;
@@ -34,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;
@@ -42,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;
 
 /**
@@ -114,7 +116,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;
@@ -150,15 +152,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]);
         }
     }
 
@@ -217,7 +215,7 @@
      *
      * @return The list of EJB files processed by the ejbc utility.
      */
-    public Hashtable getEjbFiles() {
+    public Hashtable<String, File> getEjbFiles() {
         return ejbFiles;
     }
 
@@ -236,16 +234,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);
     }
 
     /**
@@ -274,13 +264,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();
@@ -383,22 +373,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.");
             }
@@ -412,11 +397,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 commmand */
         String command;
@@ -428,6 +408,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);
 
         /*
@@ -498,18 +481,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();
     }
 
     /**
@@ -522,7 +501,7 @@
      */
     private String[] buildArgumentList(EjbInfo ejb) {
 
-        List arguments = new ArrayList();
+        List<String> arguments = new ArrayList<>();
 
         /* OPTIONAL COMMAND LINE PARAMETERS */
 
@@ -566,7 +545,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()]);
     }
 
     /**
@@ -591,6 +570,7 @@
      *
      */
     public class EjbcException extends Exception {
+        private static final long serialVersionUID = 1L;
 
         /**
          * Constructs an exception with the given descriptive message.
@@ -631,10 +611,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
 
@@ -660,7 +640,7 @@
          *         parsing.
          */
         public EjbInfo[] getEjbs() {
-            return (EjbInfo[]) ejbs.values().toArray(new EjbInfo[ejbs.size()]);
+            return ejbs.values().toArray(new EjbInfo[ejbs.size()]);
         }
 
         /**
@@ -713,35 +693,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 = Files.newInputStream(Paths.get(location)); //NOSONAR
                     }
                 }
             } catch (IOException e) {
-                return super.resolveEntity(publicId, systemId);
             }
-
             if (inputStream == null) {
                 return super.resolveEntity(publicId, systemId);
-            } else {
-                return new InputSource(inputStream);
             }
+            return new InputSource(inputStream);
         }
 
         /**
@@ -752,6 +727,7 @@
          *             (if any).
          * @throws SAXException If the parser cannot process the document.
          */
+        @Override
         public void startElement(String name, AttributeList atts)
                 throws SAXException {
 
@@ -764,13 +740,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;
             }
         }
@@ -784,9 +760,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);
         }
 
@@ -796,6 +772,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 {
 
             /*
@@ -831,30 +808,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);
             }
         }
@@ -872,18 +849,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);
             }
         }
@@ -904,7 +882,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.
@@ -926,9 +904,8 @@
             if (name == null) {
                 if (implementation == null) {
                     return "[unnamed]";
-                } else {
-                    return implementation.getClassName();
                 }
+                return implementation.getClassName();
             }
             return name;
         }
@@ -1002,7 +979,7 @@
         }
 
         public void setCmp(String cmp) {
-            setCmp(cmp.equals("Container"));
+            setCmp("Container".equals(cmp));
         }
 
         public boolean getCmp() {
@@ -1014,7 +991,7 @@
         }
 
         public void setIiop(String iiop) {
-            setIiop(iiop.equals("true"));
+            setIiop(Boolean.parseBoolean(iiop));
         }
 
         public boolean getIiop() {
@@ -1026,7 +1003,7 @@
         }
 
         public void setHasession(String hasession) {
-            setHasession(hasession.equals("true"));
+            setHasession(Boolean.parseBoolean(hasession));
         }
 
         public boolean getHasession() {
@@ -1037,7 +1014,7 @@
             cmpDescriptors.add(descriptor);
         }
 
-        public List getCmpDescriptors() {
+        public List<String> getCmpDescriptors() {
             return cmpDescriptors;
         }
 
@@ -1054,53 +1031,52 @@
 
             /* 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.");
             }
         }
 
@@ -1149,9 +1125,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;
@@ -1160,9 +1135,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);
@@ -1172,9 +1146,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);
@@ -1237,7 +1211,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?
 
             /*
@@ -1245,7 +1219,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);
@@ -1266,7 +1239,7 @@
                 }
             }
 
-            return (allClassesFound) ? destClassesModified : -1;
+            return allClassesFound ? destClassesModified : -1;
         }
 
         /**
@@ -1330,6 +1303,7 @@
          *
          * @return A String representing the EjbInfo instance.
          */
+        @Override
         public String toString() {
             String s = "EJB name: " + name
                         + "\n\r              home:      " + home
@@ -1341,7 +1315,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();
             }
@@ -1446,6 +1420,7 @@
          *
          * @return String representing the fully qualified class name.
          */
+        @Override
         public String toString() {
             return getQualifiedClassName();
         }
@@ -1477,18 +1452,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 ee5dc85..147e5d5 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 cp;
+            return new Path(getProject()).concatSystemClasspath("last");
+        } 
+        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 79f4574..c3a48ec 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);
             return;
         }
@@ -84,15 +83,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);
     }
 
     /**
@@ -102,6 +101,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 0d9bd13..71c0860 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
@@ -20,9 +20,9 @@
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
-import java.util.Enumeration;
+import java.util.Arrays;
 import java.util.Hashtable;
-
+import java.util.List;
 import javax.xml.parsers.SAXParser;
 
 import org.apache.tools.ant.AntClassLoader;
@@ -330,6 +330,7 @@
     /* ------------- */
 
     /** {@inheritDoc}. */
+    @Override
     public void processDescriptor(String aDescriptorName, SAXParser saxParser) {
 
         descriptorName = aDescriptorName;
@@ -347,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
@@ -367,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()) {
@@ -382,6 +385,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     protected File getVendorOutputJarFile(String baseName) {
         return new File(getDestDir(), baseName + suffix);
     }
@@ -459,6 +463,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     protected String getJarBaseName(String descriptorFileName) {
 
         String baseName = null;
@@ -500,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);
@@ -519,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);
 
@@ -554,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);
@@ -582,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) {
@@ -731,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.");
         }
     }
 
@@ -776,17 +782,15 @@
     }
 
     /**
-     * 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();
@@ -800,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/WeblogicDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java
index cc1bd90..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
@@ -23,7 +23,7 @@
 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;
@@ -36,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;
@@ -140,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
@@ -159,7 +161,6 @@
         sysprops.add(sysp);
     }
 
-
     /**
      * Get the classpath to the weblogic classpaths.
      * @return the classpath to configure.
@@ -181,7 +182,6 @@
         this.outputDir = outputDir;
     }
 
-
     /**
      * Optional classpath to WL6.0.
      * Weblogic 6.0 will give a warning if the home and remote interfaces
@@ -196,7 +196,6 @@
         this.wlClasspath = wlClasspath;
     }
 
-
     /**
      * The compiler (switch <code>-compiler</code>) to use; optional.
      * This allows for the selection of a different compiler
@@ -213,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.
@@ -229,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
@@ -240,7 +237,6 @@
         this.jvmDebugLevel = jvmDebugLevel;
     }
 
-
     /**
      * Get the debug level.
      * @return the jvm debug level (may be null).
@@ -249,8 +245,6 @@
         return jvmDebugLevel;
     }
 
-
-
     /**
      * Setter used to store the suffix for the generated weblogic jar file.
      *
@@ -260,7 +254,6 @@
         this.jarSuffix = inString;
     }
 
-
     /**
      * controls whether the generic file used as input to
      * ejbc is retained; defaults to false
@@ -271,7 +264,6 @@
         this.keepGeneric = inValue;
     }
 
-
     /**
      * Controls whether weblogic will keep the generated Java
      * files used to build the class files added to the
@@ -280,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.
@@ -293,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
@@ -315,7 +305,6 @@
         this.ejbcClass = ejbcClass;
     }
 
-
     /**
      * Get the ejbc compiler class.
      * @return the name of the ejbc compiler class.
@@ -324,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
@@ -336,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
@@ -348,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
@@ -360,7 +346,6 @@
         this.ejb11DTD = inString;
     }
 
-
     /**
      * Set the value of the oldCMP scheme. This is an antonym for newCMP
      * @ant.attribute ignore="true'
@@ -370,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.
@@ -387,7 +371,6 @@
         this.newCMP = newCMP;
     }
 
-
     /**
      * Do not EJBC the jar after it has been put together;
      * optional, default false
@@ -397,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);
@@ -410,7 +393,6 @@
         handler.registerDTD(PUBLICID_EJB20, DEFAULT_WL60_EJB20_DTD_LOCATION);
     }
 
-
     /**
      * Get the weblogic descriptor handler.
      * @param srcDir the source directory.
@@ -419,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
@@ -441,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
@@ -486,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);
@@ -495,36 +473,29 @@
                 DescriptorHandler handler
                     = getWeblogicDescriptorHandler(ejbDescriptor.getParentFile());
 
-                saxParser.parse(new InputSource(Files.newInputStream(weblogicDD.toPath())),
-                                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
@@ -535,7 +506,6 @@
      *      jarfile.
      */
     private void buildWeblogicJar(File sourceJar, File destJar, String publicId) {
-        Java javaTask = null;
 
         if (noEJBC) {
             try {
@@ -552,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);
@@ -592,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);
             }
@@ -636,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
@@ -654,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);
@@ -671,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
@@ -726,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())) {
@@ -768,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.
@@ -776,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 {
@@ -812,11 +767,8 @@
                     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()) {
@@ -825,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
@@ -839,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);
                         }
@@ -878,11 +833,11 @@
             }
             if (genericLoader != null
                 && genericLoader instanceof AntClassLoader) {
+                @SuppressWarnings("resource")
                 AntClassLoader loader = (AntClassLoader) genericLoader;
                 loader.cleanup();
             }
         }
-
         return rebuild;
     }
 
@@ -905,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 63caf50..6acdc47 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
@@ -23,7 +23,6 @@
 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 -> 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 @@
                 }
                 // Theres 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;
@@ -779,11 +749,8 @@
                     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,17 +789,15 @@
                 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
             FileUtils.close(genericJar);
@@ -846,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 2c06daf..1d748e4 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 bb28cd6..5c3240d 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 b3cfddc..4747821 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 00d4599..7f951d9 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,16 +20,15 @@
 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;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.types.FileSet;
-import org.apache.tools.ant.util.FileUtils;
 
 /**
  * A set of useful methods relating to extensions.
@@ -49,19 +48,10 @@
      * @param adapters the list of ExtensionAdapterss 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));
     }
 
     /**
@@ -72,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);
             }
         }
     }
@@ -92,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;
 
@@ -116,7 +102,7 @@
                 loadExtensions(file, extensions, includeImpl, includeURL);
             }
         }
-        return (Extension[]) extensions.toArray(new Extension[extensions.size()]);
+        return extensions.toArray(new Extension[extensions.size()]);
     }
 
     /**
@@ -127,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 {
-            FileUtils.close(jarFile);
         }
     }
 
@@ -158,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) {
@@ -205,18 +185,14 @@
      */
     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 {
-            FileUtils.close(jarFile);
         }
     }
 
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 cebcf0d..84ba74a 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 librarys
      * 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 da12cd0..0f31657 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 librarys
      * 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 a5105e2..6e53294 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
@@ -22,15 +22,17 @@
 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.
@@ -72,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.
@@ -106,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();
     }
@@ -143,6 +146,7 @@
      *
      * @throws BuildException if the task fails.
      */
+    @Override
     public void execute() throws BuildException {
         validate();
 
@@ -160,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);
 
@@ -188,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);
         }
     }
 
@@ -199,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());
         }
     }
 
@@ -215,13 +215,9 @@
      * @throws IOException if error writing file
      */
     private void writeManifest(final Manifest manifest) throws IOException {
-        OutputStream output = null;
-        try {
-            output = Files.newOutputStream(destFile.toPath());
+        try (OutputStream output = Files.newOutputStream(destFile.toPath())) {
             manifest.write(output);
             output.flush();
-        } finally {
-            FileUtils.close(output);
         }
     }
 
@@ -237,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);
         }
     }
 
@@ -259,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(" ")));
     }
 
     /**
@@ -276,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 c13194f..5cdc32f 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 b21719e..bade00f 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 b0ee4f8..d3eb056 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 1e4bb7b..ea8405c 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 685468a..42e2be1 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
@@ -23,11 +23,12 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.io.OutputStream;
 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;
@@ -138,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.
@@ -269,7 +270,7 @@
      * @param set the fileset to be added
      */
     public void addFileset(FileSet set) {
-        filesets.addElement(set);
+        filesets.add(set);
     }
 
     /**
@@ -281,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.",
@@ -319,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) {
@@ -362,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.
@@ -392,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);
     }
 
     /**
@@ -431,11 +423,9 @@
      * are not overwritten.  Bundle's encoding scheme is used.
      */
     private void loadResourceMap(InputStream ins) throws BuildException {
-        try {
-            BufferedReader in = null;
-            InputStreamReader isr = new InputStreamReader(ins, bundleEncoding);
-            in = new BufferedReader(isr);
-            String line = null;
+        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)) {
@@ -475,9 +465,6 @@
                     }
                 }
             }
-            if (in != null) {
-                in.close();
-            }
         } catch (IOException ioe) {
             throw new BuildException(ioe.getMessage(), getLocation());
         }
@@ -497,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++) {
@@ -549,18 +534,14 @@
     }
 
     private void translateOneFile(File src, File dest) throws IOException {
-        BufferedWriter out = null;
-        BufferedReader in = null;
-        try {
-            OutputStream fos = Files.newOutputStream(dest.toPath());
-            out = new BufferedWriter(new OutputStreamWriter(fos, destEncoding));
-            InputStream fis = Files.newInputStream(src.toPath());
-            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;"
 
@@ -602,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);
@@ -625,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 5cef009..53b234b 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
@@ -28,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;
@@ -39,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;
 
@@ -60,9 +58,9 @@
  */
 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;
 
@@ -85,7 +83,7 @@
      * @param set the FileSet to add.
      */
     public void addFileset(FileSet set) {
-        filesets.addElement(set);
+        filesets.add(set);
     }
 
     /**
@@ -230,9 +228,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()){
@@ -271,6 +267,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()));
@@ -287,14 +284,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);
@@ -302,33 +295,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();
             }
 
-            OutputStream stream = null;
-            try {
-                stream = Files.newOutputStream(newFile.toPath());
-
+            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();
             }
@@ -337,15 +322,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);
-            }
         }
     }
 
@@ -353,6 +329,7 @@
      * Executes the Task.
      * @throws BuildException on error.
      */
+    @Override
     public void execute() throws BuildException {
 
         validateAttributes();
@@ -363,29 +340,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){
@@ -406,16 +374,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 fdbde74..21d8478 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 c7a33a1..6e7f118 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
@@ -53,8 +53,8 @@
     /**
      *  All the valid actions that weblogic.deploy permits *
      */
-    private static final String[] VALID_ACTIONS
-        = {ACTION_DELETE, ACTION_DEPLOY, ACTION_LIST, ACTION_UNDEPLOY, ACTION_UPDATE};
+    private static final String[] VALID_ACTIONS = { ACTION_DELETE,
+        ACTION_DEPLOY, ACTION_LIST, ACTION_UNDEPLOY, ACTION_UPDATE };
 
     /**
      *  Description of the Field
@@ -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. <p>
      *
@@ -161,6 +155,7 @@
      *@exception  BuildException                       Description
      *      of Exception
      */
+    @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 da87509..e186dcb 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 org.apache.tools.ant.BuildException if the attributes are invalid or incomplete.
      */
+    @Override
     public void deploy() {
         Java java = new Java(getTask());
         java.setFork(true);
@@ -79,6 +80,7 @@
      *  be supplied.
      *  @exception org.apache.tools.ant.BuildException if the attributes are invalid or incomplete
      */
+    @Override
     public void validateAttributes() throws BuildException {
         super.validateAttributes();
 
@@ -92,22 +94,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);
         }
     }
 
@@ -119,17 +121,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;
     }
 
     /**
@@ -137,19 +139,16 @@
      *  <p>Valid actions are contained in the static array VALID_ACTIONS
      *  @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 f5d126e..e3bca20 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 86713da..c35db1b 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
@@ -523,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/JavahAdapterFactory.java b/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java
index 481a97d..2244e5b 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,7 +42,8 @@
     public static String getDefault() {
         if (JavaEnvUtils.isKaffe()) {
             return Kaffeh.IMPLEMENTATION_NAME;
-        } else if (JavaEnvUtils.isGij()) {
+        }
+        if (JavaEnvUtils.isGij()) {
             return Gcjh.IMPLEMENTATION_NAME;
         }
         return ForkingJavah.IMPLEMENTATION_NAME;
@@ -84,20 +85,23 @@
         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 (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));
         }
-
         return new ForkingJavah();
     }
 
@@ -113,7 +117,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 c608583..abc52e3 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,9 +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;
 import org.apache.tools.ant.Task;
@@ -42,6 +45,8 @@
 import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.LoaderUtils;
 
+import jdepend.textui.JDepend;
+
 /**
  * Runs JDepend tests.
  *
@@ -53,7 +58,6 @@
  *
  */
 public class JDependTask extends Task {
-    //private CommandlineJava commandline = new CommandlineJava();
 
     // required attributes
     private Path sourcesPath; // Deprecated!
@@ -71,7 +75,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 +83,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 +192,7 @@
      * @return a source path
      * @deprecated since 1.6.x.
      */
+    @Deprecated
     public Path createSourcespath() {
         if (sourcesPath == null) {
             sourcesPath = new Path(getProject());
@@ -201,6 +205,7 @@
      * @return the sources path
      * @deprecated since 1.6.x.
      */
+    @Deprecated
     public Path getSourcespath() {
         return sourcesPath;
     }
@@ -320,11 +325,12 @@
      * @see EnumeratedAttribute
      */
     public static class FormatAttribute extends EnumeratedAttribute {
-        private String [] formats = new String[]{"xml", "text"};
+        private String[] formats = new String[] { "xml", "text" };
 
         /**
          * @return the enumerated values
          */
+        @Override
         public String[] getValues() {
             return formats;
         }
@@ -368,11 +374,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 +387,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 +430,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 +474,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 +498,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 +521,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 +533,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 +560,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 +581,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 +625,17 @@
         }
         return new ExecuteWatchdog(getTimeout().longValue());
     }
+
+    private Optional<Path> getWorkingPath() {
+        Optional<Path> result = Optional.ofNullable(getClassespath());
+        if (result.isPresent()) {
+            return result;
+        }
+        result = Optional.ofNullable(getSourcespath());
+        if (result.isPresent()) {
+            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 f5767e6..4e4b0aa 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
@@ -54,11 +54,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;
     }
 
@@ -67,7 +75,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());
         }
@@ -78,7 +86,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 {
@@ -91,7 +99,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());
         }
@@ -102,7 +110,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 {
@@ -114,7 +122,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;
     }
 
@@ -122,15 +130,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);
@@ -161,23 +170,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 4f3cff9..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
@@ -29,6 +29,7 @@
 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(Files.newOutputStream(Paths.get(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.
@@ -223,10 +207,10 @@
             return;
         }
         try (ZipFile zipf = new ZipFile(f)) {
-            Enumeration entries = zipf.entries();
+            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.
@@ -244,33 +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();
                 }
             }
         }
     }
 
-
     /*
      * Adds contents of a directory to the output.
      */
@@ -290,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
@@ -301,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 = Files.newInputStream(file.toPath());
+            try (InputStream input = Files.newInputStream(file.toPath())) {
                 String className = ClassNameReader.getClassName(input);
 
                 if (className != null) {
@@ -311,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;
     }
 
 
@@ -337,12 +313,9 @@
         if (!compress) {
             entry.setCrc(calcChecksum(file));
         }
-        InputStream input = Files.newInputStream(file.toPath());
-
-        addToOutputStream(output, input, entry);
+        addToOutputStream(output, Files.newInputStream(file.toPath()), entry);
     }
 
-
     /*
      * A convenience method that several other methods might call.
      */
@@ -356,7 +329,7 @@
             return;
         }
 
-        int numBytes = -1;
+        int numBytes;
 
         while ((numBytes = input.read(buffer)) > 0) {
             output.write(buffer, 0, numBytes);
@@ -365,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
@@ -387,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";
                 }
@@ -416,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(Files.newInputStream(f.toPath()));
-
-        return calcChecksum(in);
+        return calcChecksum(
+            new BufferedInputStream(Files.newInputStream(f.toPath())));
     }
 
-
     /*
      * Necessary in the case where you add a entry that
      * is not compressed.
@@ -435,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 9832e3e..4af9f3d 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 {
 
@@ -496,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")
@@ -504,12 +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);
-                }
+                log("all files are up to date", Project.MSG_VERBOSE);
             }
         }
     }
@@ -519,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));
     }
 
     /**
@@ -542,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);
         }
     }
 
@@ -566,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);
             }
@@ -612,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.
@@ -647,7 +631,6 @@
             return null;
         }
         String javaFileName = mangler.mapJspToJavaName(srcFile);
-        //        String srcFileDir=srcFile.getParent();
         return new File(dest, javaFileName);
     }
 
@@ -658,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();
@@ -694,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 850c6bc..4cde079 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 exensionless 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 45a427a..779b01b 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 containg the source jsp's
      */
     public void setSrc(File dirName) {
-
         sourceDirectory = dirName;
     }
 
@@ -245,7 +238,6 @@
      * @param dirName the directory containg 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 5c4d0e3..303ef6f 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 an argument oneple 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 80ed601..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,9 +154,8 @@
         if (p == null) {
             p = new Path(getProject());
             return p.concatSystemClasspath("only");
-        } else {
-            return p.concatSystemClasspath("ignore");
         }
+        return p.concatSystemClasspath("ignore");
     }
 
     /**
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 026412f..b229d56 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
@@ -23,10 +23,6 @@
 import java.io.InputStream;
 import java.net.URL;
 import java.nio.file.Files;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Vector;
-
 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
 
     /**
@@ -257,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"));
@@ -352,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
@@ -372,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 55e7a5d..0462969 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 f41b96f..fb5d44b 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 46d6c61..975de68 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 325f44c..39d0ab3 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..1ca4a0c 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,33 @@
  */
 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       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        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 +87,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 bfcbfed..26ef424 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 errored.
      * @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 6587b1d..81841a0 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
@@ -31,6 +31,7 @@
 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;
 
@@ -58,6 +59,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;
@@ -73,19 +86,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.
      *
@@ -102,18 +102,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;
         }
     }
 
@@ -125,12 +126,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;
+            }
         }
     }
 
@@ -266,7 +273,6 @@
         this.project = project;
     }
 
-
     /**
      * @since Ant 1.6
      */
@@ -279,7 +285,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);
@@ -296,26 +302,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");
@@ -333,8 +334,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) {
@@ -354,8 +355,9 @@
      */
     public static class TypeAttribute extends EnumeratedAttribute {
         /** {@inheritDoc}. */
+        @Override
         public String[] getValues() {
-            return new String[] {"plain", "xml", "brief", "failure"};
+            return new String[] { "plain", "xml", "brief", "failure" };
         }
     }
 
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 c3bb18d..ef51fff 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 dcb2a98..e32403c 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
@@ -33,6 +33,7 @@
 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;
@@ -135,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;
@@ -186,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
      *
@@ -368,8 +370,8 @@
          */
         @Override
         public String[] getValues() {
-            return new String[] {"true", "yes", "false", "no",
-                                 "on", "off", "withOutAndErr"};
+            return new String[] { "true", "yes", "false", "no", "on", "off",
+                "withOutAndErr" };
         }
 
         /**
@@ -584,7 +586,7 @@
      * @since Ant 1.2
      */
     public void addTest(final JUnitTest test) {
-        tests.addElement(test);
+        tests.add(test);
         preConfigure(test);
     }
 
@@ -598,7 +600,7 @@
      */
     public BatchTest createBatchTest() {
         final BatchTest test = new BatchTest(getProject());
-        batchTests.addElement(test);
+        batchTests.add(test);
         preConfigure(test);
         return test;
     }
@@ -610,7 +612,7 @@
      * @since Ant 1.2
      */
     public void addFormatter(final FormatterElement fe) {
-        formatters.addElement(fe);
+        formatters.add(fe);
     }
 
     /**
@@ -714,11 +716,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;
     }
@@ -776,12 +776,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());
         }
@@ -807,28 +807,19 @@
             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,25 +838,22 @@
         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);
@@ -890,12 +878,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);
@@ -906,7 +895,7 @@
         }
 
         private final JUnitTask masterTask;
-        private final Iterator<List> iterator;
+        private final Iterator<List<JUnitTest>> iterator;
         private final int id;
     }
 
@@ -917,8 +906,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();
             }
@@ -937,14 +926,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);
             }
@@ -953,9 +942,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 */
@@ -968,24 +957,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();
 
@@ -1028,7 +1018,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
@@ -1042,13 +1032,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());
     }
@@ -1070,8 +1060,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");
         }
     }
@@ -1082,23 +1072,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) {
@@ -1119,8 +1107,6 @@
                 }
             }
             writer.flush();
-            writer.close();
-            writer = null;
 
             // execute the test and get the return code
             final ExecuteWatchdog watchdog = createWatchdog();
@@ -1131,8 +1117,6 @@
             log(e.toString(), Project.MSG_ERR);
             throw new BuildException(e);
         } finally {
-            FileUtils.close(writer);
-
             try {
                 FILE_UTILS.tryHardToDelete(casesFile);
             } catch (final Exception e) {
@@ -1146,7 +1130,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);
     }
 
@@ -1177,7 +1161,7 @@
 
         CommandlineJava cmd;
         try {
-            cmd = (CommandlineJava) (getCommandline().clone());
+            cmd = getCommandline().clone();
         } catch (final CloneNotSupportedException e) {
             throw new BuildException("This shouldn't happen", e, getLocation());
         }
@@ -1213,7 +1197,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];
@@ -1226,7 +1210,7 @@
                     formatterArg.append(outFile);
                 }
                 cmd.createArgument().setValue(formatterArg.toString());
-                formatterArg = new StringBuffer();
+                formatterArg = new StringBuilder();
             }
         }
 
@@ -1236,17 +1220,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 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());
@@ -1328,9 +1309,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);
             }
         }
 
@@ -1343,8 +1324,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));
@@ -1356,7 +1337,6 @@
         }
     }
 
-
     /**
      * check for the parameter being "withoutanderr" in a locale-independent way.
      * @param summaryOption the summary option -can be null
@@ -1400,9 +1380,9 @@
                 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 "
@@ -1501,9 +1481,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);
     }
 
 
@@ -1580,7 +1559,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",
@@ -1691,12 +1670,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);
     }
 
@@ -1713,10 +1694,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();
             }
@@ -1730,15 +1708,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.");
             }
         }
     }
@@ -1775,7 +1748,8 @@
         for (String path : modulePath.list()) {
             final File modulePathEntry = getProject().resolveFile(path);
             if (modulePathEntry.isDirectory() && !hasModuleInfo(modulePathEntry)) {
-                final File[] modules = modulePathEntry.listFiles((dir,name)->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(
@@ -1797,9 +1771,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));
     }
 
     /**
@@ -1808,6 +1782,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()];
@@ -2181,7 +2156,7 @@
         /** {@inheritDoc}. */
         @Override
         public String[] getValues() {
-            return new String[] {ONCE, PER_TEST, PER_BATCH};
+            return new String[] { ONCE, PER_TEST, PER_BATCH };
         }
     }
 
@@ -2195,9 +2170,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())) {
@@ -2206,14 +2182,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);
                 }
             }
         }
@@ -2361,7 +2333,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 835c013..2ec5653 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 ea7524d..4009666 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
@@ -29,12 +29,12 @@
 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;
@@ -73,22 +73,50 @@
  */
 
 public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestRunnerMirror {
+    private static final String JUNIT_4_TEST_ADAPTER
+    = "junit.framework.JUnit4TestAdapter";
 
-    /**
-     * Holds the registered formatters.
-     */
-    private final Vector<JUnitTaskMirror.JUnitResultFormatterMirror> formatters = new Vector();
-
-    /**
-     * Collects TestResults.
-     */
-    private IgnoredTestResult res;
+    private static final String[] DEFAULT_TRACE_FILTERS = new String[] {
+            "junit.framework.TestCase",
+            "junit.framework.TestResult",
+            "junit.framework.TestSuite",
+            "junit.framework.Assert.", // don't filter AssertionFailure
+            "junit.swingui.TestRunner",
+            "junit.awtui.TestRunner",
+            "junit.textui.TestRunner",
+            "java.lang.reflect.Method.invoke(",
+            "sun.reflect.",
+            "org.apache.tools.ant.",
+            // JUnit 4 support:
+            "org.junit.",
+            "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?
      */
@@ -101,27 +129,6 @@
      */
     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",
-                "junit.framework.TestResult",
-                "junit.framework.TestSuite",
-                "junit.framework.Assert.", // don't filter AssertionFailure
-                "junit.swingui.TestRunner",
-                "junit.awtui.TestRunner",
-                "junit.textui.TestRunner",
-                "java.lang.reflect.Method.invoke(",
-                "sun.reflect.",
-                "org.apache.tools.ant.",
-                // JUnit 4 support:
-                "org.junit.",
-                "junit.framework.JUnit4TestAdapter",
-                " more",
-        };
-
-
     /**
      * Do we stop on errors.
      */
@@ -151,9 +158,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;
 
@@ -163,12 +167,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;
 
@@ -357,6 +355,7 @@
     /**
      * Run the test.
      */
+    @Override
     public void run() {
         res = new IgnoredTestResult();
         res.addListener(wrapListener(this));
@@ -377,7 +376,7 @@
         try {
 
             try {
-                Class testClass = null;
+                Class<?> testClass;
                 if (loader == null) {
                     testClass = Class.forName(junitTest.getName());
                 } else {
@@ -391,24 +390,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)) {
@@ -434,64 +433,69 @@
                     // 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;
-                            }
-                        } else {
-                            junit4TestAdapterClass =
-                                Class.forName(JUNIT_4_TEST_ADAPTER,
-                                              true, loader);
-                            if (testMethodsSpecified) {
+                        try {
+                            Class.forName("java.lang.annotation.Annotation");
+                            junit4TestAdapterCacheClass = Class.forName(
+                                "org.apache.tools.ant.taskdefs.optional.junit.CustomJUnit4TestAdapterCache");
+                            if (loader == null) {
                                 junit4TestAdapterClass =
-                                    Class.forName(
-                                        "org.apache.tools.ant.taskdefs.optional.junit.JUnit4TestMethodAdapter",
-                                        true, loader);
-                                useSingleMethodAdapter = true;
+                                    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;
+                                }
                             }
+                        } 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};
-                            actualParams = new Object[] {testClass, methods};
+                            formalParams =
+                                new Class[] { Class.class, String[].class };
+                            actualParams = new Object[] { testClass, methods };
                         } else {
-                            formalParams = new Class[] {Class.class, Class.forName("junit.framework.JUnit4TestAdapterCache")};
-                            actualParams = new Object[] {testClass, junit4TestAdapterCacheClass.getMethod("getInstance").invoke(null)};
+                            formalParams =
+                                new Class[] { Class.class, Class.forName(
+                                    "junit.framework.JUnit4TestAdapterCache") };
+                            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.
 
@@ -511,9 +515,7 @@
                             suite = testSuite;
                         }
                     }
-
                 }
-
             } catch (final Throwable e) {
                 retCode = ERRORS;
                 exception = e;
@@ -588,12 +590,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!
@@ -603,17 +606,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;
@@ -621,22 +625,26 @@
 
         // check if we have any inner classes that contain suitable test methods
         for (final Class<?> innerClass : testClass.getDeclaredClasses()) {
-            if (containsTests(innerClass, isJUnit4) || containsTests(innerClass, !isJUnit4)) {
+            if (containsTests(innerClass, isJUnit4)
+                || containsTests(innerClass, !isJUnit4)) {
                 return true;
             }
         }
 
-        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) {
+            }
+            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 run and fails in the
                  * IDEs I've tried... so I'm happy handing the class to JUnit to try and run, and let JUnit
@@ -656,16 +664,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;
             }
         }
@@ -679,6 +690,7 @@
      *
      * @return 2 if errors occurred, 1 if tests failed else 0.
      */
+    @Override
     public int getRetCode() {
         return retCode;
     }
@@ -689,6 +701,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 + ")");
@@ -700,6 +713,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 + ")");
@@ -709,10 +723,8 @@
         if (logTestListenerEvents) {
             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());
@@ -743,6 +755,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);
     }
@@ -754,6 +767,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() + ")");
@@ -767,6 +781,7 @@
      * @since Ant 1.6
      * @param permissions the permissions to use.
      */
+    @Override
     public void setPermissions(final Permissions permissions) {
         perm = permissions;
     }
@@ -775,6 +790,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
@@ -794,12 +810,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);
@@ -807,6 +825,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void handleFlush(final String output) {
         if (systemOut != null) {
             systemOut.print(output);
@@ -814,6 +833,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void handleErrorFlush(final String output) {
         if (systemError != null) {
             systemError.print(output);
@@ -824,7 +844,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);
@@ -856,6 +876,7 @@
     }
 
     /** {@inheritDoc}. */
+    @Override
     public void addFormatter(final JUnitTaskMirror.JUnitResultFormatterMirror f) {
         formatters.addElement(f);
     }
@@ -966,19 +987,13 @@
         }
 
         // 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 java.io.BufferedReader reader =
-                    new java.io.BufferedReader(new java.io.FileReader(args[0]));
-                String testCaseName;
-                String[] testMethodNames;
+            try (
+                final BufferedReader reader =
+                    new BufferedReader(new java.io.FileReader(args[0]))){
                 int code = 0;
                 boolean errorOccurred = false;
                 boolean failureOccurred = false;
@@ -987,6 +1002,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;
@@ -1041,43 +1058,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(),
@@ -1279,14 +1305,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++;
@@ -1294,7 +1325,7 @@
                 errors++;
             }
         }
-        return new int[] {failures, errors};
+        return new int[] { failures, errors };
     }
 
 } // JUnitTestRunner
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 9a21cae..5ac988e 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 07264b7..85cfb0c 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 e381a70..a500839 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 &&
@@ -57,6 +57,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) {
@@ -67,25 +68,32 @@
     // no need to implement the rest
     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) {}
 
     private void tearDown() {
         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()
@@ -111,7 +119,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
@@ -122,9 +130,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
@@ -133,9 +141,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 416c10d..d62a847 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 92e3553..b877c0b 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
@@ -24,8 +24,8 @@
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.nio.file.Files;
-import java.util.Enumeration;
 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
@@ -216,7 +204,8 @@
         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()) {
@@ -247,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 244b8c1..f8059fe 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
@@ -25,13 +25,14 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
 import java.io.Writer;
+import java.util.function.UnaryOperator;
 import java.nio.file.Files;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.taskdefs.optional.Native2Ascii;
 import org.apache.tools.ant.util.Native2AsciiUtils;
-import org.apache.tools.ant.util.StringUtils;
 
 /**
  * Encapsulates the built-in Native2Ascii implementation.
@@ -48,8 +49,10 @@
         boolean reverse = args.getReverse();
         String encoding = args.getEncoding();
         try (BufferedReader input = getReader(srcFile, encoding, reverse);
-             Writer output = getWriter(destFile, encoding, reverse)) {
-            translate(input, output, 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);
@@ -79,15 +82,12 @@
     }
 
     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 3cd52af..438bfe9 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/SunNative2Ascii.java b/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/SunNative2Ascii.java
index fac94b1..fdcce7d 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 a9d079c..2a52390 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
@@ -29,16 +29,16 @@
 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;
@@ -119,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;
@@ -182,6 +182,7 @@
      *
      */
     protected static class FTPFileProxy extends File {
+        private static final long serialVersionUID = 1L;
 
         private final FTPFile file;
         private final String[] parts;
@@ -213,6 +214,7 @@
         /* (non-Javadoc)
          * @see java.io.File#exists()
          */
+        @Override
         public boolean exists() {
             return true;
         }
@@ -221,6 +223,7 @@
         /* (non-Javadoc)
          * @see java.io.File#getAbsolutePath()
          */
+        @Override
         public String getAbsolutePath() {
             return name;
         }
@@ -229,6 +232,7 @@
         /* (non-Javadoc)
          * @see java.io.File#getName()
          */
+        @Override
         public String getName() {
             return parts.length > 0 ? parts[parts.length - 1] : name;
         }
@@ -237,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++){
@@ -249,6 +254,7 @@
         /* (non-Javadoc)
          * @see java.io.File#getPath()
          */
+        @Override
         public String getPath() {
             return name;
         }
@@ -258,6 +264,7 @@
          * FTP files are stored as absolute paths
          * @return true
          */
+        @Override
         public boolean isAbsolute() {
             return true;
         }
@@ -266,6 +273,7 @@
         /* (non-Javadoc)
          * @see java.io.File#isDirectory()
          */
+        @Override
         public boolean isDirectory() {
             return file == null;
         }
@@ -274,6 +282,7 @@
         /* (non-Javadoc)
          * @see java.io.File#isFile()
          */
+        @Override
         public boolean isFile() {
             return file != null;
         }
@@ -284,6 +293,7 @@
          *
          * @return  false
          */
+        @Override
         public boolean isHidden() {
             return false;
         }
@@ -292,6 +302,7 @@
         /* (non-Javadoc)
          * @see java.io.File#lastModified()
          */
+        @Override
         public long lastModified() {
             if (file != null) {
                 return file.getTimestamp().getTimeInMillis();
@@ -303,6 +314,7 @@
         /* (non-Javadoc)
          * @see java.io.File#length()
          */
+        @Override
         public long length() {
             if (file != null) {
                 return file.getSize();
@@ -348,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'
@@ -358,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();
@@ -386,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++) {
@@ -411,75 +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.
          *
@@ -561,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);
@@ -623,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
@@ -658,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();
@@ -673,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) {
@@ -706,6 +712,7 @@
         public FTPFile[] listFiles(String directory) {
             return listFiles(directory, true);
         }
+
         private void checkRemoteSensitivity(FTPFile[] array, String directory) {
             if (array == null) {
                 return;
@@ -714,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 "
@@ -754,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)));
@@ -767,6 +775,7 @@
             }
             return result.toString();
         }
+
         /**
          * an AntFTPFile is a representation of a remote file
          * @since Ant 1.6
@@ -810,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 unsensitive way
              * @param parentPath        where we are
@@ -864,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
@@ -879,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
@@ -886,6 +898,7 @@
             public String getLink() {
                 return ftpFile.getLink();
             }
+
             /**
              * get the name of the file
              * @return the name of the file
@@ -893,6 +906,7 @@
             public String getName() {
                 return ftpFile.getName();
             }
+
             /**
              * find out the absolute path of the file
              * @return absolute path as string
@@ -900,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.
@@ -913,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,
@@ -939,6 +955,7 @@
                 }
                 return relativePath;
             }
+
             /**
              * get the relative path of this file
              * @param currentPath          base path
@@ -946,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) {
@@ -975,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"
@@ -988,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.
@@ -1009,6 +1021,7 @@
             public boolean isDirectory() {
                 return ftpFile.isDirectory();
             }
+
             /**
              * tell if a file is a symbolic link
              * @return <code>true</code> for symbolic links
@@ -1016,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.
@@ -1032,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
@@ -1040,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
@@ -1051,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.
@@ -1071,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
@@ -1096,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
@@ -1124,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) {
@@ -1138,6 +1163,7 @@
                              + " while checking a symlink",
                              Project.MSG_DEBUG);
         }
+        boolean result = false;
         if (currentWorkingDir != null) {
             try {
                 result = ftp.changeWorkingDirectory(file.getLink());
@@ -1154,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
@@ -1174,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
@@ -1190,7 +1220,6 @@
         this.remotedir = dir;
     }
 
-
     /**
      * Sets the FTP server to send files to.
      *
@@ -1397,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();
 
@@ -1468,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();
         }
@@ -1481,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();
         }
@@ -1494,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();
         }
@@ -1507,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().equals("")) {
             this.serverLanguageCodeConfig = serverLanguageCode;
             configurationHasBeenSet();
         }
@@ -1520,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();
         }
@@ -1534,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();
         }
@@ -1558,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.
@@ -1624,6 +1664,7 @@
         }
         this.timestampGranularity = timestampGranularity;
     }
+
     /**
      * Sets the siteCommand attribute.  This attribute
      * names the command that will be executed if the action
@@ -1633,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
@@ -1670,32 +1712,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.");
             }
         }
     }
@@ -1738,7 +1778,7 @@
             ds.scan();
         }
 
-        String[] dsfiles = null;
+        String[] dsfiles;
         if (action == RM_DIR) {
             dsfiles = ds.getIncludedDirectories();
         } else {
@@ -1748,12 +1788,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.
@@ -1774,11 +1813,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;
@@ -1789,31 +1824,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 {
@@ -1823,7 +1856,6 @@
         return dsfiles.length;
     }
 
-
     /**
      * Sends all files specified by the configured filesets to the remote
      * server.
@@ -1838,17 +1870,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);
             }
         }
 
@@ -1860,7 +1887,6 @@
         }
     }
 
-
     /**
      * Correct a file path to correspond to the remote host requirements. This
      * implementation currently assumes that the remote end can handle
@@ -1877,7 +1903,6 @@
                             remoteFileSep.charAt(0));
     }
 
-
     /**
      * Creates all parent directories specified in a complete relative
      * pathname. Attempts to create existing directories will not cause
@@ -1898,7 +1923,7 @@
             return;
         }
 
-        Vector parents = new Vector();
+        List<File> parents = new Vector<>();
         String dirname;
 
         while ((dirname = dir.getParent()) != null) {
@@ -1907,7 +1932,7 @@
                 break;
             }
             dir = checkDir;
-            parents.addElement(dir);
+            parents.add(dir);
         }
 
         // find first non cached dir
@@ -1916,15 +1941,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
@@ -1934,8 +1958,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);
@@ -1979,11 +2004,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(
@@ -2041,10 +2067,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();
@@ -2052,38 +2077,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
@@ -2093,28 +2116,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>
@@ -2179,7 +2194,6 @@
         }
     }
 
-
     /**
      * Delete a file from the remote host.
      * @param ftp ftp client
@@ -2259,10 +2273,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;
             }
@@ -2310,7 +2323,6 @@
         }
     }
 
-
     /**
      * List information about a single file from the remote host. <code>filename</code>
      * may contain a relative path specification. <p>
@@ -2355,41 +2367,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");
+                    }
                 }
             }
         }
@@ -2409,8 +2421,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());
         }
     }
 
@@ -2420,6 +2432,7 @@
      * @throws BuildException if the task fails or is not configured
      *         correctly.
      */
+    @Override
     public void execute() throws BuildException {
         checkAttributes();
 
@@ -2436,8 +2449,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);
@@ -2453,14 +2466,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());
                 }
             }
 
@@ -2468,8 +2481,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());
                 }
             }
 
@@ -2478,56 +2492,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) {
@@ -2554,7 +2555,6 @@
         }
     }
 
-
     /**
      * an action to perform, one of
      * "send", "put", "recv", "get", "del", "delete", "list", "mkdir", "chmod",
@@ -2567,44 +2567,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>
@@ -2630,9 +2633,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
@@ -2652,13 +2657,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.
@@ -2675,6 +2681,7 @@
          * Get the valid values.
          * @return the list of valid system types.
          */
+        @Override
         public String[] getValues() {
             return VALID_SYSTEM_TYPES;
         }
@@ -2685,31 +2692,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 aa060ae..2e5228d 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
@@ -731,32 +744,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.");
             }
         }
     }
@@ -767,6 +778,7 @@
      * @throws BuildException if the task fails or is not configured
      *         correctly.
      */
+    @Override
     public void execute() throws BuildException {
         checkAttributes();
         try {
@@ -814,18 +826,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());
         }
@@ -843,17 +858,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.
          *
@@ -861,26 +875,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>
@@ -906,9 +925,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
@@ -928,13 +949,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.
@@ -946,11 +968,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 35f01b3..f546b23 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
@@ -28,14 +28,16 @@
 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;
@@ -65,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;
 
@@ -83,6 +85,7 @@
      *
      */
     protected static class FTPFileProxy extends File {
+        private static final long serialVersionUID = 1L;
 
         private final FTPFile file;
         private final String[] parts;
@@ -110,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++){
@@ -146,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();
@@ -200,10 +203,10 @@
             return 0;
         }
 
-
         /* (non-Javadoc)
          * @see java.io.File#length()
          */
+        @Override
         public long length() {
             if (file != null) {
                 return file.getSize();
@@ -244,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'
@@ -259,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();
@@ -279,7 +282,6 @@
             }
         }
 
-
         /**
          * this routine is actually checking all the include patterns in
          * order to avoid scanning everything under base dir
@@ -287,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++) {
@@ -312,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.
          *
@@ -398,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 {
@@ -414,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)) {
@@ -462,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);
@@ -519,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
@@ -552,6 +554,7 @@
             fileListMap.clear();
             scannedDirs.clear();
         }
+
         /**
          * list the files present in one directory.
          * @param directory full path on the remote side
@@ -563,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();
@@ -574,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) {
@@ -598,6 +600,7 @@
                 }
             }
         }
+
         /**
          * cd into one directory and
          * list the files present in one directory.
@@ -607,6 +610,7 @@
         public FTPFile[] listFiles(String directory) {
             return listFiles(directory, true);
         }
+
         private void checkRemoteSensitivity(FTPFile[] array, String directory) {
             if (array == null) {
                 return;
@@ -615,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 "
@@ -656,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)));
@@ -669,6 +674,7 @@
             }
             return result.toString();
         }
+
         /**
          * an AntFTPFile is a representation of a remote file
          * @since Ant 1.6
@@ -693,6 +699,7 @@
             private boolean relativePathCalculated = false;
             private boolean traversesSymlinks = false;
             private String relativePath = "";
+
             /**
              * constructor
              * @param client ftp client variable
@@ -704,6 +711,7 @@
                 this.ftpFile = ftpFile;
                 this.curpwd = curpwd;
             }
+
             /**
              * other constructor
              * @param parent the parent file
@@ -712,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
@@ -721,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);
             }
             /**
@@ -766,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;
@@ -779,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
@@ -788,6 +797,7 @@
             public String getLink() {
                 return ftpFile.getLink();
             }
+
             /**
              * get the name of the file
              * @return the name of the file
@@ -795,6 +805,7 @@
             public String getName() {
                 return ftpFile.getName();
             }
+
             /**
              * find out the absolute path of the file
              * @return absolute path as string
@@ -802,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.
@@ -816,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,
@@ -842,6 +855,7 @@
                 }
                 return relativePath;
             }
+
             /**
              * get the relative path of this file
              * @param currentPath          base path
@@ -849,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) {
@@ -881,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"
@@ -894,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.
@@ -915,6 +925,7 @@
             public boolean isDirectory() {
                 return ftpFile.isDirectory();
             }
+
             /**
              * tell if a file is a symbolic link
              * @return <code>true</code> for symbolic links
@@ -922,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.
@@ -938,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
@@ -946,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
@@ -957,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.
@@ -977,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
@@ -1002,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
@@ -1034,7 +1057,8 @@
         String currentWorkingDir = null;
         if (file.isDirectory()) {
             return true;
-        } else if (file.isFile()) {
+        }
+        if (file.isFile()) {
             return false;
         }
         try {
@@ -1060,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
@@ -1080,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);
@@ -1099,7 +1126,6 @@
         h.execute(r, descr);
     }
 
-
     /**
      * For each file in the fileset, do the appropriate action: send, get,
      * delete, or list.
@@ -1130,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.
@@ -1160,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;
@@ -1175,32 +1198,30 @@
                 }
                 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());
-                                }
-                            }
-                        }, dsfile);
+                    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);
                 }
             }
         } finally {
@@ -1227,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
@@ -1266,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
@@ -1287,7 +1304,7 @@
             return;
         }
 
-        Vector parents = new Vector();
+        Vector<File> parents = new Vector<>();
         String dirname;
 
         while ((dirname = dir.getParent()) != null) {
@@ -1307,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
@@ -1323,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);
@@ -1332,6 +1351,7 @@
             ftp.changeWorkingDirectory(cwd);
         }
     }
+
     /**
      * auto find the time difference between local and remote
      * @param ftp handle to ftp client
@@ -1348,8 +1368,7 @@
             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();
@@ -1368,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(
@@ -1430,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();
@@ -1441,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");
         }
@@ -1465,9 +1484,8 @@
 
         if (task.getAction() == FTPTask.SEND_FILES) {
             return adjustedRemoteTimestamp >= localTimestamp;
-        } else {
-            return localTimestamp >= adjustedRemoteTimestamp;
         }
+        return localTimestamp >= adjustedRemoteTimestamp;
     }
 
 
@@ -1480,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>
@@ -1540,9 +1551,7 @@
 
             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()) {
@@ -1567,7 +1576,6 @@
         }
     }
 
-
     /**
      * Delete a file from the remote host.
      * @param ftp ftp client
@@ -1628,7 +1636,6 @@
         }
     }
 
-
     /**
      * Retrieve a single file from the remote host. <code>filename</code> may
      * contain a relative path specification. <p>
@@ -1699,7 +1706,6 @@
         }
     }
 
-
     /**
      * List information about a single file from the remote host. <code>filename</code>
      * may contain a relative path specification. <p>
@@ -1728,7 +1734,6 @@
         }
     }
 
-
     /**
      * Create the specified directory on the remote host.
      *
@@ -1754,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)) {
@@ -1804,6 +1808,7 @@
         }
     }
 
+    @Override
     public void doFTP() throws BuildException {
         FTPClient ftp = null;
 
@@ -1818,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);
@@ -1835,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());
                 }
             }
 
@@ -1850,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());
                 }
             }
 
@@ -1860,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()) {
@@ -1919,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 {
@@ -1935,4 +1931,3 @@
         }
     }
 }
-
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 7bcfef9..9d844a1 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
@@ -28,7 +28,6 @@
 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;
 
@@ -79,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;
@@ -94,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.
@@ -124,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());
@@ -132,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);
@@ -146,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");
         }
 
@@ -183,12 +197,11 @@
             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);
             }
@@ -298,9 +311,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) {
@@ -318,7 +329,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()) {
@@ -329,9 +343,6 @@
                                     + dir.getAbsolutePath(),
                                     Project.MSG_INFO);
                             }
-                        } else {
-                            log(dir.getAbsolutePath() + " exists. Skipping",
-                                Project.MSG_VERBOSE);
                         }
                     } else {
                         log("File separator problem with " + line,
@@ -342,8 +353,6 @@
                 }
                 line = in.readLine();
             }
-        } finally {
-            FileUtils.close(in);
         }
     }
 
@@ -355,20 +364,14 @@
      */
     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);
         }
     }
 
@@ -458,7 +461,7 @@
      * Get name of the project in the PVCS repository
      * @return Vector
      */
-    public Vector getPvcsprojects() {
+    public Vector<PvcsProject> getPvcsprojects() {
         return pvcsProjects;
     }
 
@@ -523,11 +526,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";
     }
 
     /**
@@ -654,23 +653,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 7e62549..35d873c 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;
@@ -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 definition belongs to.
      */
+    @Override
     public void setProject(Project project) {
         super.setProject(project);
         helper.setProjectComponent(this);
@@ -181,20 +181,21 @@
     /**
      * 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");
+            throw new BuildException(
+                "scriptdef requires a src attribute if the encoding is set");
         }
 
         // Check if need to set the loader
@@ -202,51 +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();
@@ -261,14 +258,14 @@
      * 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);
             }
@@ -283,14 +280,14 @@
      * @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);
@@ -298,11 +295,6 @@
                 instance = getProject().createDataType(definition.type);
             }
         } else {
-            /*
-            // try the context classloader
-            ClassLoader loader
-                = Thread.currentThread().getContextClassLoader();
-            */
             ClassLoader loader = createLoader();
 
             try {
@@ -310,13 +302,13 @@
             } 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;
     }
@@ -329,7 +321,9 @@
      * @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);
     }
 
@@ -342,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);
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 c6614cb..66e0eb2 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 9095f07..3a82ea4 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
@@ -69,6 +69,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 fab6fb9..a7b23c5 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
@@ -58,6 +58,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 cdbf92b..b17e0c1 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
@@ -78,6 +78,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 dd6b13a..0b41105 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
@@ -63,6 +63,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/sound/AntSoundPlayer.java b/src/main/org/apache/tools/ant/taskdefs/optional/sound/AntSoundPlayer.java
index 92dd348..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
@@ -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) {
@@ -180,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();
@@ -192,6 +188,7 @@
      *  Fired before any targets are started.
      * @param event ignored
      */
+    @Override
     public void buildStarted(BuildEvent event) {
     }
 
@@ -201,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!
@@ -215,6 +213,7 @@
      * @param event ignored.
      *  @see BuildEvent#getTarget()
      */
+    @Override
     public void targetStarted(BuildEvent event) {
     }
 
@@ -224,6 +223,7 @@
      * @param event ignored.
      *  @see BuildEvent#getException()
      */
+    @Override
     public void targetFinished(BuildEvent event) {
     }
 
@@ -232,6 +232,7 @@
      * @param event ignored.
      *  @see BuildEvent#getTask()
      */
+    @Override
     public void taskStarted(BuildEvent event) {
     }
 
@@ -241,6 +242,7 @@
      * @param event ignored.
      *  @see BuildEvent#getException()
      */
+    @Override
     public void taskFinished(BuildEvent event) {
     }
 
@@ -250,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 c0236e1..1a26fa4 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 b5088a7..89230be 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 d6abb95..2e426ee 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
@@ -226,6 +226,7 @@
      * This initializizs 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";
@@ -241,14 +242,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 3942003..1206d79 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
@@ -295,18 +295,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 */
@@ -314,32 +312,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());
@@ -350,7 +343,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();
@@ -423,9 +416,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) {
@@ -450,9 +442,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) {
@@ -461,23 +452,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);
@@ -498,9 +485,8 @@
         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;
                 }
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 e9f2675..3fec911 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.
@@ -65,7 +63,7 @@
      * <p>
      */
     public void addTask(final Task nestedTask) {
-        nestedTasks.addElement(nestedTask);
+        nestedTasks.add(nestedTask);
     }
 
     /**
@@ -148,48 +146,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
@@ -197,9 +185,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();
@@ -220,34 +207,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.");
@@ -257,34 +254,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.");
@@ -311,13 +318,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 087a402..e68f38d 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;
@@ -156,11 +157,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);
         }
     }
 
@@ -229,7 +228,7 @@
      */
     public void add(ResourceCollection res) {
         if (rcs == null) {
-            rcs = new LinkedList<ResourceCollection>();
+            rcs = new LinkedList<>();
         }
         rcs.add(res);
     }
@@ -271,24 +270,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);
         }
     }
 
@@ -330,9 +326,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);
@@ -340,15 +335,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);
@@ -433,19 +428,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;
@@ -462,28 +457,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;
     }
 
@@ -493,21 +486,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
@@ -515,9 +511,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);
@@ -527,7 +522,7 @@
                 }
             }
             ds.add(root);
-       }
+        }
         return ds;
     }
 
@@ -550,15 +545,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 8775c11..1ffb5bd 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
@@ -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);
@@ -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 214dd4e..67424f4 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
@@ -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);
         }
     }
 
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 2b32907..dc8f2f1 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;
 
     /**
      * Constructor for a local file to remote.
@@ -67,7 +67,7 @@
      */
     public ScpToMessageBySftp(final boolean verbose,
                               final Session session,
-                              final List aDirectoryList,
+                              final List<Directory> aDirectoryList,
                               final String aRemotePath) {
         this(verbose, session, aRemotePath);
 
@@ -107,7 +107,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);
     }
@@ -171,21 +171,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) {
@@ -197,12 +195,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());
         }
     }
 
@@ -263,6 +260,7 @@
      * Get the local file.
      * @return the local file.
      */
+    @Override
     public File getLocalFile() {
         return localFile;
     }
@@ -271,6 +269,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 2eb357a..a7eb85f 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
@@ -566,12 +567,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 d3385e6..baced9e 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 1279a2c..ecf819b 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 53f7253..cd827e6 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 a45b74f..606a2b3 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
@@ -35,14 +35,16 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
 import java.io.PrintStream;
+import java.util.ArrayList;
+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.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;
@@ -119,7 +121,7 @@
 
     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;
@@ -189,8 +191,6 @@
             SYMLINK_UTILS.deleteSymbolicLink(FILE_UTILS
                                              .resolveFile(new File("."), link),
                                              this);
-        } catch (FileNotFoundException fnfe) {
-            handleError(fnfe.toString());
         } catch (IOException ioe) {
             handleError(ioe.toString());
         } finally {
@@ -206,14 +206,13 @@
     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();
+            for (String lnk : links.stringPropertyNames()) {
                 String res = links.getProperty(lnk);
                 // handle the case where lnk points to a directory (bug 25181)
                 try {
@@ -249,30 +248,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 +269,7 @@
                     }
                 }
                 writePropertyFile(linksToStore, dir);
-            }
+            });
         } finally {
             setDefaults();
         }
@@ -367,7 +356,7 @@
      * @param set      The fileset to add.
      */
     public void addFileset(FileSet set) {
-        fileSets.addElement(set);
+        fileSets.add(set);
     }
 
     /**
@@ -434,15 +423,11 @@
      */
     private void writePropertyFile(Properties properties, File dir)
         throws BuildException {
-        BufferedOutputStream bos = null;
-        try {
-            bos = new BufferedOutputStream(
-                Files.newOutputStream(new File(dir, linkFileName).toPath()));
+        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);
         }
     }
 
@@ -485,16 +470,14 @@
                 }
             }
         }
-        String[] cmd = new String[] {"ln", options, res, lnk};
         try {
-            Execute.runCommand(this, cmd);
+            Execute.runCommand(this, "ln", options, res, lnk);
         } catch (BuildException failedToExecute) {
             if (failonerror) {
                 throw failedToExecute;
-            } else {
-                //log at the info level, and keep going.
-                log(failedToExecute.getMessage(), failedToExecute, Project.MSG_INFO);
             }
+            //log at the info level, and keep going.
+            log(failedToExecute.getMessage(), failedToExecute, Project.MSG_INFO);
         }
     }
 
@@ -505,33 +488,30 @@
      * &quot;record&quot;. This means that filesets are interpreted
      * as the directories in which links may be found.
      *
-     * @param v   The filesets specified by the user.
+     * @param fileSets   The filesets specified by the user.
      * @return A HashSet 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) {
+        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++) {
+
+            Stream.of(ds.getIncludedFiles(), ds.getIncludedDirectories())
+                .flatMap(Stream::of).forEach(path -> {
                     try {
-                        File f = new File(dir, fnd[j][k]);
+                        File f = new File(dir, path);
                         File pf = f.getParentFile();
                         String name = f.getName();
                         if (SYMLINK_UTILS.isSymbolicLink(pf, name)) {
                             result.add(new File(pf.getCanonicalFile(), name));
                         }
                     } catch (IOException e) {
-                        handleError("IOException: " + fnd[j][k] + " omitted");
+                        handleError("IOException: " + path + " omitted");
                     }
-                }
-            }
+                });
         }
         return result;
     }
@@ -544,41 +524,35 @@
      * names of the property files with the link information and the
      * subdirectories in which to look for them.
      *
-     * @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(Files.newInputStream(inc.toPath()));
+                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)));
@@ -586,8 +560,7 @@
                 // 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));
                 }
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 e029191..7fe1351 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
index f55fb7c..4502d07 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/xz/Unxz.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/xz/Unxz.java
@@ -19,13 +19,11 @@
 package org.apache.tools.ant.taskdefs.optional.xz;
 
 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.taskdefs.Unpack;
-import org.apache.tools.ant.util.FileUtils;
 import org.tukaani.xz.XZInputStream;
 
 /**
@@ -46,6 +44,7 @@
      * Get the default extension.
      * @return the value ".xz"
      */
+    @Override
     protected String getDefaultExtension() {
         return DEFAULT_EXTENSION;
     }
@@ -53,18 +52,15 @@
     /**
      * Implement the gunzipping.
      */
+    @Override
     protected void extract() {
         if (srcResource.getLastModified() > dest.lastModified()) {
             log("Expanding " + srcResource.getName() + " to "
                         + dest.getAbsolutePath());
 
-            OutputStream out = null;
-            XZInputStream zIn = null;
-            InputStream fis = null;
-            try {
-                out = Files.newOutputStream(dest.toPath());
-                fis = srcResource.getInputStream();
-                zIn = new XZInputStream(fis);
+            try (XZInputStream zIn =
+                new XZInputStream(srcResource.getInputStream());
+                    OutputStream out = Files.newOutputStream(dest.toPath())) {
                 byte[] buffer = new byte[BUFFER_SIZE];
                 int count = 0;
                 do {
@@ -74,10 +70,6 @@
             } catch (IOException ioe) {
                 String msg = "Problem expanding xz " + ioe.getMessage();
                 throw new BuildException(msg, ioe, getLocation());
-            } finally {
-                FileUtils.close(fis);
-                FileUtils.close(out);
-                FileUtils.close(zIn);
             }
         }
     }
@@ -88,6 +80,7 @@
      * <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
index 7603192..58cff61 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/xz/Xz.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/xz/Xz.java
@@ -18,12 +18,10 @@
 
 package org.apache.tools.ant.taskdefs.optional.xz;
 
-import java.io.BufferedOutputStream;
 import java.io.IOException;
 import java.nio.file.Files;
 
 import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.taskdefs.Pack;
 import org.tukaani.xz.LZMA2Options;
 import org.tukaani.xz.XZOutputStream;
@@ -41,17 +39,14 @@
     /**
      * Compress the zipFile.
      */
+    @Override
     protected void pack() {
-        XZOutputStream zOut = null;
-        try {
-            zOut = new XZOutputStream(Files.newOutputStream(zipFile.toPath()),
-                                      new LZMA2Options());
+        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());
-        } finally {
-            FileUtils.close(zOut);
         }
     }
 
@@ -61,6 +56,7 @@
      * <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..0ed2639 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")
@@ -421,7 +413,7 @@
              * This is supposed to make Ant always recompile the
              * class, as a file of that name should not exist.
              */
-            String[] target = new String[] {name + ".tmp." + RAND.nextLong()};
+            String[] target = new String[] { name + ".tmp." + RAND.nextLong() };
 
             if (!attributes.getIiop() && !attributes.getIdl()) {
                 // JRMP with simple naming convention
@@ -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 559c769..0b43e74 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 92d5ace..58e7c16 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;
@@ -66,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;
@@ -113,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();
@@ -482,14 +485,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()
@@ -497,8 +500,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);
@@ -570,6 +573,7 @@
      *
      * @return whether any selectors are in this container.
      */
+    @Override
     public synchronized boolean hasSelectors() {
         if (isReference()) {
             return getRef(getProject()).hasSelectors();
@@ -591,12 +595,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()));
     }
 
     /**
@@ -604,6 +603,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();
@@ -617,13 +617,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()]);
     }
 
     /**
@@ -631,6 +631,7 @@
      *
      * @return an <code>Enumeration</code> of selectors.
      */
+    @Override
     public synchronized Enumeration<FileSelector> selectorElements() {
         if (isReference()) {
             return getRef(getProject()).selectorElements();
@@ -644,6 +645,7 @@
      *
      * @param selector the new <code>FileSelector</code> to add.
      */
+    @Override
     public synchronized void appendSelector(FileSelector selector) {
         if (isReference()) {
             throw noChildrenAllowed();
@@ -659,6 +661,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);
     }
@@ -667,6 +670,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);
     }
@@ -675,6 +679,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);
     }
@@ -683,6 +688,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);
     }
@@ -691,6 +697,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);
     }
@@ -699,6 +706,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);
     }
@@ -707,6 +715,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);
     }
@@ -715,6 +724,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);
     }
@@ -723,6 +733,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);
     }
@@ -731,6 +742,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);
     }
@@ -739,6 +751,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);
     }
@@ -747,6 +760,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);
     }
@@ -755,6 +769,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);
     }
@@ -763,6 +778,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);
     }
@@ -771,6 +787,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);
     }
@@ -779,6 +796,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);
     }
@@ -787,6 +805,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);
     }
@@ -796,6 +815,7 @@
      * @param selector the <code>ModifiedSelector</code> to add.
      * @since ant 1.6
      */
+    @Override
     public void addModified(ModifiedSelector selector) {
         appendSelector(selector);
     }
@@ -834,6 +854,7 @@
      * @param selector the <code>FileSelector</code> to add.
      * @since Ant 1.6
      */
+    @Override
     public void add(FileSelector selector) {
         appendSelector(selector);
     }
@@ -843,22 +864,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));
     }
 
     /**
@@ -868,22 +881,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);
         }
     }
 
@@ -924,14 +935,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()) {
@@ -940,11 +949,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 a54db50..6be6569 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 a417a0c..a996f91 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;
         }
@@ -385,7 +384,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()]);
     }
@@ -412,6 +411,7 @@
      * Return the command line as a string.
      * @return the command line.
      */
+    @Override
     public String toString() {
         return toString(getCommandline());
     }
@@ -432,17 +432,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;
     }
 
     /**
@@ -486,7 +485,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;
 
@@ -548,10 +547,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);
@@ -642,9 +642,8 @@
         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));
@@ -679,7 +678,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 d811633..a14c38e 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;
@@ -395,6 +397,7 @@
                             parseClassFromModuleClassPair(javaCommand.getExecutable())),
                                               false);
                     break;
+                default:
             }
         }
         executableType = ExecutableType.MODULE;
@@ -479,7 +482,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
@@ -562,6 +565,7 @@
      * Get a string description.
      * @return the command line as a string.
      */
+    @Override
     public String toString() {
         return Commandline.toString(getCommandline());
     }
@@ -613,6 +617,7 @@
      *             Please dont use this, it effectively creates the
      *             entire command.
      */
+    @Deprecated
     public int size() {
         int size = getActualVMCommand().size() + javaCommand.size()
             + sysProperties.size();
@@ -721,7 +726,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();
@@ -791,7 +797,7 @@
         Path fullClasspath = modulepath != null
             ? modulepath.concatSystemClasspath("ignore") : null;
         return fullClasspath != null
-            && fullClasspath.toString().trim().length() > 0;
+            && !fullClasspath.toString().trim().isEmpty();
     }
 
     /**
@@ -803,7 +809,7 @@
         Path fullClasspath = upgrademodulepath != null
             ? upgrademodulepath.concatSystemClasspath("ignore") : null;
         return fullClasspath != null
-            && fullClasspath.toString().trim().length() > 0;
+            && !fullClasspath.toString().trim().isEmpty();
     }
 
     /**
@@ -840,7 +846,7 @@
      */
     private boolean isCloneVm() {
         return cloneVm
-            || "true".equals(System.getProperty("ant.build.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 fda4af6..24f7682 100644
--- a/src/main/org/apache/tools/ant/types/DataType.java
+++ b/src/main/org/apache/tools/ant/types/DataType.java
@@ -340,6 +340,7 @@
      * Basic DataType toString().
      * @return this DataType formatted as a String.
      */
+    @Override
     public String toString() {
         String d = getDescription();
         return d == null ? getDataTypeName() : getDataTypeName() + " " + d;
@@ -350,6 +351,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 bc893d8..23ea205 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 EnumeratedAttribut 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 42e2763..f91059e 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 4ff3181..a504896 100644
--- a/src/main/org/apache/tools/ant/types/FilterSet.java
+++ b/src/main/org/apache/tools/ant/types/FilterSet.java
@@ -29,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;
 
 /**
@@ -114,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.
@@ -187,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;
 
@@ -196,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.
@@ -259,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());
@@ -358,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);
-           InputStream in = null;
-           try {
-              Properties props = new Properties();
-              in = Files.newInputStream(filtersFile.toPath());
-              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;
     }
@@ -471,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())));
@@ -484,7 +466,7 @@
      * @return Return true if there are filters in this set.
      */
     public synchronized boolean hasFilters() {
-        return getFilters().size() > 0;
+        return !getFilters().isEmpty();
     }
 
     /**
@@ -545,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
@@ -555,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);
@@ -603,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) {
@@ -623,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 16270e3..3a671fa 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;
@@ -71,7 +72,6 @@
     public static Path systemClasspath = //NOSONAR
         new Path(null, System.getProperty("java.class.path"));
 
-
     /**
      * The system bootclasspath as a Path object.
      *
@@ -94,7 +94,7 @@
          * @param loc a <code>File</code> value
          */
         public void setLocation(File loc) {
-            parts = new String[] {translateFile(loc.getAbsolutePath())};
+            parts = new String[] { translateFile(loc.getAbsolutePath()) };
         }
 
         /**
@@ -119,6 +119,7 @@
          * Create an iterator.
          * @return an iterator.
          */
+        @Override
         public Iterator<Resource> iterator() {
             return new FileResourceIterator(getProject(), null, parts);
         }
@@ -127,6 +128,7 @@
          * Check if this resource is only for filesystems.
          * @return true.
          */
+        @Override
         public boolean isFilesystemOnly() {
             return true;
         }
@@ -135,6 +137,7 @@
          * Get the number of resources.
          * @return the number of parts.
          */
+        @Override
         public int size() {
             return parts == null ? 0 : parts.length;
         }
@@ -194,6 +197,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();
@@ -344,9 +348,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()) {
@@ -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 ac1b84c..1aedcb6 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 d27b199..7f7271a 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;
@@ -527,13 +527,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) {
@@ -571,7 +571,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]));
@@ -587,6 +587,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()) {
@@ -603,7 +604,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 6cd0e07..31a6d0a 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;
 
@@ -139,7 +140,7 @@
      * @return the name of this resource.
      */
     public String getName() {
-        return isReference() ? ((Resource) getCheckedRef()).getName() : name;
+        return isReference() ? getCheckedRef().getName() : name;
     }
 
     /**
@@ -158,7 +159,7 @@
      */
     public boolean isExists() {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).isExists();
+            return getCheckedRef().isExists();
         }
         //default true:
         return exists == null || exists.booleanValue();
@@ -185,7 +186,7 @@
      */
     public long getLastModified() {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getLastModified();
+            return getCheckedRef().getLastModified();
         }
         if (!isExists() || lastmodified == null) {
             return UNKNOWN_DATETIME;
@@ -209,7 +210,7 @@
      */
     public boolean isDirectory() {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).isDirectory();
+            return getCheckedRef().isDirectory();
         }
         //default false:
         return directory != null && directory.booleanValue();
@@ -242,7 +243,7 @@
      */
     public long getSize() {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getSize();
+            return getCheckedRef().getSize();
         }
         return isExists()
             ? (size != null ? size.longValue() : UNKNOWN_SIZE)
@@ -253,13 +254,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.");
         }
     }
 
@@ -270,9 +271,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());
     }
@@ -283,6 +285,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;
@@ -299,6 +302,7 @@
      * @return hash code as int.
      * @since Ant 1.7
      */
+    @Override
     public int hashCode() {
         if (isReference()) {
             return getCheckedRef().hashCode();
@@ -318,7 +322,7 @@
      */
     public InputStream getInputStream() throws IOException {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getInputStream();
+            return getCheckedRef().getInputStream();
         }
         throw new UnsupportedOperationException();
     }
@@ -334,7 +338,7 @@
      */
     public OutputStream getOutputStream() throws IOException {
         if (isReference()) {
-            return ((Resource) getCheckedRef()).getOutputStream();
+            return getCheckedRef().getOutputStream();
         }
         throw new UnsupportedOperationException();
     }
@@ -344,24 +348,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();
     }
 
     /**
@@ -369,8 +359,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;
     }
 
     /**
@@ -378,8 +369,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;
     }
 
@@ -388,6 +380,7 @@
      * @return this Resource formatted as a String.
      * @since Ant 1.7
      */
+    @Override
     public String toString() {
         if (isReference()) {
             return getCheckedRef().toString();
@@ -404,7 +397,7 @@
      * @since Ant 1.7
      */
     public final String toLongString() {
-        return isReference() ? ((Resource) getCheckedRef()).toLongString()
+        return isReference() ? getCheckedRef().toLongString()
             : getDataTypeName() + " \"" + toString() + '"';
     }
 
@@ -412,6 +405,7 @@
      * Overrides the base version.
      * @param r the Reference to set.
      */
+    @Override
     public void setRefid(Reference r) {
         if (name != null
             || exists != null
@@ -434,9 +428,28 @@
      * <p>This implementation of the method will return the current
      * instance itself if it can be assigned to the given class.</p>
      *
+     * @param <T> desired type
+     * @param clazz
+     * @return <T>
      * @since Ant 1.8.0
      */
     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
+     * @return {@link Optional} <T>
+     * @since Ant 1.11
+     */
+    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..9fd7f58 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();
 
-    /**
-     * 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}.
+	 *
+	 * @return whether this is a filesystem-only resource collection.
+	 */
+	boolean isFilesystemOnly();
 
-    /**
-     * 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}.
-     * @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.11
+	 */
+	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 9281d5d..753e533 100644
--- a/src/main/org/apache/tools/ant/types/XMLCatalog.java
+++ b/src/main/org/apache/tools/ant/types/XMLCatalog.java
@@ -356,6 +356,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();
@@ -372,6 +373,7 @@
      * @return the resolved entity.
      * @see org.xml.sax.EntityResolver#resolveEntity
      */
+    @Override
     public InputSource resolveEntity(String publicId, String systemId)
         throws SAXException, IOException {
 
@@ -403,6 +405,7 @@
      * @throws TransformerException if an error occurs.
      * @see javax.xml.transform.URIResolver#resolve
      */
+    @Override
     public Source resolve(String href, String base)
         throws TransformerException {
 
@@ -428,7 +431,7 @@
             // setEntityResolver (see setEntityResolver javadoc comment)
             //
             source = new SAXSource();
-            URL baseURL = null;
+            URL baseURL;
             try {
                 if (base == null) {
                     baseURL = FILE_UTILS.getFileURL(getProject().getBaseDir());
@@ -448,6 +451,7 @@
         return source;
     }
 
+    @Override
     protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
         throws BuildException {
         if (isChecked()) {
@@ -495,7 +499,7 @@
 
         if (catalogResolver == null) {
 
-            AntClassLoader loader = null;
+            AntClassLoader loader;
             // Memory-Leak in line below
             loader = getProject().createClassLoader(Path.systemClasspath);
 
@@ -590,12 +594,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);
     }
 
     /**
@@ -628,7 +629,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
@@ -645,7 +646,6 @@
             }
         }
 
-        InputSource source = null;
         URL url = null;
         try {
             url = new URL(baseURL, uri);
@@ -670,7 +670,8 @@
             }
         }
 
-        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);
@@ -701,14 +702,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
@@ -737,7 +737,7 @@
     private InputSource urlLookup(ResourceLocation matchingEntry) {
 
         String uri = matchingEntry.getLocation();
-        URL baseURL = null;
+        URL baseURL;
 
         //
         // The ResourceLocation may specify a relative url for its
@@ -754,15 +754,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;
@@ -792,10 +792,6 @@
      * the ExternalResolver strategy.
      */
     private interface CatalogResolver extends URIResolver, EntityResolver {
-
-        InputSource resolveEntity(String publicId, String systemId);
-
-        Source resolve(String href, String base) throws TransformerException;
     }
 
     /**
@@ -812,6 +808,7 @@
                 Project.MSG_VERBOSE);
         }
 
+        @Override
         public InputSource resolveEntity(String publicId,
                                          String systemId) {
             InputSource result = null;
@@ -837,6 +834,7 @@
             return result;
         }
 
+        @Override
         public Source resolve(String href, String base)
             throws TransformerException {
 
@@ -948,14 +946,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: '"
@@ -999,11 +998,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..49f66eb 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 (ZipFile zf = new ZipFile(srcFile, encoding)) {
 
-        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);
-            }
             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/mappers/CutDirsMapper.java b/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java
index b9e7cfb..8f24e92 100644
--- a/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java
+++ b/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java
@@ -46,6 +46,7 @@
      * Empty implementation.
      * @param ignore ignored.
      */
+    @Override
     public void setFrom(final String ignore) {
     }
 
@@ -53,10 +54,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");
@@ -71,6 +74,6 @@
         if (nthMatch == -1) {
             return null;
         }
-        return new String[] {sourceFileName.substring(nthMatch + 1)};
+        return new String[] { sourceFileName.substring(nthMatch + 1) };
     }
 }
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..4eb5813 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 a4a288b..8fefe86 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);
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 3b0f1a1..a990fd0 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);
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 38dab0b..6fa4b58 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 9225840..e5e11a5 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);
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..f966646 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 bb3cf54..5ea51c7 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,6 +196,7 @@
      * @see DirectoryScanner#getNotIncludedFiles
      */
     /** {@inheritDoc}. */
+    @Override
     public String[] getNotIncludedFiles() {
         return null;
     }
@@ -202,6 +205,7 @@
      * @see DirectoryScanner#setExcludes
      */
     /** {@inheritDoc}. */
+    @Override
     public void setExcludes(String[] excludes) {
     }
 
@@ -209,6 +213,7 @@
      * @see DirectoryScanner#setIncludes
      */
     /** {@inheritDoc}. */
+    @Override
     public void setIncludes(String[] includes) {
     }
 
@@ -216,6 +221,7 @@
      * @see DirectoryScanner#setCaseSensitive
      */
     /** {@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 9924d90..46a3b8b 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 3013bde..0904ba2 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("Execing 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("Execing Transforms");
                 image = ((TransformOperation) instr)
                     .executeTransformOperation(PlanarImage.wrapRenderedImage(bi));
-                bi = image.getAsBufferedImage();
             }
         }
         System.out.println("Execing 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 869fbac..d862459 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
@@ -92,6 +92,7 @@
      * Draw the text.
      * @return the resultant image.
      */
+    @Override
     public PlanarImage executeDrawOperation() {
         log("\tCreating Text \"" + strText + "\"");
 
@@ -100,19 +101,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);
@@ -122,7 +122,17 @@
         graphics.setFont(f);
         graphics.setColor(couloir);
         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
index dfd02e7..8f2908e 100644
--- a/src/main/org/apache/tools/ant/types/optional/xz/XzResource.java
+++ b/src/main/org/apache/tools/ant/types/optional/xz/XzResource.java
@@ -20,6 +20,8 @@
 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;
@@ -43,7 +45,7 @@
      * Constructor with another resource to wrap.
      * @param other the resource to wrap.
      */
-    public XzResource(org.apache.tools.ant.types.ResourceCollection other) {
+    public XzResource(ResourceCollection other) {
         super(other);
     }
 
@@ -53,6 +55,7 @@
      * @return the wrapped stream.
      * @throws IOException if there is a problem.
      */
+    @Override
     protected InputStream wrapStream(InputStream in) throws IOException {
         return new XZInputStream(in);
     }
@@ -63,7 +66,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 XZOutputStream(out, new LZMA2Options());
     }
 
@@ -71,6 +75,7 @@
      * 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 cbf3f3f..6097b83 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 2312d3d..1a7b44c 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 417da9a..d37e5ee 100644
--- a/src/main/org/apache/tools/ant/types/resources/AbstractClasspathResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/AbstractClasspathResource.java
@@ -151,14 +151,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);
         }
     }
 
@@ -177,18 +173,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();
-                        }
-                    }
-                };
+                }
+            };
     }
 
     /**
@@ -198,10 +197,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");
@@ -254,8 +253,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 09ce032..9fe16ab 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 representatation 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 4b0d51c..f47676f 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
@@ -72,16 +72,13 @@
     /**
      * Sums the sizes of nested archives.
      */
+    @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();
     }
 
     /**
@@ -89,15 +86,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();
     }
 
     /**
@@ -105,9 +98,10 @@
      */
     public boolean isFilesystemOnly() {
         if (isReference()) {
-            return ((Archives) getCheckedRef()).isFilesystemOnly();
+            return getCheckedRef().isFilesystemOnly();
         }
         dieOnCircularReference();
+        // TODO check each archive in turn?
         return false;
     }
 
@@ -117,8 +111,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);
@@ -130,7 +124,7 @@
      * @return a cloned instance.
      */
     @Override
-    public Object clone() {
+    public Archives clone() {
         try {
             final Archives a = (Archives) super.clone();
             a.zips = (Union) zips.clone();
@@ -148,14 +142,20 @@
      * and returns an iterator over the collected archives.
      */
     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();
     }
 
     /**
@@ -190,5 +190,10 @@
             setChecked(true);
         }
     }
+    
+    @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 281fa0f..e394ba9 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
     }
 
     /**
@@ -120,9 +120,7 @@
             throw noChildrenAllowed();
         }
         try {
-            for (ResourceCollection resourceCollection : c) {
-                add(resourceCollection);
-            }
+            c.forEach(this::add);
         } catch (ClassCastException e) {
             throw new BuildException(e);
         }
@@ -134,9 +132,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());
@@ -146,9 +145,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();
@@ -158,27 +159,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());
     }
 
     /**
@@ -225,11 +219,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) {
@@ -241,21 +236,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 78ba95e..0bec29f 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 79445bf..2a00872 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 d427888..a1c410a 100644
--- a/src/main/org/apache/tools/ant/types/resources/FileResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/FileResource.java
@@ -105,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) {
@@ -138,7 +139,7 @@
      */
     public File getBaseDir() {
         if (isReference()) {
-            return ((FileResource) getCheckedRef()).getBaseDir();
+            return getCheckedRef().getBaseDir();
         }
         dieOnCircularReference();
         return baseDir;
@@ -148,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();
@@ -161,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()
@@ -174,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();
     }
 
@@ -183,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();
     }
 
@@ -193,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();
     }
 
@@ -202,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();
     }
 
@@ -212,9 +219,9 @@
      * @return an InputStream object.
      * @throws IOException if an error occurs.
      */
+    @Override
     public InputStream getInputStream() throws IOException {
-        return isReference()
-            ? ((Resource) getCheckedRef()).getInputStream()
+        return isReference() ? getCheckedRef().getInputStream()
             : Files.newInputStream(getNotNullFile().toPath());
     }
 
@@ -226,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);
     }
@@ -236,9 +244,10 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public OutputStream getAppendOutputStream() throws IOException {
         if (isReference()) {
-            return ((FileResource) getCheckedRef()).getAppendOutputStream();
+            return getCheckedRef().getAppendOutputStream();
         }
         return getOutputStream(true);
     }
@@ -264,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;
@@ -293,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;
@@ -313,6 +324,7 @@
      * Get the hash code for this Resource.
      * @return hash code as int.
      */
+    @Override
     public int hashCode() {
         if (isReference()) {
             return getCheckedRef().hashCode();
@@ -324,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();
@@ -339,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;
@@ -351,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)) {
@@ -382,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);
@@ -390,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 4f9acd3..e7b2fca 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 cd19c9c..1e91a88 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 2f1a926..13d84d1 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;
@@ -121,10 +122,10 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public boolean isFilesystemOnly() {
         if (isReference()) {
-            return ((MappedResourceCollection) getCheckedRef())
-                .isFilesystemOnly();
+            return getCheckedRef().isFilesystemOnly();
         }
         checkInitialized();
         return false;
@@ -133,9 +134,10 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public int size() {
         if (isReference()) {
-            return ((MappedResourceCollection) getCheckedRef()).size();
+            return getCheckedRef().size();
         }
         checkInitialized();
         return cacheCollection().size();
@@ -144,9 +146,10 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public Iterator<Resource> iterator() {
         if (isReference()) {
-            return ((MappedResourceCollection) getCheckedRef()).iterator();
+            return getCheckedRef().iterator();
         }
         checkInitialized();
         return cacheCollection().iterator();
@@ -156,6 +159,7 @@
      * Overrides the base version.
      * @param r the Reference to set.
      */
+    @Override
     public void setRefid(Reference r) {
         if (nested != null || mapper != null) {
             throw tooManyAttributes();
@@ -167,7 +171,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();
@@ -187,6 +192,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()) {
@@ -208,8 +214,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();
     }
@@ -222,46 +229,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 d793890..4628bdf 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 9eb8c1d..1856d85 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();
@@ -237,6 +237,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());
@@ -246,6 +247,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());
@@ -256,6 +258,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());
@@ -266,6 +269,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());
@@ -276,6 +280,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 fbb226c..204db1d 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;
@@ -96,11 +96,12 @@
      * Makes this instance in effect a reference to another ResourceList
      * instance.
      */
+    @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);
@@ -112,9 +113,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 ((ResourceList) getCheckedRef()).iterator();
+            return getCheckedRef().iterator();
         }
         return cache().iterator();
     }
@@ -123,9 +125,10 @@
      * Fulfill the ResourceCollection contract.
      * @return number of elements as int.
      */
+    @Override
     public synchronized int size() {
         if (isReference()) {
-            return ((ResourceList) getCheckedRef()).size();
+            return getCheckedRef().size();
         }
         return cache().size();
     }
@@ -134,9 +137,10 @@
      * Fulfill the ResourceCollection contract.
      * @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();
     }
@@ -148,6 +152,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()) {
@@ -168,62 +173,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();
-            try (BufferedReader reader = new BufferedReader(crh.getAssembledReader())) {
-                streamResources.setCache(true);
-
-                String line = null;
-                while ((line = reader.readLine()) != null) {
-                    streamResources.add(parse(line));
-                }
-            }
-
+            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);
@@ -236,4 +232,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 1dd888d..b0acfa3 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;
 
@@ -151,7 +163,7 @@
             return;
         }
         if (rc == null) {
-            rc = new Vector<ResourceCollection>();
+            rc = Collections.synchronizedList(new ArrayList<>());
         }
         rc.add(c);
         invalidateExistingIterators();
@@ -163,6 +175,7 @@
      * Fulfill the ResourceCollection contract.
      * @return an Iterator of Resources.
      */
+    @Override
     public synchronized Iterator<Resource> iterator() {
         if (isReference()) {
             return getRef().iterator();
@@ -175,6 +188,7 @@
      * Fulfill the ResourceCollection contract.
      * @return number of elements as int.
      */
+    @Override
     public synchronized int size() {
         if (isReference()) {
             return getRef().size();
@@ -187,24 +201,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();
@@ -213,14 +224,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));
     }
 
     /**
@@ -230,6 +235,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()) {
@@ -259,8 +265,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..cc9cc26 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 c8e772b..6177f2e 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 e2f2f9f..9c10658 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();
     }
@@ -117,7 +116,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();
     }
 
     /**
@@ -125,12 +125,8 @@
      * @return Collection<String>
      */
     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));
     }
 
     /**
@@ -138,19 +134,17 @@
      * @return Set<Resource>
      */
     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/Content.java b/src/main/org/apache/tools/ant/types/resources/comparators/Content.java
index 1810b64..07dd315 100644
--- a/src/main/org/apache/tools/ant/types/resources/comparators/Content.java
+++ b/src/main/org/apache/tools/ant/types/resources/comparators/Content.java
@@ -57,7 +57,7 @@
      * @return a negative integer, zero, or a positive integer as the first
      *         argument is less than, equal to, or greater than the second.
      * @throws BuildException if I/O errors occur.
-     * @see org.apache.tools.ant.util.ResourceUtils#compareContent(Resource, Resource, boolean).
+     * @see org.apache.tools.ant.util.ResourceUtils#compareContent(Resource, Resource, boolean)
      */
     protected int resourceCompare(Resource foo, Resource bar) {
         try {
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..dbe13d4 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..1d6d3c3 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 c787a76..664261d 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 50c242a..f5adeb4 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 6b1c800..795d453 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.
@@ -45,9 +45,9 @@
      * Construct a new ResourceSelectorContainer with the specified array of selectors.
      * @param r the ResourceSelector[] to add.
      */
-    public ResourceSelectorContainer(ResourceSelector[] r) {
-        for (int i = 0; i < r.length; i++) {
-            add(r[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 3039d48..61f02b6 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);
     }
 
 
@@ -358,17 +346,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 414390e..6307ced 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.
      *
@@ -76,7 +70,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
@@ -86,11 +79,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.
@@ -121,6 +113,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 3fcccd7..baf14da 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 */
 
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 8232e45..e79061c 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 c701fb8..90fa9e0 100644
--- a/src/main/org/apache/tools/ant/types/selectors/DifferentSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/DifferentSelector.java
@@ -54,7 +54,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
@@ -62,6 +61,7 @@
     public void setIgnoreFileTimes(boolean ignoreFileTimes) {
         this.ignoreFileTimes = ignoreFileTimes;
     }
+
     /**
      * This flag tells the selector to ignore contents
      * @param ignoreContents if true ignore contents
@@ -70,6 +70,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
@@ -99,16 +100,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
index 891b795..214b98f 100644
--- a/src/main/org/apache/tools/ant/types/selectors/ExecutableSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/ExecutableSelector.java
@@ -18,12 +18,8 @@
 
 package org.apache.tools.ant.types.selectors;
 
-import java.nio.file.Files;
 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;
+import java.nio.file.Files;
 
 /**
  * A selector that selects executable files.
@@ -35,17 +31,10 @@
  *
  * @since Ant 1.10.0
  */
-public class ExecutableSelector implements FileSelector, ResourceSelector {
+public class ExecutableSelector implements FileSelector {
 
     public boolean isSelected(File basedir, String filename, File file) {
         return file != null && Files.isExecutable(file.toPath());
     }
 
-    public boolean isSelected(Resource r) {
-        FileProvider fp = r.as(FileProvider.class);
-        if (fp != null) {
-            return isSelected(null, null, fp.getFile());
-        }
-        return false;
-    }
 }
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..984db23 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
+     * @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
index 32aaa8d..88f3b08 100644
--- a/src/main/org/apache/tools/ant/types/selectors/OwnedBySelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/OwnedBySelector.java
@@ -18,15 +18,12 @@
 
 package org.apache.tools.ant.types.selectors;
 
-import java.nio.file.Files;
-import java.nio.file.attribute.UserPrincipal;
 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;
-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 files based on their owner.
@@ -39,7 +36,7 @@
  *
  * @since Ant 1.10.0
  */
-public class OwnedBySelector implements FileSelector, ResourceSelector {
+public class OwnedBySelector implements FileSelector {
 
     private String owner;
 
@@ -67,12 +64,4 @@
         return false;
     }
 
-    @Override
-    public boolean isSelected(Resource r) {
-        FileProvider fp = r.as(FileProvider.class);
-        if (fp != null) {
-            return isSelected(null, null, fp.getFile());
-        }
-        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 1c0c000..1b39d22 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 9ff91ad..f62880b 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: " + <"compare",
      * "less", "more", "equal"> + "}".
@@ -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
index 28c3bcb..d5df1ce 100644
--- a/src/main/org/apache/tools/ant/types/selectors/SymlinkSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/SymlinkSelector.java
@@ -18,12 +18,8 @@
 
 package org.apache.tools.ant.types.selectors;
 
-import java.nio.file.Files;
 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;
+import java.nio.file.Files;
 
 /**
  * A selector that selects symbolic links.
@@ -34,17 +30,10 @@
  *
  * @since Ant 1.10.0
  */
-public class SymlinkSelector implements FileSelector, ResourceSelector {
+public class SymlinkSelector implements FileSelector {
 
     public boolean isSelected(File basedir, String filename, File file) {
         return file != null && Files.isSymbolicLink(file.toPath());
     }
 
-    public boolean isSelected(Resource r) {
-        FileProvider fp = r.as(FileProvider.class);
-        if (fp != null) {
-            return isSelected(null, null, fp.getFile());
-        }
-        return false;
-    }
 }
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 a712759..48e4ce7 100644
--- a/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java
+++ b/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java
@@ -19,6 +19,7 @@
 package org.apache.tools.ant.types.selectors;
 
 import java.io.File;
+import java.io.IOException;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.util.FileUtils;
@@ -148,7 +149,7 @@
                     return true;
                 }
                 base = new File(base, tokenizedPath[i]);
-            } catch (java.io.IOException ioe) {
+            } catch (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
@@ -189,8 +190,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 dbe7ec8..e9413df 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
@@ -114,12 +116,7 @@
      * Does the tokenized pattern contain the given string?
      */
     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));
     }
 
     /**
@@ -162,16 +159,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..ef6853f 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 26c6945..a660caf 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,6 @@
 
 import java.io.BufferedInputStream;
 import java.io.File;
-import java.io.InputStream;
 import java.nio.file.Files;
 import java.security.NoSuchAlgorithmException;
 import java.util.Locale;
@@ -105,6 +104,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 +115,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();
-                 InputStream fis = Files.newInputStream(file.toPath());
-                 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 e) {
             }
-        } catch (Exception e) {
-            rval = null;
         }
-        return rval;
+        return null;
     }
 
 
@@ -142,11 +138,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 9624145..cc9a66c 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,6 @@
 
 
 import java.io.File;
-import java.io.InputStream;
 import java.nio.file.Files;
 import java.security.DigestInputStream;
 import java.security.MessageDigest;
@@ -119,10 +118,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 +138,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;
-            }
-            InputStream fis = null;
-
-            byte[] buf = new byte[readBufferSize];
-            try {
+            if (file.canRead()) {
+                byte[] buf = new byte[readBufferSize];
                 messageDigest.reset();
-                fis = Files.newInputStream(file.toPath());
-                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)
+                        ;
+                    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);
                     }
-                    checksumSb.append(hexStr);
+                    return checksumSb.toString();
+                } catch (Exception e) {
                 }
-                checksum = checksumSb.toString();
-            } catch (Exception e) {
-                return null;
             }
         } catch (Exception e) {
-            return null;
         }
-        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 9f53809..f2097fd 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();
     }
 
 
@@ -400,21 +396,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);
         }
@@ -431,6 +428,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
@@ -440,30 +438,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. "
-                  + "Akkording 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. "
+              + "Akkording to 'selres' attribute value it is "
+              + ((selectResourcesWithoutInputStream) ? "" : " not")
+              + "selected.", Project.MSG_INFO);
+            return selectResourcesWithoutInputStream;
+        } catch (Exception e) {
+            throw new BuildException(e);
         }
     }
 
@@ -476,11 +473,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.
@@ -503,7 +500,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) {
@@ -513,7 +510,6 @@
                 saveCache();
             }
         }
-
         return rv;
     }
 
@@ -690,13 +686,14 @@
      * Defined in org.apache.tools.ant.types.Parameterizable.
      * Overwrite implementation in superclass because only special
      * parameters are valid.
-     * @see #addParam(String,Object).
+     * @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);
             }
         }
     }
@@ -731,23 +728,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);
@@ -776,7 +761,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
         }
     }
@@ -789,8 +774,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);
@@ -807,7 +793,8 @@
     /**
      * Signals that the last target has finished.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void buildFinished(BuildEvent event) {
         if (getDelayUpdate()) {
             saveCache();
@@ -818,7 +805,8 @@
     /**
      * Signals that a target has finished.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void targetFinished(BuildEvent event) {
         if (getDelayUpdate()) {
             saveCache();
@@ -829,7 +817,8 @@
     /**
      * Signals that a task has finished.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void taskFinished(BuildEvent event) {
         if (getDelayUpdate()) {
             saveCache();
@@ -840,7 +829,8 @@
     /**
      * Signals that a build has started.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void buildStarted(BuildEvent event) {
         // no-op
     }
@@ -849,7 +839,8 @@
     /**
      * Signals that a target is starting.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void targetStarted(BuildEvent event) {
         // no-op
     }
@@ -859,7 +850,8 @@
     /**
      * Signals that a task is starting.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void taskStarted(BuildEvent event) {
         // no-op
     }
@@ -868,7 +860,8 @@
     /**
      * Signals a message logging event.
      * @param event received BuildEvent
-    */
+     */
+    @Override
     public void messageLogged(BuildEvent event) {
         // no-op
     }
@@ -903,8 +896,9 @@
          * {@inheritDoc}
          * @see EnumeratedAttribute#getValues()
          */
+        @Override
         public String[] getValues() {
-            return new String[] {"propertyfile" };
+            return new String[] { "propertyfile" };
         }
     }
 
@@ -933,8 +927,9 @@
          * {@inheritDoc}
          * @see EnumeratedAttribute#getValues()
          */
+        @Override
         public String[] getValues() {
-            return new String[] {"hashvalue", "digest", "checksum" };
+            return new String[] { "hashvalue", "digest", "checksum" };
         }
     }
 
@@ -963,8 +958,9 @@
          * {@inheritDoc}
          * @see EnumeratedAttribute#getValues()
          */
+        @Override
         public String[] getValues() {
-            return new String[] {"equal", "rule" };
+            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 2a16d1f..d0de982 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,13 +22,9 @@
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.nio.file.Files;
-import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.Properties;
-import java.util.Vector;
 
 
 /**
@@ -119,6 +115,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 +127,12 @@
     /**
      * Load the cache from underlying properties file.
      */
+    @Override
     public void load() {
         if ((cachefile != null) && cachefile.isFile() && cachefile.canRead()) {
-            try {
-                BufferedInputStream bis = new BufferedInputStream(
-                    Files.newInputStream(cachefile.toPath()));
+            try (BufferedInputStream bis = new BufferedInputStream(
+                Files.newInputStream(cachefile.toPath()))) {
                 cache.load(bis);
-                bis.close();
             } catch (Exception e) {
                 e.printStackTrace(); //NOSONAR
             }
@@ -153,17 +149,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(
-                      Files.newOutputStream(cachefile.toPath()));
+            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 +167,7 @@
     }
 
     /** Deletes the cache and its underlying file. */
+    @Override
     public void delete() {
         cache = new Properties();
         cachefile.delete();
@@ -184,6 +180,7 @@
      * @param key the key
      * @return the stored value
      */
+    @Override
     public Object get(Object key) {
         if (!cacheLoaded) {
             load();
@@ -200,6 +197,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 +207,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 +220,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 309860e..0f7787a 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;
         }
@@ -243,14 +245,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) {
@@ -286,6 +290,9 @@
         return p.getProperty(REUSE_LOADER_REF) != null;
     }
 
+    private ClasspathUtils() {
+    }
+
     /**
      * Delegate that helps out any specific ProjectComponent that needs
      * dynamic classloading.
@@ -457,7 +464,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 ff0111e..e39f09e 100644
--- a/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java
+++ b/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java
@@ -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) {
diff --git a/src/main/org/apache/tools/ant/util/ConcatResourceInputStream.java b/src/main/org/apache/tools/ant/util/ConcatResourceInputStream.java
index 7bae58e..d030a55 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 cafecf0..7f6013a 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) {
@@ -596,13 +595,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
@@ -610,31 +613,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 9ce737b..42b3eab 100644
--- a/src/main/org/apache/tools/ant/util/DateUtils.java
+++ b/src/main/org/apache/tools/ant/util/DateUtils.java
@@ -66,12 +66,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
@@ -215,7 +215,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;
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 11ae06b..8bbdf91 100644
--- a/src/main/org/apache/tools/ant/util/FileUtils.java
+++ b/src/main/org/apache/tools/ant/util/FileUtils.java
@@ -37,19 +37,20 @@
 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;
 
@@ -112,6 +113,7 @@
      *             Use getFileUtils instead,
      * FileUtils do not have state.
      */
+    @Deprecated
     public static FileUtils newFileUtils() {
         return new FileUtils();
     }
@@ -275,7 +277,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,
@@ -305,7 +307,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 {
@@ -440,7 +442,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,
@@ -476,7 +478,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 {
@@ -514,7 +516,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,
@@ -554,7 +556,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,
@@ -698,10 +700,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();
@@ -735,7 +737,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]);
 
@@ -755,7 +757,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) {
@@ -783,7 +785,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)) {
 
@@ -836,7 +838,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;
@@ -849,13 +851,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) {
@@ -897,6 +899,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);
     }
@@ -926,7 +929,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();
@@ -987,6 +990,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);
@@ -1032,8 +1036,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();
     }
 
     /**
@@ -1062,17 +1067,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();
@@ -1138,6 +1143,7 @@
      * @since Ant 1.5
      * @deprecated use SymbolicLinkUtils instead
      */
+    @Deprecated
     public boolean isSymbolicLink(File parent, String name)
         throws IOException {
         SymbolicLinkUtils u = SymbolicLinkUtils.getSymbolicLinkUtils();
@@ -1375,11 +1381,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;
     }
@@ -1506,7 +1509,6 @@
                     JarURLConnection juc = (JarURLConnection) conn;
                     JarFile jf = juc.getJarFile();
                     jf.close();
-                    jf = null;
                 } else if (conn instanceof HttpURLConnection) {
                     ((HttpURLConnection) conn).disconnect();
                 }
@@ -1623,7 +1625,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
@@ -1661,7 +1663,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, '/');
     }
@@ -1675,18 +1677,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)));
     }
 
     /**
@@ -1700,6 +1692,7 @@
     public String getDefaultEncoding() {
         InputStreamReader is = new InputStreamReader(
             new InputStream() { //NOSONAR
+                @Override
                 public int read() {
                     return -1;
                 }
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 da2a0f1..4d2d5cc 100644
--- a/src/main/org/apache/tools/ant/util/GlobPatternMapper.java
+++ b/src/main/org/apache/tools/ant/util/GlobPatternMapper.java
@@ -107,42 +107,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;
+        }
     }
 
     /**
@@ -152,6 +152,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 ac806d7..56e9f7b 100644
--- a/src/main/org/apache/tools/ant/util/IdentityStack.java
+++ b/src/main/org/apache/tools/ant/util/IdentityStack.java
@@ -40,7 +40,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);
         }
@@ -69,6 +69,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;
     }
@@ -80,6 +81,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++) {
@@ -97,6 +99,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) {
@@ -106,22 +109,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 84e82fd..ea21b6b 100644
--- a/src/main/org/apache/tools/ant/util/JavaEnvUtils.java
+++ b/src/main/org/apache/tools/ant/util/JavaEnvUtils.java
@@ -448,7 +448,7 @@
      */
 
     private static void buildJrePackages() {
-        jrePackages = new Vector<String>();
+        jrePackages = new Vector<>();
         switch(javaVersionNumber) {
             case VERSION_9:
             case VERSION_1_8:
@@ -502,7 +502,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");
         switch(javaVersionNumber) {
             case VERSION_9:
@@ -577,15 +577,11 @@
     public static File createVmsJavaOptionFile(String[] cmd)
             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 < cmd.length; i++) {
                 out.write(cmd[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 853bec2..f4f2fe7 100644
--- a/src/main/org/apache/tools/ant/util/LayoutPreservingProperties.java
+++ b/src/main/org/apache/tools/ant/util/LayoutPreservingProperties.java
@@ -27,10 +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) {
@@ -288,11 +290,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;
@@ -317,7 +317,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());
         }
@@ -327,8 +327,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);
 
@@ -349,7 +349,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) {
@@ -384,7 +384,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
@@ -454,13 +454,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') {
@@ -540,7 +541,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];
@@ -571,7 +572,7 @@
      */
     private String escapeUnicode(final char ch) {
         return "\\" + UnicodeUtil.EscapeUnicode(ch);
-        }
+    }
 
     /**
      * Remove the comments in the leading up the {@link logicalLines}
@@ -618,7 +619,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) {
@@ -639,6 +642,8 @@
      * A blank line of the input stream.
      */
     private static class Blank extends LogicalLine {
+        private static final long serialVersionUID = 1L;
+
         public Blank() {
             super("");
         }
@@ -648,6 +653,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);
         }
@@ -659,6 +666,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;
@@ -676,6 +685,7 @@
             return name;
         }
 
+        @SuppressWarnings("unused")
         public String getValue() {
             return value;
         }
@@ -694,10 +704,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
@@ -711,10 +721,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 781d0c7..cd7801d 100644
--- a/src/main/org/apache/tools/ant/util/LazyFileOutputStream.java
+++ b/src/main/org/apache/tools/ant/util/LazyFileOutputStream.java
@@ -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);
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 7f158db..9298a73 100644
--- a/src/main/org/apache/tools/ant/util/MergingMapper.java
+++ b/src/main/org/apache/tools/ant/util/MergingMapper.java
@@ -44,6 +44,7 @@
      * Ignored.
      * @param from ignored.
      */
+    @Override
     public void setFrom(String from) {
     }
 
@@ -51,6 +52,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};
     }
@@ -60,6 +62,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/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 f327b77..be3523d 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 ed8b47a..27ba8ce 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;
 
@@ -60,12 +62,11 @@
      * @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
@@ -80,12 +81,11 @@
      * @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
@@ -100,13 +100,12 @@
      * @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
@@ -123,14 +122,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,12 +143,13 @@
      * @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
@@ -182,9 +182,8 @@
                 return (BuildException) t2;
             }
             return new BuildException(t2);
-        } else {
-            return new BuildException(t);
         }
+        return new BuildException(t);
     }
 
     /**
@@ -198,13 +197,8 @@
     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);
         }
diff --git a/src/main/org/apache/tools/ant/util/ReflectWrapper.java b/src/main/org/apache/tools/ant/util/ReflectWrapper.java
index e34363e..f803c88 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);
         }
@@ -56,8 +55,9 @@
     /**
      * @return the wrapped object.
      */
-    public Object getObject() {
-        return obj;
+    @SuppressWarnings("unchecked")
+    public <T> T getObject() {
+        return (T) obj;
     }
 
     /**
@@ -65,7 +65,7 @@
      * @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);
     }
 
@@ -76,8 +76,7 @@
      * @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);
     }
 
@@ -90,10 +89,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..5974847 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,18 +77,18 @@
      * @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) {
@@ -123,7 +124,7 @@
             || !reg.matches(sourceFileName, regexpOptions)) {
             return null;
         }
-        return new String[] {replaceReferences(sourceFileName)};
+        return new String[] { replaceReferences(sourceFileName) };
     }
 
     /**
@@ -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 c4532a7..9b246a0 100644
--- a/src/main/org/apache/tools/ant/util/ResourceUtils.java
+++ b/src/main/org/apache/tools/ant/util/ResourceUtils.java
@@ -28,6 +28,7 @@
 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;
@@ -35,6 +36,7 @@
 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;
@@ -142,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));
     }
 
     /**
@@ -181,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;
         }
@@ -301,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)
@@ -338,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,
@@ -378,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,
@@ -391,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 {
@@ -405,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
@@ -561,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());
     }
 
     /**
@@ -582,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();
@@ -595,9 +578,6 @@
                 }
             }
             return in2.read() == -1 ? 0 : -1;
-        } finally {
-            FileUtils.close(in1);
-            FileUtils.close(in2);
         }
     }
 
@@ -612,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) {
@@ -630,9 +609,6 @@
                 expected = in1.readLine();
             }
             return in2.readLine() == null ? 0 : -1; //NOSONAR
-        } finally {
-            FileUtils.close(in1);
-            FileUtils.close(in2);
         }
     }
 
@@ -659,40 +635,18 @@
 
     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 {
-        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;
@@ -708,49 +662,40 @@
                 }
                 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,
                                                           final Project project)
         throws IOException {
-        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);
@@ -759,9 +704,6 @@
                 }
                 out.write(buffer, 0, nRead);
             }
-        } finally {
-            FileUtils.close(out);
-            FileUtils.close(in);
         }
     }
 
@@ -776,35 +718,28 @@
                                   + " for " + destFile);
         }
 
-        FileChannel srcChannel = null;
-        FileChannel destChannel = null;
-
-        try {
-            srcChannel = FileChannel.open(sourceFile.toPath(), StandardOpenOption.READ);
-            destChannel = FileChannel.open(destFile.toPath(), StandardOpenOption.CREATE,
-                StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE);
-
+        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);
         }
     }
 
     private static void copyUsingStreams(final Resource source, final Resource dest,
                                          final boolean append, final Project project)
         throws IOException {
-        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;
@@ -812,9 +747,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 4765268..374da29 100644
--- a/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java
+++ b/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java
@@ -26,7 +26,6 @@
 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;
@@ -65,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
@@ -73,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
             }
-        }
+        });
     }
 
     /**
@@ -101,7 +98,6 @@
         for (int i = 1; isValid && i < key.length(); i++) {
             isValid = Character.isJavaIdentifierPart(key.charAt(i));
         }
-
         if (isValid) {
             beans.put(key, bean);
         }
@@ -111,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;
     }
 
@@ -226,29 +222,15 @@
      */
     public void setSrc(File file) {
         String filename = file.getPath();
-        if (!file.exists()) {
-            throw new BuildException("file " + filename + " not found.");
-        }
 
-        InputStream in = null;
-        try {
-            in = Files.newInputStream(file.toPath());
+        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.");
-        }
-
-        final Charset charset;
-        if (null == encoding) {
-            charset = null;
-        } else {
-            charset = Charset.forName(encoding);
-        }
-
-        try {
-            readSource(in, filename, charset);
-        } finally {
-            FileUtils.close(in);
+            throw new BuildException("file " + filename + " not found.", e);
         }
     }
 
@@ -259,19 +241,11 @@
      * @param charset the encoding for the reader, may be null.
      */
     private void readSource(InputStream in, String name, Charset charset) {
-        Reader reader = null;
-        try {
-            if (null == charset) {
-                reader = new InputStreamReader(in);
-            } else {
-                reader = new InputStreamReader(in, charset);
-            }
-            reader = new BufferedReader(reader);
+        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(reader);
         }
     }
 
@@ -292,21 +266,14 @@
         }
 
         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);
         }
-
-        try {
-            readSource(in, name, (Charset) null);
-        } finally {
-            FileUtils.close(in);
-        }
     }
 
     /**
@@ -316,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);
     }
 
     /**
@@ -394,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");
         }
     }
 
diff --git a/src/main/org/apache/tools/ant/util/SourceFileScanner.java b/src/main/org/apache/tools/ant/util/SourceFileScanner.java
index c79f034..879da84 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 f48d3d3..f2b5232 100644
--- a/src/main/org/apache/tools/ant/util/SplitClassLoader.java
+++ b/src/main/org/apache/tools/ant/util/SplitClassLoader.java
@@ -42,9 +42,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;
         }
@@ -54,9 +55,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 6ee9c45..93b4f90 100644
--- a/src/main/org/apache/tools/ant/util/StringUtils.java
+++ b/src/main/org/apache/tools/ant/util/StringUtils.java
@@ -152,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);
@@ -255,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;
     }
 
     /**
@@ -270,9 +269,8 @@
     public static String removePrefix(String string, String prefix) {
         if (string.startsWith(prefix)) {
             return string.substring(prefix.length());
-        } else {
-            return string;
         }
+        return string;
     }
     
     /**
@@ -286,7 +284,8 @@
         if (collection == null) {
             return "";
         }
-        return collection.stream().map( o -> String.valueOf(o) ).collect(joining(separator));
+        return collection.stream().map(String::valueOf)
+            .collect(joining(separator));
     }
 
     /**
@@ -307,7 +306,6 @@
         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.
@@ -315,16 +313,11 @@
      *
      */
     public static String trimToNull(String inputString) {
-
         if (inputString == null) {
             return null;
         }
-
-       String tmpString = inputString.trim();
-        if ("".equals(tmpString)) {
-            return null;
-        }
-        return tmpString;
+        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 62b7a3f..37a74be 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;
@@ -176,11 +175,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..f1665c7 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);
-            }
+            c.forEach(this::add);
         }
     }
 
+    @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 92f322f..1c00102 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 b05ed1f..3ec4146 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<>();
     }
 
     /**
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 997af7a..4676ab5 100644
--- a/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
+++ b/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
@@ -18,12 +18,21 @@
 
 package org.apache.tools.ant.util.optional;
 
-import java.util.Iterator;
+import java.util.function.BiConsumer;
+import java.util.Map;
+import java.util.Objects;
+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.MagicNames;
 import org.apache.tools.ant.Project;
-import org.apache.tools.ant.util.ReflectWrapper;
 import org.apache.tools.ant.util.ScriptRunnerBase;
 
 /**
@@ -31,20 +40,22 @@
  * @since Ant 1.7.0
  */
 public class JavaxScriptRunner extends ScriptRunnerBase {
-    private ReflectWrapper engine;
-    private ReflectWrapper compiledScript;
+    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();
@@ -66,6 +77,7 @@
      *
      * @exception BuildException if something goes wrong executing the script.
      */
+    @Override
     public void executeScript(String execName) throws BuildException {
         evaluateScript(execName);
     }
@@ -82,70 +94,60 @@
         checkLanguage();
         ClassLoader origLoader = replaceContextLoader();
         try {
-
             if (getCompiled()) {
-
-                final String compiledScriptRefName = MagicNames.SCRIPT_CACHE + "." + getLanguage() +
-                    "." + getScript().hashCode() + "." +
-                    (null == getClass().getClassLoader() ? 0 : getClass().getClassLoader().hashCode());
+                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 ReflectWrapper engine = createEngine();
+                    final ScriptEngine engine = createEngine();
                     if (engine == null) {
                         throw new BuildException(
-                            "Unable to create javax script engine for "
-                            + getLanguage());
+                            "Unable to create javax script engine for %s",
+                            getLanguage());
                     }
+                    if (Compilable.class.isInstance(engine)) {
+                        getProject().log("compile script " + execName,
+                            Project.MSG_VERBOSE);
 
-                    final Class engineClass = Class.forName("javax.script.ScriptEngine", true, getClass().getClassLoader());
-                    final Class compilableClass = Class.forName("javax.script.Compilable", true, getClass().getClassLoader());
-                    final Object wrappedObject = engine.getObject();
-
-                    if (engineClass.isAssignableFrom(wrappedObject.getClass()) &&
-                        compilableClass.isAssignableFrom(wrappedObject.getClass())) {
-
-                        getProject().log("compile script " + execName, Project.MSG_VERBOSE);
-
-                        final Object compiled = engine.invoke("compile", String.class, getScript());
-                        compiledScript = new ReflectWrapper(compiled);
-
+                        compiledScript =
+                            ((Compilable) engine).compile(getScript());
                     } else {
-                        getProject().log("script compilation not available for " + execName, Project.MSG_VERBOSE);
-                        compiledScript = new ReflectWrapper(null);
+                        getProject().log(
+                            "script compilation not available for " + execName,
+                            Project.MSG_VERBOSE);
+                        compiledScript = null;
                     }
-                    getProject().addReference(compiledScriptRefName, compiledScript);
+                    getProject().addReference(compiledScriptRefName,
+                        compiledScript);
                 }
+                if (null != compiledScript) {
+                    final Bindings bindings = new SimpleBindings();
 
-                if (null != compiledScript.getObject()) {
+                    applyBindings(bindings::put);
 
-                    final ReflectWrapper simpleBindings = new ReflectWrapper(getClass().getClassLoader(), "javax.script.SimpleBindings");
+                    getProject().log(
+                        "run compiled script " + compiledScriptRefName,
+                        Project.MSG_DEBUG);
 
-                    applyBindings(simpleBindings);
-
-                    getProject().log("run compiled script " + compiledScriptRefName, Project.MSG_DEBUG);
-
-                    final Class bindingsClass  = Class.forName("javax.script.Bindings", true, getClass().getClassLoader());
-
-                    return compiledScript.invoke("eval", bindingsClass, simpleBindings.getObject());
+                    return compiledScript.eval(bindings);
                 }
             }
 
-            ReflectWrapper engine = createEngine();
+            ScriptEngine engine = createEngine();
             if (engine == null) {
                 throw new BuildException(
                     "Unable to create javax script engine for "
-                    + getLanguage());
+                        + getLanguage());
             }
 
-            applyBindings(engine);
+            applyBindings(engine::put);
 
-            // execute the script
-            return engine.invoke("eval", String.class, getScript());
+            return engine.eval(getScript());
 
         } catch (BuildException be) {
             //catch and rethrow build exceptions
@@ -160,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;
@@ -172,33 +174,29 @@
         }
     }
 
-    private void applyBindings(ReflectWrapper engine) {
-        for (Iterator i = getBeans().keySet().iterator(); i.hasNext();) {
-            String key = (String) i.next();
-            Object value = getBeans().get(key);
-            if ("FX".equalsIgnoreCase(getLanguage())) {
-                key += ":" + value.getClass().getName(); 
-            }
-            engine.invoke("put", String.class, key, Object.class, value);
+    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));
         }
+        source.forEach(target::accept);
     }
 
-    private ReflectWrapper createEngine() {
-        if (engine != null) {
-            return engine;
+    private ScriptEngine createEngine() {
+        if (keptEngine != null) {
+            return keptEngine;
         }
-        ReflectWrapper manager = new ReflectWrapper(
-            getClass().getClassLoader(), "javax.script.ScriptEngineManager");
-        Object e = manager.invoke(
-            "getEngineByName", String.class, getLanguage());
-        if (e == null) {
-            return null;
+        ScriptEngine result =
+            new ScriptEngineManager().getEngineByName(getLanguage());
+        if (result != null && getKeepEngine()) {
+            this.keptEngine = result;
         }
-        ReflectWrapper ret = new ReflectWrapper(e);
-        if (getKeepEngine()) {
-            this.engine = ret;
-        }
-        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 0f4cd1f..39439ae 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();
@@ -146,8 +149,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 529a78a..928939f 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 substition 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 865f424..b497b78 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 3ca8070..76d2789 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 a0a8a15..22d5888 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 ebd85fa..df2b2fd 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 b4173a9..4dc25dc 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.
@@ -109,23 +111,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;
@@ -135,46 +137,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.
@@ -204,234 +201,222 @@
      *
      */
     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};
+        int[] ok = { OK_QUIT };
         try {
             send("QUIT", ok);
         } catch (IOException e) {
@@ -440,23 +425,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) {
@@ -485,42 +470,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 c1693f4..b6b3172 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 resonse.
      */
-    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/tests/junit/org/apache/tools/ant/taskdefs/ProtectedJarMethodsTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/ProtectedJarMethodsTest.java
index 27b3c8c..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/types/resources/LazyResourceCollectionTest.java b/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java
index bb85d81..34bcecd 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
@@ -1,186 +1,184 @@
-/*

- *  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.resources;

+/*
+ *  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.resources;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class LazyResourceCollectionTest {
+
+    private class StringResourceCollection implements ResourceCollection {
+        List<StringResourceIterator> createdIterators = new ArrayList<>();

+
+        @Override

+        public int 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<Resource> {

+        int cursor = 0;
+
+        @Override

+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override

+        public StringResource next() {

+            if (cursor < 3) {
+                cursor++;
+                return new StringResource("r" + cursor);
+            }
+            return null;
+        }
+
+        @Override

+        public boolean hasNext() {
+            return cursor < 3;
+        }
+    }
+
+    @Test
+    public void testLazyLoading() throws Exception {
+        StringResourceCollection collectionTest = new StringResourceCollection();
+        LazyResourceCollectionWrapper lazyCollection = new LazyResourceCollectionWrapper();
+        lazyCollection.add(collectionTest);
+
+        Iterator<Resource> it = lazyCollection.iterator();
+        assertOneCreatedIterator(collectionTest);
+        StringResourceIterator stringResourceIterator =

+            collectionTest.createdIterators.get(0);

+        assertEquals("A resource was loaded without iterating", 1,
+            stringResourceIterator.cursor);

+
+        assertStringValue("r1", it.next());

+        assertOneCreatedIterator(collectionTest);
+        assertEquals("Iterating once load more than 1 resource", 2,
+            stringResourceIterator.cursor);

+
+        assertStringValue("r2", it.next());

+        assertOneCreatedIterator(collectionTest);
+        assertEquals("Iterating twice load more than 2 resources", 3,
+            stringResourceIterator.cursor);

+
+        assertStringValue("r3", it.next());

+        assertOneCreatedIterator(collectionTest);
+        assertEquals("Iterating 3 times load more than 3 resources", 3,
+            stringResourceIterator.cursor);

+
+        try {
+            it.next();
+            fail("NoSuchElementException should have been raised");
+        } catch (NoSuchElementException e) {
+            // ok
+        }
+    }
+
+    private void assertOneCreatedIterator(
+            StringResourceCollection testCollection) {
+        assertEquals("More than one iterator has been created", 1,
+                testCollection.createdIterators.size());
+    }
+
+    @Test
+    public void testCaching() throws Exception {
+        StringResourceCollection collectionTest = new StringResourceCollection();
+        LazyResourceCollectionWrapper lazyCollection = new LazyResourceCollectionWrapper();
+        lazyCollection.add(collectionTest);
+
+        assertTrue(lazyCollection.isCache());
+        Iterator<Resource> it1 = lazyCollection.iterator();
+        assertOneCreatedIterator(collectionTest);
+        Iterator<Resource> it2 = lazyCollection.iterator();
+        assertOneCreatedIterator(collectionTest);
+
+        StringResourceIterator stringResourceIterator =

+            collectionTest.createdIterators.get(0);

+        assertEquals("A resource was loaded without iterating", 1,
+            stringResourceIterator.cursor);

+
+        assertStringValue("r1", it1.next());

+        assertEquals("Iterating once load more than 1 resource", 2,
+            stringResourceIterator.cursor);

+
+        assertStringValue("r1", it2.next());

+        assertEquals(
+            "The second iterator did not lookup in the cache for a resource", 2,

+            stringResourceIterator.cursor);

+
+        assertStringValue("r2", it2.next());

+        assertEquals("Iterating twice load more than 2 resources", 3,
+            stringResourceIterator.cursor);

+
+        assertStringValue("r2", it1.next());

+        assertEquals(
+            "The first iterator did not lookup in the cache for a resource", 3,

+            stringResourceIterator.cursor);

+
+        assertStringValue("r3", it2.next());

+        assertEquals("Iterating 3 times load more than 3 resources", 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();
+            fail("NoSuchElementException should have been raised");
+        } catch (NoSuchElementException e) {
+            // ok
+        }
+
+        try {
+            it2.next();
+            fail("NoSuchElementException should have been raised");
+        } catch (NoSuchElementException e) {
+            // ok
+        }
+    }
 

-import java.util.ArrayList;

-import java.util.Arrays;

-import java.util.Iterator;

-import java.util.List;

-import java.util.NoSuchElementException;

-

-

-import org.apache.tools.ant.types.Resource;

-import org.apache.tools.ant.types.ResourceCollection;

-import org.junit.Test;

-

-import static org.junit.Assert.assertEquals;

-import static org.junit.Assert.assertTrue;

-import static org.junit.Assert.fail;

-

-public class LazyResourceCollectionTest {

-

-    private class StringResourceCollection implements ResourceCollection {

-        List resources = Arrays.<Resource>asList();

-

-        List createdIterators = new ArrayList();

-

-        public int size() {

-            return resources.size();

-        }

-

-        public Iterator<Resource> iterator() {

-            StringResourceIterator it = new StringResourceIterator();

-            createdIterators.add(it);

-            return it;

-        }

-

-        public boolean isFilesystemOnly() {

-            return false;

-        }

+    private void assertStringValue(String expected, Resource r) {

+        assertEquals(expected, r.as(StringResource.class).getValue());

     }

-

-    private class StringResourceIterator implements Iterator {

-        int cursor = 0;

-

-        public void remove() {

-            throw new UnsupportedOperationException();

-        }

-

-        public Object next() {

-            if (cursor < 3) {

-                cursor++;

-                return new StringResource("r" + cursor);

-            }

-            return null;

-        }

-

-        public boolean hasNext() {

-            return cursor < 3;

-        }

-    }

-

-    @Test

-    public void testLazyLoading() throws Exception {

-        StringResourceCollection collectionTest = new StringResourceCollection();

-        LazyResourceCollectionWrapper lazyCollection = new LazyResourceCollectionWrapper();

-        lazyCollection.add(collectionTest);

-

-        Iterator<Resource> it = lazyCollection.iterator();

-        assertOneCreatedIterator(collectionTest);

-        StringResourceIterator stringResourceIterator = (StringResourceIterator) collectionTest.createdIterators

-                .get(0);

-        assertEquals("A resource was loaded without iterating", 1,

-                stringResourceIterator.cursor);

-

-        StringResource r = (StringResource) it.next();

-        assertOneCreatedIterator(collectionTest);

-        assertEquals("r1", r.getValue());

-        assertEquals("Iterating once load more than 1 resource", 2,

-                stringResourceIterator.cursor);

-

-        r = (StringResource) it.next();

-        assertOneCreatedIterator(collectionTest);

-        assertEquals("r2", r.getValue());

-        assertEquals("Iterating twice load more than 2 resources", 3,

-                stringResourceIterator.cursor);

-

-        r = (StringResource) it.next();

-        assertOneCreatedIterator(collectionTest);

-        assertEquals("r3", r.getValue());

-        assertEquals("Iterating 3 times load more than 3 resources", 3,

-                stringResourceIterator.cursor);

-

-        try {

-            it.next();

-            fail("NoSuchElementException should have been raised");

-        } catch (NoSuchElementException e) {

-            // ok

-        }

-    }

-

-    private void assertOneCreatedIterator(

-            StringResourceCollection testCollection) {

-        assertEquals("More than one iterator has been created", 1,

-                testCollection.createdIterators.size());

-    }

-

-    @Test

-    public void testCaching() throws Exception {

-        StringResourceCollection collectionTest = new StringResourceCollection();

-        LazyResourceCollectionWrapper lazyCollection = new LazyResourceCollectionWrapper();

-        lazyCollection.add(collectionTest);

-

-        assertTrue(lazyCollection.isCache());

-        Iterator<Resource> it1 = lazyCollection.iterator();

-        assertOneCreatedIterator(collectionTest);

-        Iterator<Resource> it2 = lazyCollection.iterator();

-        assertOneCreatedIterator(collectionTest);

-

-        StringResourceIterator stringResourceIterator = (StringResourceIterator) collectionTest.createdIterators

-                .get(0);

-        assertEquals("A resource was loaded without iterating", 1,

-                stringResourceIterator.cursor);

-

-        StringResource r = (StringResource) it1.next();

-        assertEquals("r1", r.getValue());

-        assertEquals("Iterating once load more than 1 resource", 2,

-                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);

-

-        r = (StringResource) it2.next();

-        assertEquals("r2", r.getValue());

-        assertEquals("Iterating twice load more than 2 resources", 3,

-                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);

-

-        r = (StringResource) it2.next();

-        assertEquals("r3", r.getValue());

-        assertEquals("Iterating 3 times load more than 3 resources", 3,

-                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);

-

-        try {

-            it1.next();

-            fail("NoSuchElementException should have been raised");

-        } catch (NoSuchElementException e) {

-            // ok

-        }

-

-        try {

-            it2.next();

-            fail("NoSuchElementException should have been raised");

-        } catch (NoSuchElementException e) {

-            // ok

-        }

-    }

-}

+}