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 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.URISyntaxException;
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.Paths;
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;

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.CredentialsProvider;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
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;

/**
 * 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 )
        {
            if ( Files.isRegularFile( Paths.get( f ) ) && !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;
        }
    }

    /**
     * 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>.
     * @param globalSettingsFile reference to settings file, could be null.
     * @throws MavenInvocationException if any
     * @since 2.6
     */
    protected static void invokeMaven( Log log, File localRepositoryDir, File projectFile, List<String> goals,
                                       Properties properties, File invokerLog, File globalSettingsFile )
        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.setGlobalSettingsFile( globalSettingsFile );
        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 );

        try
        {
            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( "" );
        }
        catch ( IOException ioe )
        {
            throw new MavenInvocationException( "IOException while consuming invocation output", ioe );
        }

        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;
        }

        try ( CloseableHttpClient 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();

            if ( isEmpty( redirects ) )
            {
                return url;
            }
            else
            {
                URI last = redirects.get( redirects.size() - 1 );

                // URI must refer to directory, so prevent redirects to index.html
                // see https://issues.apache.org/jira/browse/MJAVADOC-539
                String truncate = "index.html";
                if ( last.getPath().endsWith( "/" + truncate ) )
                {
                    try
                    {
                        String fixedPath = last.getPath().substring( 0, last.getPath().length() - truncate.length() );
                        last = new URI( last.getScheme(), last.getAuthority(), fixedPath, last.getQuery(),
                                last.getFragment() );
                    }
                    catch ( URISyntaxException ex )
                    {
                        // not supposed to happen, but when it does just keep the last URI
                    }
                }
                return last.toURL();
            }
        }
    }

    /**
     * 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 CloseableHttpClient 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.close();
                    }
                }
            };
        }

        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 CloseableHttpClient createHttpClient( Settings settings, URL url )
    {
        HttpClientBuilder builder = HttpClients.custom();
        
        Registry<ConnectionSocketFactory> csfRegistry =
            RegistryBuilder.<ConnectionSocketFactory>create()
                .register( "http", PlainConnectionSocketFactory.getSocketFactory() )
                .register( "https", SSLConnectionSocketFactory.getSystemSocketFactory() )
                .build();
        
        builder.setConnectionManager( new PoolingHttpClientConnectionManager( csfRegistry ) );
        builder.setDefaultRequestConfig( RequestConfig.custom()
                                         .setSocketTimeout( DEFAULT_TIMEOUT )
                                         .setConnectTimeout( DEFAULT_TIMEOUT )
                                         .setCircularRedirectsAllowed( true )
                                         .setCookieSpec( CookieSpecs.IGNORE_COOKIES )
                                         .build() );
        
        // Some web servers don't allow the default user-agent sent by httpClient
        builder.setUserAgent( "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" );

        // Some server reject requests that do not have an Accept header
        builder.setDefaultHeaders( Arrays.asList( new BasicHeader( HttpHeaders.ACCEPT, "*/*" ) ) );

        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() );
                builder.setProxy( proxy );

                if ( StringUtils.isNotEmpty( activeProxy.getUsername() ) && activeProxy.getPassword() != null )
                {
                    Credentials credentials =
                        new UsernamePasswordCredentials( activeProxy.getUsername(), activeProxy.getPassword() );

                    CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
                    credentialsProvider.setCredentials( AuthScope.ANY, credentials );
                    builder.setDefaultCredentialsProvider( credentialsProvider );
                }
            }
        }
        return builder.build();
    }

    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;
    }
}
