package org.apache.maven.plugins.javadoc;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.http.HttpHeaders;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Settings;
import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.DefaultInvoker;
import org.apache.maven.shared.invoker.InvocationOutputHandler;
import org.apache.maven.shared.invoker.InvocationRequest;
import org.apache.maven.shared.invoker.InvocationResult;
import org.apache.maven.shared.invoker.Invoker;
import org.apache.maven.shared.invoker.MavenInvocationException;
import org.apache.maven.shared.invoker.PrintStreamHandler;
import org.apache.maven.wagon.proxy.ProxyInfo;
import org.apache.maven.wagon.proxy.ProxyUtils;
import org.codehaus.plexus.languages.java.version.JavaVersion;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.Os;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.cli.CommandLineException;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import org.codehaus.plexus.util.cli.Commandline;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Modifier;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * Set of utilities methods for Javadoc.
 *
 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
 * @since 2.4
 */
public class JavadocUtil
{
    /** The default timeout used when fetching url, i.e. 2000. */
    public static final int DEFAULT_TIMEOUT = 2000;

    /** Error message when VM could not be started using invoker. */
    protected static final String ERROR_INIT_VM =
        "Error occurred during initialization of VM, try to reduce the Java heap size for the MAVEN_OPTS "
            + "environment variable using -Xms:<size> and -Xmx:<size>.";

    /**
     * Method that removes the invalid directories in the specified directories. <b>Note</b>: All elements in
     * <code>dirs</code> could be an absolute or relative against the project's base directory <code>String</code> path.
     *
     * @param project the current Maven project not null
     * @param dirs the collection of <code>String</code> directories path that will be validated.
     * @return a List of valid <code>String</code> directories absolute paths.
     */
    public static Collection<Path> pruneDirs( MavenProject project, Collection<String> dirs )
    {
        final Path projectBasedir = project.getBasedir().toPath();

        Set<Path> pruned = new LinkedHashSet<>( dirs.size() );
        for ( String dir : dirs )
        {
            if ( dir == null )
            {
                continue;
            }

            Path directory = projectBasedir.resolve( dir );

            if ( Files.isDirectory( directory ) )
            {
                pruned.add( directory.toAbsolutePath() );
            }
        }

        return pruned;
    }

    /**
     * Method that removes the invalid files in the specified files. <b>Note</b>: All elements in <code>files</code>
     * should be an absolute <code>String</code> path.
     *
     * @param files the list of <code>String</code> files paths that will be validated.
     * @return a List of valid <code>File</code> objects.
     */
    protected static List<String> pruneFiles( Collection<String> files )
    {
        List<String> pruned = new ArrayList<>( files.size() );
        for ( String f : files )
        {
            if ( !shouldPruneFile( f, pruned ) )
            {
                pruned.add( f );
            }
        }

        return pruned;
    }

    /**
     * Determine whether a file should be excluded from the provided list of paths, based on whether it exists and is
     * already present in the list.
     *
     * @param f The files.
     * @param pruned The list of pruned files..
     * @return true if the file could be pruned false otherwise.
     */
    public static boolean shouldPruneFile( String f, List<String> pruned )
    {
        if ( f != null )
        {
            File file = new File( f );
            if ( file.isFile() && ( isEmpty( pruned ) || !pruned.contains( f ) ) )
            {
                return false;
            }
        }

        return true;
    }

    /**
     * Method that gets all the source files to be excluded from the javadoc on the given source paths.
     *
     * @param sourcePaths the path to the source files
     * @param excludedPackages the package names to be excluded in the javadoc
     * @return a List of the packages to be excluded in the generated javadoc
     */
    protected static List<String> getExcludedPackages( Collection<Path> sourcePaths,
                                                       Collection<String> excludedPackages )
    {
        List<String> excludedNames = new ArrayList<>();
        for ( Path sourcePath : sourcePaths )
        {
            excludedNames.addAll( getExcludedPackages( sourcePath, excludedPackages ) );
        }

        return excludedNames;
    }

    /**
     * Convenience method to wrap an argument value in single quotes (i.e. <code>'</code>). Intended for values which
     * may contain whitespaces. <br>
     * To prevent javadoc error, the line separator (i.e. <code>\n</code>) are skipped.
     *
     * @param value the argument value.
     * @return argument with quote
     */
    protected static String quotedArgument( String value )
    {
        String arg = value;

        if ( StringUtils.isNotEmpty( arg ) )
        {
            if ( arg.contains( "'" ) )
            {
                arg = StringUtils.replace( arg, "'", "\\'" );
            }
            arg = "'" + arg + "'";

            // To prevent javadoc error
            arg = StringUtils.replace( arg, "\n", " " );
        }

        return arg;
    }

    /**
     * Convenience method to format a path argument so that it is properly interpreted by the javadoc tool. Intended for
     * path values which may contain whitespaces.
     *
     * @param value the argument value.
     * @return path argument with quote
     */
    protected static String quotedPathArgument( String value )
    {
        String path = value;

        if ( StringUtils.isNotEmpty( path ) )
        {
            path = path.replace( '\\', '/' );
            if ( path.contains( "\'" ) )
            {
                String split[] = path.split( "\'" );
                path = "";

                for ( int i = 0; i < split.length; i++ )
                {
                    if ( i != split.length - 1 )
                    {
                        path = path + split[i] + "\\'";
                    }
                    else
                    {
                        path = path + split[i];
                    }
                }
            }
            path = "'" + path + "'";
        }

        return path;
    }

    /**
     * Convenience method that copy all <code>doc-files</code> directories from <code>javadocDir</code> to the
     * <code>outputDirectory</code>.
     *
     * @param outputDirectory the output directory
     * @param javadocDir the javadoc directory
     * @param excludedocfilessubdir the excludedocfilessubdir parameter
     * @throws IOException if any
     * @since 2.5
     */
    protected static void copyJavadocResources( File outputDirectory, File javadocDir, String excludedocfilessubdir )
        throws IOException
    {
        if ( !javadocDir.isDirectory() )
        {
            return;
        }

        List<String> excludes = new ArrayList<>( Arrays.asList( FileUtils.getDefaultExcludes() ) );

        if ( StringUtils.isNotEmpty( excludedocfilessubdir ) )
        {
            StringTokenizer st = new StringTokenizer( excludedocfilessubdir, ":" );
            String current;
            while ( st.hasMoreTokens() )
            {
                current = st.nextToken();
                excludes.add( "**/" + current + "/**" );
            }
        }

        List<String> docFiles =
            FileUtils.getDirectoryNames( javadocDir, "resources,**/doc-files",
                                         StringUtils.join( excludes.iterator(), "," ), false, true );
        for ( String docFile : docFiles )
        {
            File docFileOutput = new File( outputDirectory, docFile );
            FileUtils.mkdir( docFileOutput.getAbsolutePath() );
            FileUtils.copyDirectoryStructure( new File( javadocDir, docFile ), docFileOutput );
            List<String> files =
                FileUtils.getFileAndDirectoryNames( docFileOutput, StringUtils.join( excludes.iterator(), "," ), null,
                                                    true, true, true, true );
            for ( String filename : files )
            {
                File file = new File( filename );

                if ( file.isDirectory() )
                {
                    FileUtils.deleteDirectory( file );
                }
                else
                {
                    file.delete();
                }
            }
        }
    }

    /**
     * Method that gets the files or classes that would be included in the javadocs using the subpackages parameter.
     *
     * @param sourceDirectory the directory where the source files are located
     * @param fileList the list of all relative files found in the sourceDirectory
     * @param excludePackages package names to be excluded in the javadoc
     * @return a StringBuilder that contains the appended file names of the files to be included in the javadoc
     */
    protected static List<String> getIncludedFiles( File sourceDirectory, String[] fileList,
                                                    Collection<String> excludePackages )
    {
        List<String> files = new ArrayList<>();

        List<Pattern> excludePackagePatterns = new ArrayList<>( excludePackages.size() );
        for ( String excludePackage :  excludePackages )
        {
            excludePackagePatterns.add( Pattern.compile( excludePackage.replace( '.', File.separatorChar )
                                                                       .replace( "\\", "\\\\" )
                                                                       .replace( "*", ".+" )
                                                                       .concat( "[\\\\/][^\\\\/]+\\.java" )
                                                                                ) );
        }

        for ( String file : fileList )
        {
            boolean excluded = false;
            for ( Pattern excludePackagePattern :  excludePackagePatterns )
            {
                if ( excludePackagePattern.matcher( file ).matches() )
                {
                    excluded = true;
                    break;
                }
            }

            if ( !excluded )
            {
                files.add( file );
            }
        }

        return files;
    }

    /**
     * Method that gets the complete package names (including subpackages) of the packages that were defined in the
     * excludePackageNames parameter.
     *
     * @param sourceDirectory the directory where the source files are located
     * @param excludePackagenames package names to be excluded in the javadoc
     * @return a List of the packagenames to be excluded
     */
    protected static Collection<String> getExcludedPackages( final Path sourceDirectory,
                                                             Collection<String> excludePackagenames )
    {
        final String regexFileSeparator = File.separator.replace( "\\", "\\\\" );

        final Collection<String> fileList = new ArrayList<>();

        try
        {
            Files.walkFileTree( sourceDirectory, new SimpleFileVisitor<Path>()
            {
                @Override
                public FileVisitResult visitFile( Path file, BasicFileAttributes attrs )
                    throws IOException
                {
                    if ( file.getFileName().toString().endsWith( ".java" ) )
                    {
                        fileList.add( sourceDirectory.relativize( file.getParent() ).toString() );
                    }
                    return FileVisitResult.CONTINUE;
                }
            } );
        }
        catch ( IOException e )
        {
            // noop
        }

        List<String> files = new ArrayList<>();
        for ( String excludePackagename : excludePackagenames )
        {
            // Usage of wildcard was bad specified and bad implemented, i.e. using String.contains()
            //   without respecting surrounding context
            // Following implementation should match requirements as defined in the examples:
            // - A wildcard at the beginning should match 1 or more folders
            // - Any other wildcard must match exactly one folder
            Pattern p = Pattern.compile( excludePackagename.replace( ".", regexFileSeparator )
                                                           .replaceFirst( "^\\*", ".+" )
                                                           .replace( "*", "[^" + regexFileSeparator + "]+" ) );

            for ( String aFileList : fileList )
            {
                if ( p.matcher( aFileList ).matches() )
                {
                    files.add( aFileList.replace( File.separatorChar, '.' ) );
                }
            }
        }

        return files;
    }

    /**
     * Convenience method that gets the files to be included in the javadoc.
     *
     * @param sourceDirectory the directory where the source files are located
     * @param excludePackages the packages to be excluded in the javadocs
     * @param sourceFileIncludes files to include.
     * @param sourceFileExcludes files to exclude.
     */
    protected static List<String> getFilesFromSource( File sourceDirectory, List<String> sourceFileIncludes,
                                                      List<String> sourceFileExcludes,
                                                      Collection<String> excludePackages )
    {
        DirectoryScanner ds = new DirectoryScanner();
        if ( sourceFileIncludes == null )
        {
            sourceFileIncludes = Collections.singletonList( "**/*.java" );
        }
        ds.setIncludes( sourceFileIncludes.toArray( new String[sourceFileIncludes.size()] ) );
        if ( sourceFileExcludes != null && sourceFileExcludes.size() > 0 )
        {
            ds.setExcludes( sourceFileExcludes.toArray( new String[sourceFileExcludes.size()] ) );
        }
        ds.setBasedir( sourceDirectory );
        ds.scan();

        String[] fileList = ds.getIncludedFiles();

        List<String> files = new ArrayList<>();
        if ( fileList.length != 0 )
        {
            for ( String includedFile : getIncludedFiles( sourceDirectory, fileList, excludePackages ) )
            {
                files.add( includedFile );
            }
        }

        return files;
    }

    /**
     * Call the Javadoc tool and parse its output to find its version, i.e.:
     *
     * <pre>
     * javadoc.exe( or.sh ) - J - version
     * </pre>
     *
     * @param javadocExe not null file
     * @return the javadoc version as float
     * @throws IOException if javadocExe is null, doesn't exist or is not a file
     * @throws CommandLineException if any
     * @throws IllegalArgumentException if no output was found in the command line
     * @throws PatternSyntaxException if the output contains a syntax error in the regular-expression pattern.
     * @see #extractJavadocVersion(String)
     */
    protected static JavaVersion getJavadocVersion( File javadocExe )
        throws IOException, CommandLineException, IllegalArgumentException
    {
        if ( ( javadocExe == null ) || ( !javadocExe.exists() ) || ( !javadocExe.isFile() ) )
        {
            throw new IOException( "The javadoc executable '" + javadocExe + "' doesn't exist or is not a file. " );
        }

        Commandline cmd = new Commandline();
        cmd.setExecutable( javadocExe.getAbsolutePath() );
        cmd.setWorkingDirectory( javadocExe.getParentFile() );
        cmd.createArg().setValue( "-J-version" );

        CommandLineUtils.StringStreamConsumer out = new JavadocOutputStreamConsumer();
        CommandLineUtils.StringStreamConsumer err = new JavadocOutputStreamConsumer();

        int exitCode = CommandLineUtils.executeCommandLine( cmd, out, err );

        if ( exitCode != 0 )
        {
            StringBuilder msg = new StringBuilder( "Exit code: " + exitCode + " - " + err.getOutput() );
            msg.append( '\n' );
            msg.append( "Command line was:" + CommandLineUtils.toString( cmd.getCommandline() ) );
            throw new CommandLineException( msg.toString() );
        }

        if ( StringUtils.isNotEmpty( err.getOutput() ) )
        {
            return JavaVersion.parse( extractJavadocVersion( err.getOutput() ) );
        }
        else if ( StringUtils.isNotEmpty( out.getOutput() ) )
        {
            return JavaVersion.parse( extractJavadocVersion( out.getOutput() ) );
        }

        throw new IllegalArgumentException( "No output found from the command line 'javadoc -J-version'" );
    }

    /**
     * Parse the output for 'javadoc -J-version' and return the javadoc version recognized. <br>
     * Here are some output for 'javadoc -J-version' depending the JDK used:
     * <table summary="Output for 'javadoc -J-version' per JDK">
     * <tr>
     * <th>JDK</th>
     * <th>Output for 'javadoc -J-version'</th>
     * </tr>
     * <tr>
     * <td>Sun 1.4</td>
     * <td>java full version "1.4.2_12-b03"</td>
     * </tr>
     * <tr>
     * <td>Sun 1.5</td>
     * <td>java full version "1.5.0_07-164"</td>
     * </tr>
     * <tr>
     * <td>IBM 1.4</td>
     * <td>javadoc full version "J2RE 1.4.2 IBM Windows 32 build cn1420-20040626"</td>
     * </tr>
     * <tr>
     * <td>IBM 1.5 (French JVM)</td>
     * <td>javadoc version complète de "J2RE 1.5.0 IBM Windows 32 build pwi32pdev-20070426a"</td>
     * </tr>
     * <tr>
     * <td>FreeBSD 1.5</td>
     * <td>java full version "diablo-1.5.0-b01"</td>
     * </tr>
     * <tr>
     * <td>BEA jrockit 1.5</td>
     * <td>java full version "1.5.0_11-b03"</td>
     * </tr>
     * </table>
     *
     * @param output for 'javadoc -J-version'
     * @return the version of the javadoc for the output, only digits and dots
     * @throws PatternSyntaxException if the output doesn't match with the output pattern
     *             <tt>(?s).*?[^a-zA-Z]([0-9]+\\.?[0-9]*)(\\.([0-9]+))?.*</tt>.
     * @throws IllegalArgumentException if the output is null
     */
    protected static String extractJavadocVersion( String output )
        throws IllegalArgumentException
    {
        if ( StringUtils.isEmpty( output ) )
        {
            throw new IllegalArgumentException( "The output could not be null." );
        }

        Pattern pattern = Pattern.compile( "(?s).*?[^a-zA-Z](([0-9]+\\.?[0-9]*)(\\.[0-9]+)?).*" );

        Matcher matcher = pattern.matcher( output );
        if ( !matcher.matches() )
        {
            throw new PatternSyntaxException( "Unrecognized version of Javadoc: '" + output + "'", pattern.pattern(),
                                              pattern.toString().length() - 1 );
        }

        return matcher.group( 1 );
    }

    /**
     * Parse a memory string which be used in the JVM arguments <code>-Xms</code> or <code>-Xmx</code>. <br>
     * Here are some supported memory string depending the JDK used:
     * <table summary="Memory argument support per JDK">
     * <tr>
     * <th>JDK</th>
     * <th>Memory argument support for <code>-Xms</code> or <code>-Xmx</code></th>
     * </tr>
     * <tr>
     * <td>SUN</td>
     * <td>1024k | 128m | 1g | 1t</td>
     * </tr>
     * <tr>
     * <td>IBM</td>
     * <td>1024k | 1024b | 128m | 128mb | 1g | 1gb</td>
     * </tr>
     * <tr>
     * <td>BEA</td>
     * <td>1024k | 1024kb | 128m | 128mb | 1g | 1gb</td>
     * </tr>
     * </table>
     *
     * @param memory the memory to be parsed, not null.
     * @return the memory parsed with a supported unit. If no unit specified in the <code>memory</code> parameter, the
     *         default unit is <code>m</code>. The units <code>g | gb</code> or <code>t | tb</code> will be converted in
     *         <code>m</code>.
     * @throws IllegalArgumentException if the <code>memory</code> parameter is null or doesn't match any pattern.
     */
    protected static String parseJavadocMemory( String memory )
        throws IllegalArgumentException
    {
        if ( StringUtils.isEmpty( memory ) )
        {
            throw new IllegalArgumentException( "The memory could not be null." );
        }

        Pattern p = Pattern.compile( "^\\s*(\\d+)\\s*?\\s*$" );
        Matcher m = p.matcher( memory );
        if ( m.matches() )
        {
            return m.group( 1 ) + "m";
        }

        p = Pattern.compile( "^\\s*(\\d+)\\s*k(b)?\\s*$", Pattern.CASE_INSENSITIVE );
        m = p.matcher( memory );
        if ( m.matches() )
        {
            return m.group( 1 ) + "k";
        }

        p = Pattern.compile( "^\\s*(\\d+)\\s*m(b)?\\s*$", Pattern.CASE_INSENSITIVE );
        m = p.matcher( memory );
        if ( m.matches() )
        {
            return m.group( 1 ) + "m";
        }

        p = Pattern.compile( "^\\s*(\\d+)\\s*g(b)?\\s*$", Pattern.CASE_INSENSITIVE );
        m = p.matcher( memory );
        if ( m.matches() )
        {
            return ( Integer.parseInt( m.group( 1 ) ) * 1024 ) + "m";
        }

        p = Pattern.compile( "^\\s*(\\d+)\\s*t(b)?\\s*$", Pattern.CASE_INSENSITIVE );
        m = p.matcher( memory );
        if ( m.matches() )
        {
            return ( Integer.parseInt( m.group( 1 ) ) * 1024 * 1024 ) + "m";
        }

        throw new IllegalArgumentException( "Could convert not to a memory size: " + memory );
    }

    /**
     * Validate if a charset is supported on this platform.
     *
     * @param charsetName the charsetName to be check.
     * @return <code>true</code> if the given charset is supported by the JVM, <code>false</code> otherwise.
     */
    protected static boolean validateEncoding( String charsetName )
    {
        if ( StringUtils.isEmpty( charsetName ) )
        {
            return false;
        }

        try
        {
            return Charset.isSupported( charsetName );
        }
        catch ( IllegalCharsetNameException e )
        {
            return false;
        }
    }

    /**
     * For security reasons, if an active proxy is defined and needs an authentication by username/password, hide the
     * proxy password in the command line.
     *
     * @param cmdLine a command line, not null
     * @param settings the user settings
     * @return the cmdline with '*' for the http.proxyPassword JVM property
     */
    protected static String hideProxyPassword( String cmdLine, Settings settings )
    {
        if ( cmdLine == null )
        {
            throw new IllegalArgumentException( "cmdLine could not be null" );
        }

        if ( settings == null )
        {
            return cmdLine;
        }

        Proxy activeProxy = settings.getActiveProxy();
        if ( activeProxy != null && StringUtils.isNotEmpty( activeProxy.getHost() )
            && StringUtils.isNotEmpty( activeProxy.getUsername() )
            && StringUtils.isNotEmpty( activeProxy.getPassword() ) )
        {
            String pass = "-J-Dhttp.proxyPassword=\"" + activeProxy.getPassword() + "\"";
            String hidepass =
                "-J-Dhttp.proxyPassword=\"" + StringUtils.repeat( "*", activeProxy.getPassword().length() ) + "\"";

            return StringUtils.replace( cmdLine, pass, hidepass );
        }

        return cmdLine;
    }

    /**
     * Auto-detect the class names of the implementation of <code>com.sun.tools.doclets.Taglet</code> class from a given
     * jar file. <br>
     * <b>Note</b>: <code>JAVA_HOME/lib/tools.jar</code> is a requirement to find
     * <code>com.sun.tools.doclets.Taglet</code> class.
     *
     * @param jarFile not null
     * @return the list of <code>com.sun.tools.doclets.Taglet</code> class names from a given jarFile.
     * @throws IOException if jarFile is invalid or not found, or if the <code>JAVA_HOME/lib/tools.jar</code> is not
     *             found.
     * @throws ClassNotFoundException if any
     * @throws NoClassDefFoundError if any
     */
    protected static List<String> getTagletClassNames( File jarFile )
        throws IOException, ClassNotFoundException, NoClassDefFoundError
    {
        List<String> classes = getClassNamesFromJar( jarFile );
        ClassLoader cl;

        // Needed to find com.sun.tools.doclets.Taglet class
        File tools = new File( System.getProperty( "java.home" ), "../lib/tools.jar" );
        if ( tools.exists() && tools.isFile() )
        {
            cl = new URLClassLoader( new URL[] { jarFile.toURI().toURL(), tools.toURI().toURL() }, null );
        }
        else
        {
            cl = new URLClassLoader( new URL[] { jarFile.toURI().toURL() }, ClassLoader.getSystemClassLoader() );
        }

        List<String> tagletClasses = new ArrayList<>();

        Class<?> tagletClass;

        try
        {
            tagletClass = cl.loadClass( "com.sun.tools.doclets.Taglet" );
        }
        catch ( ClassNotFoundException e )
        {
            tagletClass = cl.loadClass( "jdk.javadoc.doclet.Taglet" );
        }

        for ( String s : classes )
        {
            Class<?> c = cl.loadClass( s );

            if ( tagletClass.isAssignableFrom( c ) && !Modifier.isAbstract( c.getModifiers() ) )
            {
                tagletClasses.add( c.getName() );
            }
        }

        return tagletClasses;
    }

    /**
     * Copy the given url to the given file.
     *
     * @param url not null url
     * @param file not null file where the url will be created
     * @throws IOException if any
     * @since 2.6
     */
    protected static void copyResource( URL url, File file )
        throws IOException
    {
        if ( file == null )
        {
            throw new IOException( "The file can't be null." );
        }
        if ( url == null )
        {
            throw new IOException( "The url could not be null." );
        }

        FileUtils.copyURLToFile( url, file );
    }

    /**
     * Invoke Maven for the given project file with a list of goals and properties, the output will be in the invokerlog
     * file. <br>
     * <b>Note</b>: the Maven Home should be defined in the <code>maven.home</code> Java system property or defined in
     * <code>M2_HOME</code> system env variables.
     *
     * @param log a logger could be null.
     * @param localRepositoryDir the localRepository not null.
     * @param projectFile a not null project file.
     * @param goals a not null goals list.
     * @param properties the properties for the goals, could be null.
     * @param invokerLog the log file where the invoker will be written, if null using <code>System.out</code>.
     * @throws MavenInvocationException if any
     * @since 2.6
     */
    protected static void invokeMaven( Log log, File localRepositoryDir, File projectFile, List<String> goals,
                                       Properties properties, File invokerLog )
        throws MavenInvocationException
    {
        if ( projectFile == null )
        {
            throw new IllegalArgumentException( "projectFile should be not null." );
        }
        if ( !projectFile.isFile() )
        {
            throw new IllegalArgumentException( projectFile.getAbsolutePath() + " is not a file." );
        }
        if ( goals == null || goals.size() == 0 )
        {
            throw new IllegalArgumentException( "goals should be not empty." );
        }
        if ( localRepositoryDir == null || !localRepositoryDir.isDirectory() )
        {
            throw new IllegalArgumentException( "localRepositoryDir '" + localRepositoryDir
                + "' should be a directory." );
        }

        String mavenHome = getMavenHome( log );
        if ( StringUtils.isEmpty( mavenHome ) )
        {
            String msg = "Could NOT invoke Maven because no Maven Home is defined. You need to have set the M2_HOME "
                + "system env variable or a maven.home Java system properties.";
            if ( log != null )
            {
                log.error( msg );
            }
            else
            {
                System.err.println( msg );
            }
            return;
        }

        Invoker invoker = new DefaultInvoker();
        invoker.setMavenHome( new File( mavenHome ) );
        invoker.setLocalRepositoryDirectory( localRepositoryDir );

        InvocationRequest request = new DefaultInvocationRequest();
        request.setBaseDirectory( projectFile.getParentFile() );
        request.setPomFile( projectFile );
        request.setBatchMode( true );
        if ( log != null )
        {
            request.setDebug( log.isDebugEnabled() );
        }
        else
        {
            request.setDebug( true );
        }
        request.setGoals( goals );
        if ( properties != null )
        {
            request.setProperties( properties );
        }
        File javaHome = getJavaHome( log );
        if ( javaHome != null )
        {
            request.setJavaHome( javaHome );
        }

        if ( log != null && log.isDebugEnabled() )
        {
            log.debug( "Invoking Maven for the goals: " + goals + " with "
                + ( properties == null ? "no properties" : "properties=" + properties ) );
        }
        InvocationResult result = invoke( log, invoker, request, invokerLog, goals, properties, null );

        if ( result.getExitCode() != 0 )
        {
            String invokerLogContent = readFile( invokerLog, "UTF-8" );

            // see DefaultMaven
            if ( invokerLogContent != null && ( !invokerLogContent.contains( "Scanning for projects..." )
                || invokerLogContent.contains( OutOfMemoryError.class.getName() ) ) )
            {
                if ( log != null )
                {
                    log.error( "Error occurred during initialization of VM, trying to use an empty MAVEN_OPTS..." );

                    if ( log.isDebugEnabled() )
                    {
                        log.debug( "Reinvoking Maven for the goals: " + goals + " with an empty MAVEN_OPTS..." );
                    }
                }
                result = invoke( log, invoker, request, invokerLog, goals, properties, "" );
            }
        }

        if ( result.getExitCode() != 0 )
        {
            String invokerLogContent = readFile( invokerLog, "UTF-8" );

            // see DefaultMaven
            if ( invokerLogContent != null && ( !invokerLogContent.contains( "Scanning for projects..." )
                || invokerLogContent.contains( OutOfMemoryError.class.getName() ) ) )
            {
                throw new MavenInvocationException( ERROR_INIT_VM );
            }

            throw new MavenInvocationException( "Error when invoking Maven, consult the invoker log file: "
                + invokerLog.getAbsolutePath() );
        }
    }

    /**
     * Read the given file and return the content or null if an IOException occurs.
     *
     * @param javaFile not null
     * @param encoding could be null
     * @return the content with unified line separator of the given javaFile using the given encoding.
     * @see FileUtils#fileRead(File, String)
     * @since 2.6.1
     */
    protected static String readFile( final File javaFile, final String encoding )
    {
        try
        {
            return FileUtils.fileRead( javaFile, encoding );
        }
        catch ( IOException e )
        {
            return null;
        }
    }

    /**
     * Split the given path with colon and semi-colon, to support Solaris and Windows path. Examples:
     *
     * <pre>
     * splitPath( "/home:/tmp" )     = ["/home", "/tmp"]
     * splitPath( "/home;/tmp" )     = ["/home", "/tmp"]
     * splitPath( "C:/home:C:/tmp" ) = ["C:/home", "C:/tmp"]
     * splitPath( "C:/home;C:/tmp" ) = ["C:/home", "C:/tmp"]
     * </pre>
     *
     * @param path which can contain multiple paths separated with a colon (<code>:</code>) or a semi-colon
     *            (<code>;</code>), platform independent. Could be null.
     * @return the path splitted by colon or semi-colon or <code>null</code> if path was <code>null</code>.
     * @since 2.6.1
     */
    protected static String[] splitPath( final String path )
    {
        if ( path == null )
        {
            return null;
        }

        List<String> subpaths = new ArrayList<>();
        PathTokenizer pathTokenizer = new PathTokenizer( path );
        while ( pathTokenizer.hasMoreTokens() )
        {
            subpaths.add( pathTokenizer.nextToken() );
        }

        return subpaths.toArray( new String[subpaths.size()] );
    }

    /**
     * Unify the given path with the current System path separator, to be platform independent. Examples:
     *
     * <pre>
     * unifyPathSeparator( "/home:/tmp" ) = "/home:/tmp" (Solaris box)
     * unifyPathSeparator( "/home:/tmp" ) = "/home;/tmp" (Windows box)
     * </pre>
     *
     * @param path which can contain multiple paths by separating them with a colon (<code>:</code>) or a semi-colon
     *            (<code>;</code>), platform independent. Could be null.
     * @return the same path but separated with the current System path separator or <code>null</code> if path was
     *         <code>null</code>.
     * @since 2.6.1
     * @see #splitPath(String)
     * @see File#pathSeparator
     */
    protected static String unifyPathSeparator( final String path )
    {
        if ( path == null )
        {
            return null;
        }

        return StringUtils.join( splitPath( path ), File.pathSeparator );
    }

    // ----------------------------------------------------------------------
    // private methods
    // ----------------------------------------------------------------------

    /**
     * @param jarFile not null
     * @return all class names from the given jar file.
     * @throws IOException if any or if the jarFile is null or doesn't exist.
     */
    private static List<String> getClassNamesFromJar( File jarFile )
        throws IOException
    {
        if ( jarFile == null || !jarFile.exists() || !jarFile.isFile() )
        {
            throw new IOException( "The jar '" + jarFile + "' doesn't exist or is not a file." );
        }

        List<String> classes = new ArrayList<>();
        try ( JarInputStream jarStream = new JarInputStream( new FileInputStream( jarFile ) ) )
        {
            for ( JarEntry jarEntry = jarStream.getNextJarEntry(); jarEntry != null; jarEntry =
                jarStream.getNextJarEntry() )
            {
                if ( jarEntry.getName().toLowerCase( Locale.ENGLISH ).endsWith( ".class" ) )
                {
                    String name = jarEntry.getName().substring( 0, jarEntry.getName().indexOf( "." ) );

                    classes.add( name.replaceAll( "/", "\\." ) );
                }

                jarStream.closeEntry();
            }
        }

        return classes;
    }

    /**
     * @param log could be null
     * @param invoker not null
     * @param request not null
     * @param invokerLog not null
     * @param goals not null
     * @param properties could be null
     * @param mavenOpts could be null
     * @return the invocation result
     * @throws MavenInvocationException if any
     * @since 2.6
     */
    private static InvocationResult invoke( Log log, Invoker invoker, InvocationRequest request, File invokerLog,
                                            List<String> goals, Properties properties, String mavenOpts )
        throws MavenInvocationException
    {
        PrintStream ps;
        OutputStream os = null;
        if ( invokerLog != null )
        {
            if ( log != null && log.isDebugEnabled() )
            {
                log.debug( "Using " + invokerLog.getAbsolutePath() + " to log the invoker" );
            }

            try
            {
                if ( !invokerLog.exists() )
                {
                    // noinspection ResultOfMethodCallIgnored
                    invokerLog.getParentFile().mkdirs();
                }
                os = new FileOutputStream( invokerLog );
                ps = new PrintStream( os, true, "UTF-8" );
            }
            catch ( FileNotFoundException e )
            {
                if ( log != null && log.isErrorEnabled() )
                {
                    log.error( "FileNotFoundException: " + e.getMessage() + ". Using System.out to log the invoker." );
                }
                ps = System.out;
            }
            catch ( UnsupportedEncodingException e )
            {
                if ( log != null && log.isErrorEnabled() )
                {
                    log.error( "UnsupportedEncodingException: " + e.getMessage()
                        + ". Using System.out to log the invoker." );
                }
                ps = System.out;
            }
        }
        else
        {
            if ( log != null && log.isDebugEnabled() )
            {
                log.debug( "Using System.out to log the invoker." );
            }

            ps = System.out;
        }

        if ( mavenOpts != null )
        {
            request.setMavenOpts( mavenOpts );
        }

        InvocationOutputHandler outputHandler = new PrintStreamHandler( ps, false );
        request.setOutputHandler( outputHandler );

        outputHandler.consumeLine( "Invoking Maven for the goals: " + goals + " with "
            + ( properties == null ? "no properties" : "properties=" + properties ) );
        outputHandler.consumeLine( "" );
        outputHandler.consumeLine( "M2_HOME=" + getMavenHome( log ) );
        outputHandler.consumeLine( "MAVEN_OPTS=" + getMavenOpts( log ) );
        outputHandler.consumeLine( "JAVA_HOME=" + getJavaHome( log ) );
        outputHandler.consumeLine( "JAVA_OPTS=" + getJavaOpts( log ) );
        outputHandler.consumeLine( "" );

        try
        {
            return invoker.execute( request );
        }
        finally
        {
            IOUtil.close( os );
        }
    }

    /**
     * @param log a logger could be null
     * @return the Maven home defined in the <code>maven.home</code> system property or defined in <code>M2_HOME</code>
     *         system env variables or null if never set.
     * @since 2.6
     */
    private static String getMavenHome( Log log )
    {
        String mavenHome = System.getProperty( "maven.home" );
        if ( mavenHome == null )
        {
            try
            {
                mavenHome = CommandLineUtils.getSystemEnvVars().getProperty( "M2_HOME" );
            }
            catch ( IOException e )
            {
                if ( log != null && log.isDebugEnabled() )
                {
                    log.debug( "IOException: " + e.getMessage() );
                }
            }
        }

        File m2Home = new File( mavenHome );
        if ( !m2Home.exists() )
        {
            if ( log != null && log.isErrorEnabled() )
            {
                log.error( "Cannot find Maven application directory. Either specify \'maven.home\' system property, or "
                    + "M2_HOME environment variable." );
            }
        }

        return mavenHome;
    }

    /**
     * @param log a logger could be null
     * @return the <code>MAVEN_OPTS</code> env variable value
     * @since 2.6
     */
    private static String getMavenOpts( Log log )
    {
        String mavenOpts = null;
        try
        {
            mavenOpts = CommandLineUtils.getSystemEnvVars().getProperty( "MAVEN_OPTS" );
        }
        catch ( IOException e )
        {
            if ( log != null && log.isDebugEnabled() )
            {
                log.debug( "IOException: " + e.getMessage() );
            }
        }

        return mavenOpts;
    }

    /**
     * @param log a logger could be null
     * @return the <code>JAVA_HOME</code> from System.getProperty( "java.home" ) By default,
     *         <code>System.getProperty( "java.home" ) = JRE_HOME</code> and <code>JRE_HOME</code> should be in the
     *         <code>JDK_HOME</code>
     * @since 2.6
     */
    private static File getJavaHome( Log log )
    {
        File javaHome = null;

        String javaHomeValue = null;
        try
        {
            javaHomeValue = CommandLineUtils.getSystemEnvVars().getProperty( "JAVA_HOME" );
        }
        catch ( IOException e )
        {
            if ( log != null && log.isDebugEnabled() )
            {
                log.debug( "IOException: " + e.getMessage() );
            }
        }

        // if maven.home is set, we can assume JAVA_HOME must be used for testing
        if ( System.getProperty( "maven.home" ) == null || javaHomeValue == null )
        {
            // JEP220 (Java9) restructured the JRE/JDK runtime image
            if ( SystemUtils.IS_OS_MAC_OSX || JavaVersion.JAVA_VERSION.isAtLeast( "9" ) )
            {
                javaHome = SystemUtils.getJavaHome();
            }
            else
            {
                javaHome = new File( SystemUtils.getJavaHome(), ".." );
            }
        }

        if ( javaHome == null || !javaHome.exists() )
        {
            javaHome = new File( javaHomeValue );
        }

        if ( javaHome == null || !javaHome.exists() )
        {
            if ( log != null && log.isErrorEnabled() )
            {
                log.error( "Cannot find Java application directory. Either specify \'java.home\' system property, or "
                    + "JAVA_HOME environment variable." );
            }
        }

        return javaHome;
    }

    /**
     * @param log a logger could be null
     * @return the <code>JAVA_OPTS</code> env variable value
     * @since 2.6
     */
    private static String getJavaOpts( Log log )
    {
        String javaOpts = null;
        try
        {
            javaOpts = CommandLineUtils.getSystemEnvVars().getProperty( "JAVA_OPTS" );
        }
        catch ( IOException e )
        {
            if ( log != null && log.isDebugEnabled() )
            {
                log.debug( "IOException: " + e.getMessage() );
            }
        }

        return javaOpts;
    }

    /**
     * A Path tokenizer takes a path and returns the components that make up that path. The path can use path separators
     * of either ':' or ';' and file separators of either '/' or '\'.
     *
     * @version revision 439418 taken on 2009-09-12 from Ant Project (see
     *          http://svn.apache.org/repos/asf/ant/core/trunk/src/main/org/apache/tools/ant/PathTokenizer.java)
     */
    private static class PathTokenizer
    {
        /**
         * A tokenizer to break the string up based on the ':' or ';' separators.
         */
        private StringTokenizer tokenizer;

        /**
         * A String which stores any path components which have been read ahead due to DOS filesystem compensation.
         */
        private String lookahead = null;

        /**
         * A boolean that determines if we are running on Novell NetWare, which exhibits slightly different path name
         * characteristics (multi-character volume / drive names)
         */
        private boolean onNetWare = Os.isFamily( "netware" );

        /**
         * Flag to indicate whether or not we are running on a platform with a DOS style filesystem
         */
        private boolean dosStyleFilesystem;

        /**
         * Constructs a path tokenizer for the specified path.
         *
         * @param path The path to tokenize. Must not be <code>null</code>.
         */
        PathTokenizer( String path )
        {
            if ( onNetWare )
            {
                // For NetWare, use the boolean=true mode, so we can use delimiter
                // information to make a better decision later.
                tokenizer = new StringTokenizer( path, ":;", true );
            }
            else
            {
                // on Windows and Unix, we can ignore delimiters and still have
                // enough information to tokenize correctly.
                tokenizer = new StringTokenizer( path, ":;", false );
            }
            dosStyleFilesystem = File.pathSeparatorChar == ';';
        }

        /**
         * Tests if there are more path elements available from this tokenizer's path. If this method returns
         * <code>true</code>, then a subsequent call to nextToken will successfully return a token.
         *
         * @return <code>true</code> if and only if there is at least one token in the string after the current
         *         position; <code>false</code> otherwise.
         */
        public boolean hasMoreTokens()
        {
            return lookahead != null || tokenizer.hasMoreTokens();

        }

        /**
         * Returns the next path element from this tokenizer.
         *
         * @return the next path element from this tokenizer.
         * @exception NoSuchElementException if there are no more elements in this tokenizer's path.
         */
        public String nextToken()
            throws NoSuchElementException
        {
            String token;
            if ( lookahead != null )
            {
                token = lookahead;
                lookahead = null;
            }
            else
            {
                token = tokenizer.nextToken().trim();
            }

            if ( !onNetWare )
            {
                if ( token.length() == 1 && Character.isLetter( token.charAt( 0 ) ) && dosStyleFilesystem
                    && tokenizer.hasMoreTokens() )
                {
                    // we are on a dos style system so this path could be a drive
                    // spec. We look at the next token
                    String nextToken = tokenizer.nextToken().trim();
                    if ( nextToken.startsWith( "\\" ) || nextToken.startsWith( "/" ) )
                    {
                        // we know we are on a DOS style platform and the next path
                        // starts with a slash or backslash, so we know this is a
                        // drive spec
                        token += ":" + nextToken;
                    }
                    else
                    {
                        // store the token just read for next time
                        lookahead = nextToken;
                    }
                }
            }
            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( ":" ) )
                {
                    // ignore ";" and get the next token
                    token = tokenizer.nextToken().trim();
                }

                if ( tokenizer.hasMoreTokens() )
                {
                    // this path could be a drive spec, so look at the next token
                    String nextToken = tokenizer.nextToken().trim();

                    // make sure we aren't going to get the path separator next
                    if ( !nextToken.equals( File.pathSeparator ) )
                    {
                        if ( nextToken.equals( ":" ) )
                        {
                            if ( !token.startsWith( "/" ) && !token.startsWith( "\\" ) && !token.startsWith( "." )
                                && !token.startsWith( ".." ) )
                            {
                                // it indeed is a drive spec, get the next bit
                                String oneMore = tokenizer.nextToken().trim();
                                if ( !oneMore.equals( File.pathSeparator ) )
                                {
                                    token += ":" + oneMore;
                                }
                                else
                                {
                                    token += ":";
                                    lookahead = oneMore;
                                }
                            }
                            // implicit else: ignore the ':' since we have either a
                            // UNIX or a relative path
                        }
                        else
                        {
                            // store the token just read for next time
                            lookahead = nextToken;
                        }
                    }
                }
            }
            return token;
        }
    }

    /**
     * Ignores line like 'Picked up JAVA_TOOL_OPTIONS: ...' as can happen on CI servers.
     *
     * @author Robert Scholte
     * @since 3.0.1
     */
    protected static class JavadocOutputStreamConsumer
        extends CommandLineUtils.StringStreamConsumer
    {
        @Override
        public void consumeLine( String line )
        {
            if ( !line.startsWith( "Picked up " ) )
            {
                super.consumeLine( line );
            }
        }
    }

    static List<String> toList( String src )
    {
        return toList( src, null, null );
    }

    static List<String> toList( String src, String elementPrefix, String elementSuffix )
    {
        if ( StringUtils.isEmpty( src ) )
        {
            return null;
        }

        List<String> result = new ArrayList<>();

        StringTokenizer st = new StringTokenizer( src, "[,:;]" );
        StringBuilder sb = new StringBuilder( 256 );
        while ( st.hasMoreTokens() )
        {
            sb.setLength( 0 );
            if ( StringUtils.isNotEmpty( elementPrefix ) )
            {
                sb.append( elementPrefix );
            }

            sb.append( st.nextToken() );

            if ( StringUtils.isNotEmpty( elementSuffix ) )
            {
                sb.append( elementSuffix );
            }

            result.add( sb.toString() );
        }

        return result;
    }

    static <T> List<T> toList( T[] multiple )
    {
        return toList( null, multiple );
    }

    static <T> List<T> toList( T single, T[] multiple )
    {
        if ( single == null && ( multiple == null || multiple.length < 1 ) )
        {
            return null;
        }

        List<T> result = new ArrayList<>();
        if ( single != null )
        {
            result.add( single );
        }

        if ( multiple != null && multiple.length > 0 )
        {
            result.addAll( Arrays.asList( multiple ) );
        }

        return result;
    }

    // TODO: move to plexus-utils or use something appropriate from there
    public static String toRelative( File basedir, String absolutePath )
    {
        String relative;

        absolutePath = absolutePath.replace( '\\', '/' );
        String basedirPath = basedir.getAbsolutePath().replace( '\\', '/' );

        if ( absolutePath.startsWith( basedirPath ) )
        {
            relative = absolutePath.substring( basedirPath.length() );
            if ( relative.startsWith( "/" ) )
            {
                relative = relative.substring( 1 );
            }
            if ( relative.length() <= 0 )
            {
                relative = ".";
            }
        }
        else
        {
            relative = absolutePath;
        }

        return relative;
    }

    /**
     * Convenience method to determine that a collection is not empty or null.
     * @param collection the collection to verify
     * @return {@code true} if not {@code null} and not empty, otherwise {@code false}
     */
    public static boolean isNotEmpty( final Collection<?> collection )
    {
        return collection != null && !collection.isEmpty();
    }

    /**
     * Convenience method to determine that a collection is empty or null.
     * @param collection the collection to verify
     * @return {@code true} if {@code null} or empty, otherwise {@code false}
     */
    public static boolean isEmpty( final Collection<?> collection )
    {
        return collection == null || collection.isEmpty();
    }

    /**
     * Execute an Http request at the given URL, follows redirects, and returns the last redirect locations. For URLs
     * that aren't http/https, this does nothing and simply returns the given URL unchanged.
     *
     * @param url URL.
     * @param settings Maven settings.
     * @return Last redirect location.
     * @throws IOException if there was an error during the Http request.
     */
    protected static URL getRedirectUrl( URL url, Settings settings )
        throws IOException
    {
        String protocol = url.getProtocol();
        if ( !"http".equals( protocol ) && !"https".equals( protocol ) )
        {
            return url;
        }
        HttpClient httpClient = null;
        try
        {
            httpClient = createHttpClient( settings, url );
            HttpClientContext httpContext = HttpClientContext.create();
            HttpGet httpMethod = new HttpGet( url.toString() );
            HttpResponse response = httpClient.execute( httpMethod, httpContext );
            int status = response.getStatusLine().getStatusCode();
            if ( status != HttpStatus.SC_OK )
            {
                throw new FileNotFoundException( "Unexpected HTTP status code " + status + " getting resource "
                    + url.toExternalForm() + "." );
            }

            List<URI> redirects = httpContext.getRedirectLocations();
            return isEmpty( redirects ) ? url : redirects.get( redirects.size() - 1 ).toURL();
        }
        finally
        {
            if ( httpClient != null )
            {
                httpClient.getConnectionManager().shutdown();
            }
        }
    }

    /**
     * Validates an <code>URL</code> to point to a valid <code>package-list</code> resource.
     *
     * @param url The URL to validate.
     * @param settings The user settings used to configure the connection to the URL or {@code null}.
     * @param validateContent <code>true</code> to validate the content of the <code>package-list</code> resource;
     *            <code>false</code> to only check the existence of the <code>package-list</code> resource.
     * @return <code>true</code> if <code>url</code> points to a valid <code>package-list</code> resource;
     *         <code>false</code> else.
     * @throws IOException if reading the resource fails.
     * @see #createHttpClient(org.apache.maven.settings.Settings, java.net.URL)
     * @since 2.8
     */
    protected static boolean isValidPackageList( URL url, Settings settings, boolean validateContent )
        throws IOException
    {
        if ( url == null )
        {
            throw new IllegalArgumentException( "The url is null" );
        }

        try ( BufferedReader reader = getReader( url, settings ) )
        {
            if ( validateContent )
            {
                for ( String line = reader.readLine(); line != null; line = reader.readLine() )
                {
                    if ( !isValidPackageName( line ) )
                    {
                        return false;
                    }
                }
            }
            return true;
        }
    }

    protected static boolean isValidElementList( URL url, Settings settings, boolean validateContent )
                    throws IOException
    {
        if ( url == null )
        {
            throw new IllegalArgumentException( "The url is null" );
        }

        try ( BufferedReader reader = getReader( url, settings ) )
        {
            if ( validateContent )
            {
                for ( String line = reader.readLine(); line != null; line = reader.readLine() )
                {
                    if ( line.startsWith( "module:" ) )
                    {
                        continue;
                    }

                    if ( !isValidPackageName( line ) )
                    {
                        return false;
                    }
                }
            }
            return true;
        }
    }

    private static BufferedReader getReader( URL url, Settings settings ) throws IOException
    {
        BufferedReader reader = null;

        if ( "file".equals( url.getProtocol() ) )
        {
            // Intentionally using the platform default encoding here since this is what Javadoc uses internally.
            reader = new BufferedReader( new InputStreamReader( url.openStream() ) );
        }
        else
        {
            // http, https...
            final HttpClient httpClient = createHttpClient( settings, url );

            final HttpGet httpMethod = new HttpGet( url.toString() );

            HttpResponse response;
            HttpClientContext httpContext = HttpClientContext.create();
            try
            {
                response = httpClient.execute( httpMethod, httpContext );
            }
            catch ( SocketTimeoutException e )
            {
                // could be a sporadic failure, one more retry before we give up
                response = httpClient.execute( httpMethod, httpContext );
            }

            int status = response.getStatusLine().getStatusCode();
            if ( status != HttpStatus.SC_OK )
            {
                throw new FileNotFoundException( "Unexpected HTTP status code " + status + " getting resource "
                    + url.toExternalForm() + "." );
            }
            else
            {
                int pos = url.getPath().lastIndexOf( '/' );
                List<URI> redirects = httpContext.getRedirectLocations();
                if ( pos >= 0 && isNotEmpty( redirects ) )
                {
                    URI location = redirects.get( redirects.size() - 1 );
                    String suffix = url.getPath().substring( pos );
                    // Redirections shall point to the same file, e.g. /package-list
                    if ( !location.getPath().endsWith( suffix ) )
                    {
                        throw new FileNotFoundException( url.toExternalForm() + " redirects to "
                                + location.toURL().toExternalForm() + "." );
                    }
                }
            }

            // Intentionally using the platform default encoding here since this is what Javadoc uses internally.
            reader = new BufferedReader( new InputStreamReader( response.getEntity().getContent() ) )
            {
                @Override
                public void close()
                    throws IOException
                {
                    super.close();

                    if ( httpMethod != null )
                    {
                        httpMethod.releaseConnection();
                    }
                    if ( httpClient != null )
                    {
                        httpClient.getConnectionManager().shutdown();
                    }
                }
            };
        }

        return reader;
    }

    private static boolean isValidPackageName( String str )
    {
        if ( StringUtils.isEmpty( str ) )
        {
            // unnamed package is valid (even if bad practice :) )
            return true;
        }

        int idx;
        while ( ( idx = str.indexOf( '.' ) ) != -1 )
        {
            if ( !isValidClassName( str.substring( 0, idx ) ) )
            {
                return false;
            }

            str = str.substring( idx + 1 );
        }

        return isValidClassName( str );
    }

    private static boolean isValidClassName( String str )
    {
        if ( StringUtils.isEmpty( str ) || !Character.isJavaIdentifierStart( str.charAt( 0 ) ) )
        {
            return false;
        }

        for ( int i = str.length() - 1; i > 0; i-- )
        {
            if ( !Character.isJavaIdentifierPart( str.charAt( i ) ) )
            {
                return false;
            }
        }

        return true;
    }

    /**
     * Creates a new {@code HttpClient} instance.
     *
     * @param settings The settings to use for setting up the client or {@code null}.
     * @param url The {@code URL} to use for setting up the client or {@code null}.
     * @return A new {@code HttpClient} instance.
     * @see #DEFAULT_TIMEOUT
     * @since 2.8
     */
    private static HttpClient createHttpClient( Settings settings, URL url )
    {
        DefaultHttpClient httpClient = new DefaultHttpClient( new PoolingClientConnectionManager() );
        httpClient.getParams().setIntParameter( CoreConnectionPNames.SO_TIMEOUT, DEFAULT_TIMEOUT );
        httpClient.getParams().setIntParameter( CoreConnectionPNames.CONNECTION_TIMEOUT, DEFAULT_TIMEOUT );
        httpClient.getParams().setBooleanParameter( ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true );

        // Some web servers don't allow the default user-agent sent by httpClient
        httpClient.getParams().setParameter( CoreProtocolPNames.USER_AGENT,
                                             "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" );

        // Some server reject requests that do not have an Accept header
        httpClient.getParams().setParameter( ClientPNames.DEFAULT_HEADERS,
                                             Arrays.asList( new BasicHeader( HttpHeaders.ACCEPT, "*/*" ) ) );

        httpClient.getParams().setParameter( ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY );

        if ( settings != null && settings.getActiveProxy() != null )
        {
            Proxy activeProxy = settings.getActiveProxy();

            ProxyInfo proxyInfo = new ProxyInfo();
            proxyInfo.setNonProxyHosts( activeProxy.getNonProxyHosts() );

            if ( StringUtils.isNotEmpty( activeProxy.getHost() )
                && ( url == null || !ProxyUtils.validateNonProxyHosts( proxyInfo, url.getHost() ) ) )
            {
                HttpHost proxy = new HttpHost( activeProxy.getHost(), activeProxy.getPort() );
                httpClient.getParams().setParameter( ConnRoutePNames.DEFAULT_PROXY, proxy );

                if ( StringUtils.isNotEmpty( activeProxy.getUsername() ) && activeProxy.getPassword() != null )
                {
                    Credentials credentials =
                        new UsernamePasswordCredentials( activeProxy.getUsername(), activeProxy.getPassword() );

                    httpClient.getCredentialsProvider().setCredentials( AuthScope.ANY, credentials );
                }
            }
        }

        return httpClient;
    }

    static boolean equalsIgnoreCase( String value, String... strings )
    {
        for ( String s : strings )
        {
            if ( s.equalsIgnoreCase( value ) )
            {
                return true;
            }
        }
        return false;
    }

    static boolean equals( String value, String... strings )
    {
        for ( String s : strings )
        {
            if ( s.equals( value ) )
            {
                return true;
            }
        }
        return false;
    }
}
