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.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.archiver.MavenArchiver;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.javadoc.options.BootclasspathArtifact;
import org.apache.maven.plugins.javadoc.options.DocletArtifact;
import org.apache.maven.plugins.javadoc.options.Group;
import org.apache.maven.plugins.javadoc.options.JavadocOptions;
import org.apache.maven.plugins.javadoc.options.JavadocPathArtifact;
import org.apache.maven.plugins.javadoc.options.OfflineLink;
import org.apache.maven.plugins.javadoc.options.ResourcesArtifact;
import org.apache.maven.plugins.javadoc.options.Tag;
import org.apache.maven.plugins.javadoc.options.Taglet;
import org.apache.maven.plugins.javadoc.options.TagletArtifact;
import org.apache.maven.plugins.javadoc.options.io.xpp3.JavadocOptionsXpp3Writer;
import org.apache.maven.plugins.javadoc.resolver.JavadocBundle;
import org.apache.maven.plugins.javadoc.resolver.ResourceResolver;
import org.apache.maven.plugins.javadoc.resolver.SourceResolverConfig;
import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Settings;
import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate;
import org.apache.maven.shared.artifact.filter.resolve.AndFilter;
import org.apache.maven.shared.artifact.filter.resolve.PatternExclusionsFilter;
import org.apache.maven.shared.artifact.filter.resolve.PatternInclusionsFilter;
import org.apache.maven.shared.artifact.filter.resolve.ScopeFilter;
import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter;
import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver;
import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
import org.apache.maven.shared.transfer.dependencies.DefaultDependableCoordinate;
import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
import org.apache.maven.shared.invoker.MavenInvocationException;
import org.apache.maven.toolchain.Toolchain;
import org.apache.maven.toolchain.ToolchainManager;
import org.apache.maven.wagon.PathUtils;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
import org.codehaus.plexus.components.io.fileselectors.IncludeExcludeFileSelector;
import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor;
import org.codehaus.plexus.languages.java.jpms.LocationManager;
import org.codehaus.plexus.languages.java.jpms.ModuleNameSource;
import org.codehaus.plexus.languages.java.jpms.ResolvePathRequest;
import org.codehaus.plexus.languages.java.jpms.ResolvePathResult;
import org.codehaus.plexus.languages.java.jpms.ResolvePathsRequest;
import org.codehaus.plexus.languages.java.jpms.ResolvePathsResult;
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.ReaderFactory;
import org.codehaus.plexus.util.WriterFactory;
import org.codehaus.plexus.util.cli.CommandLineException;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import org.codehaus.plexus.util.cli.Commandline;
import org.codehaus.plexus.util.xml.Xpp3Dom;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
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.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.stream.Collectors;

import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtLeast;
import static org.apache.maven.plugins.javadoc.JavadocUtil.toRelative;
import static org.apache.maven.plugins.javadoc.JavadocUtil.toList;
import static org.apache.maven.plugins.javadoc.JavadocUtil.isEmpty;
import static org.apache.maven.plugins.javadoc.JavadocUtil.isNotEmpty;

/**
 * Base class with majority of Javadoc functionalities.
 *
 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
 * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html">
 *      The Java API Documentation Generator, 7</a>
 * @since 2.0
 */
public abstract class AbstractJavadocMojo
    extends AbstractMojo
{
    /**
     * Classifier used in the name of the javadoc-options XML file, and in the resources bundle
     * artifact that gets attached to the project. This one is used for non-test javadocs.
     *
     * @see #TEST_JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER
     * @since 2.7
     */
    public static final String JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER = "javadoc-resources";

    /**
     * Classifier used in the name of the javadoc-options XML file, and in the resources bundle
     * artifact that gets attached to the project. This one is used for test-javadocs.
     *
     * @see #JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER
     * @since 2.7
     */
    public static final String TEST_JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER = "test-javadoc-resources";

    /**
     * The Javadoc script file name when <code>debug</code> parameter is on, i.e. javadoc.bat or javadoc.sh
     */
    protected static final String DEBUG_JAVADOC_SCRIPT_NAME = "javadoc." + ( SystemUtils.IS_OS_WINDOWS ? "bat" : "sh" );

    /**
     * The <code>options</code> file name in the output directory when calling:
     * <code>javadoc.exe(or .sh) &#x40;options &#x40;packages | &#x40;argfile | &#x40;files</code>
     */
    protected static final String OPTIONS_FILE_NAME = "options";

    /**
     * The <code>packages</code> file name in the output directory when calling:
     * <code>javadoc.exe(or .sh) &#x40;options &#x40;packages | &#x40;argfile | &#x40;files</code>
     */
    protected static final String PACKAGES_FILE_NAME = "packages";

    /**
     * The <code>argfile</code> file name in the output directory when calling:
     * <code>javadoc.exe(or .sh) &#x40;options &#x40;packages | &#x40;argfile | &#x40;files</code>
     */
    protected static final String ARGFILE_FILE_NAME = "argfile";

    /**
     * The <code>files</code> file name in the output directory when calling:
     * <code>javadoc.exe(or .sh) &#x40;options &#x40;packages | &#x40;argfile | &#x40;files</code>
     */
    protected static final String FILES_FILE_NAME = "files";

    /**
     * The current class directory
     */
    private static final String RESOURCE_DIR = ClassUtils.getPackageName( JavadocReport.class ).replace( '.', '/' );

    /**
     * Default css file name
     */
    private static final String DEFAULT_CSS_NAME = "stylesheet.css";

    /**
     * Default location for css
     */
    private static final String RESOURCE_CSS_DIR = RESOURCE_DIR + "/css";

    private static final String PACKAGE_LIST = "package-list";
    private static final String ELEMENT_LIST = "element-list";


    /**
     * For Javadoc options appears since Java 1.4.
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.1.html#summary">
     * What's New in Javadoc 1.4</a>
     *
     * @since 2.1
     */
    private static final JavaVersion SINCE_JAVADOC_1_4 = JavaVersion.parse( "1.4" );

    /**
     * For Javadoc options appears since Java 1.4.2.
     * See <a
     * href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.2.html#commandlineoptions">
     * What's New in Javadoc 1.4.2</a>
     *
     * @since 2.1
     */
    private static final JavaVersion SINCE_JAVADOC_1_4_2 = JavaVersion.parse( "1.4.2" );

    /**
     * For Javadoc options appears since Java 5.0.
     * See <a
     * href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.5.0.html#commandlineoptions">
     * What's New in Javadoc 5.0</a>
     *
     * @since 2.1
     */
    private static final JavaVersion SINCE_JAVADOC_1_5 = JavaVersion.parse( "1.5" );

    /**
     * For Javadoc options appears since Java 6.0.
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/index.html">
     * Javadoc Technology</a>
     *
     * @since 2.4
     */
    private static final JavaVersion SINCE_JAVADOC_1_6 = JavaVersion.parse( "1.6" );

    /**
     * For Javadoc options appears since Java 8.0.
     * See <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/javadoc/index.html">
     * Javadoc Technology</a>
     *
     * @since 3.0.0
     */
    private static final JavaVersion SINCE_JAVADOC_1_8 = JavaVersion.parse( "1.8" );

    /**
     *
     */
    private static final JavaVersion JAVA_VERSION = JavaVersion.JAVA_SPECIFICATION_VERSION;

    // ----------------------------------------------------------------------
    // Mojo components
    // ----------------------------------------------------------------------

    /**
     * Archiver manager
     *
     * @since 2.5
     */
    @Component
    private ArchiverManager archiverManager;

    @Component
    private ResourceResolver resourceResolver;

    @Component
    private ArtifactResolver artifactResolver;

    @Component
    private ArtifactHandlerManager artifactHandlerManager;

    @Component
    private DependencyResolver dependencyResolver;

    /**
     * Project builder
     *
     * @since 3.0
     */
    @Component
    private ProjectBuilder mavenProjectBuilder;

    /** */
    @Component
    private ToolchainManager toolchainManager;

    final LocationManager locationManager = new LocationManager();

    // ----------------------------------------------------------------------
    // Mojo parameters
    // ----------------------------------------------------------------------

    /**
     * The current build session instance. This is used for
     * toolchain manager API calls.
     */
    @Parameter( defaultValue = "${session}", readonly = true, required = true )
    protected MavenSession session;

    /**
     * The Maven Settings.
     *
     * @since 2.3
     */
    @Parameter( defaultValue = "${settings}", readonly = true, required = true )
    private Settings settings;

    /**
     * The Maven Project Object
     */
    @Parameter( defaultValue = "${project}", readonly = true, required = true )
    protected MavenProject project;

    @Parameter( defaultValue = "${mojoExecution}", readonly = true )
    private MojoExecution mojo;

    /**
     * Specify if the Javadoc should operate in offline mode.
     */
    @Parameter( defaultValue = "${settings.offline}", required = true, readonly = true )
    private boolean isOffline;

    /**
     * Specifies the Javadoc resources directory to be included in the Javadoc (i.e. package.html, images...).
     * <br/>
     * Could be used in addition of <code>docfilessubdirs</code> parameter.
     * <br/>
     * See <a href="#docfilessubdirs">docfilessubdirs</a>.
     *
     * @see #docfilessubdirs
     * @since 2.1
     */
    @Parameter( defaultValue = "${basedir}/src/main/javadoc" )
    private File javadocDirectory;

    /**
     * Set an additional option(s) on the command line. All input will be passed as-is to the
     * {@code @options} file. You must take care of quoting and escaping. Useful for a custom doclet.
     *
     * @since 3.0.0
     */
    @Parameter
    private String[] additionalOptions;

    /**
     * Set an additional Javadoc option(s) (i.e. JVM options) on the command line.
     * Example:
     * <pre>
     * &lt;additionalJOption&gt;-J-Xss128m&lt;/additionalJOption&gt;
     * </pre>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#J">Jflag</a>.
     * <br/>
     * See <a href="http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp">vmoptions</a>.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/net/properties.html">Networking
     * Properties</a>.
     *
     * @since 2.3
     */
    @Parameter( property = "additionalJOption" )
    private String additionalJOption;

    /**
     * Set additional JVM options for the execution of the javadoc command via the '-J' option to javadoc.
     * Example:
     * <pre>
     *     &lt;additionalJOptions&gt;
     *         &lt;additionalJOption&gt;-J-Xmx1g &lt;/additionalJOption&gt;
     *     &lt;/additionalJOptions&gt;
     * </pre>
     * @since 2.9
     */
    @Parameter
    private String[] additionalJOptions;

    /**
     * A list of artifacts containing resources which should be copied into the
     * Javadoc output directory (like stylesheets, icons, etc.).
     * <br/>
     * Example:
     * <pre>
     * &lt;resourcesArtifacts&gt;
     *   &lt;resourcesArtifact&gt;
     *     &lt;groupId&gt;external.group.id&lt;/groupId&gt;
     *     &lt;artifactId&gt;external-resources&lt;/artifactId&gt;
     *     &lt;version&gt;1.0&lt;/version&gt;
     *   &lt;/resourcesArtifact&gt;
     * &lt;/resourcesArtifacts&gt;
     * </pre>
     * <br/>
     * See <a href="./apidocs/org/apache/maven/plugins/javadoc/options/ResourcesArtifact.html">Javadoc</a>.
     * <br/>
     *
     * @since 2.5
     */
    @Parameter( property = "resourcesArtifacts" )
    private ResourcesArtifact[] resourcesArtifacts;

    /**
     * The local repository where the artifacts are located.
     */
    @Parameter( property = "localRepository" )
    private ArtifactRepository localRepository;

    /**
     * The projects in the reactor for aggregation report.
     */
    @Parameter( property = "reactorProjects", readonly = true )
    private List<MavenProject> reactorProjects;

    /**
     * Set this to <code>true</code> to debug the Javadoc plugin. With this, <code>javadoc.bat(or.sh)</code>,
     * <code>options</code>, <code>@packages</code> or <code>argfile</code> files are provided in the output directory.
     * <br/>
     *
     * @since 2.1
     */
    @Parameter( property = "debug", defaultValue = "false" )
    private boolean debug;

    /**
     * Sets the absolute path of the Javadoc Tool executable to use. Since version 2.5, a mere directory specification
     * is sufficient to have the plugin use "javadoc" or "javadoc.exe" respectively from this directory.
     *
     * @since 2.3
     */
    @Parameter( property = "javadocExecutable" )
    private String javadocExecutable;

    /**
     * Version of the Javadoc Tool executable to use, ex. "1.3", "1.5".
     *
     * @since 2.3
     */
    @Parameter( property = "javadocVersion" )
    private String javadocVersion;

    /**
     * Version of the Javadoc Tool executable to use.
     */
    private JavaVersion javadocRuntimeVersion;

    /**
     * Specifies whether the Javadoc generation should be skipped.
     *
     * @since 2.5
     */
    @Parameter( property = "maven.javadoc.skip", defaultValue = "false" )
    protected boolean skip;

    /**
     * Specifies if the build will fail if there are errors during javadoc execution or not.
     *
     * @since 2.5
     */
    @Parameter( property = "maven.javadoc.failOnError", defaultValue = "true" )
    protected boolean failOnError;


    /**
     * Specifies if the build will fail if there are warning during javadoc execution or not.
     *
     * @since 3.0.1
     */
    @Parameter( property = "maven.javadoc.failOnWarnings", defaultValue = "false" )
    protected boolean failOnWarnings;

    /**
     * Specifies to use the
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#standard">
     * options provided by the Standard Doclet</a> for a custom doclet.
     * <br>
     * Example:
     * <pre>
     * &lt;docletArtifacts&gt;
     *   &lt;docletArtifact&gt;
     *     &lt;groupId&gt;com.sun.tools.doclets&lt;/groupId&gt;
     *     &lt;artifactId&gt;doccheck&lt;/artifactId&gt;
     *     &lt;version&gt;1.2b2&lt;/version&gt;
     *   &lt;/docletArtifact&gt;
     * &lt;/docletArtifacts&gt;
     * &lt;useStandardDocletOptions&gt;true&lt;/useStandardDocletOptions&gt;
     * </pre>
     *
     * @since 2.5
     */
    @Parameter( property = "useStandardDocletOptions", defaultValue = "true" )
    protected boolean useStandardDocletOptions;

    /**
     * Detect the Javadoc links for all dependencies defined in the project. The detection is based on the default
     * Maven conventions, i.e.: <code>${project.url}/apidocs</code>.
     * <br/>
     * For instance, if the project has a dependency to
     * <a href="http://commons.apache.org/lang/">Apache Commons Lang</a> i.e.:
     * <pre>
     * &lt;dependency&gt;
     *   &lt;groupId&gt;commons-lang&lt;/groupId&gt;
     *   &lt;artifactId&gt;commons-lang&lt;/artifactId&gt;
     * &lt;/dependency&gt;
     * </pre>
     * The added Javadoc <code>-link</code> parameter will be <code>http://commons.apache.org/lang/apidocs</code>.
     *
     * @see #links
     * @see #dependencyLinks
     * @since 2.6
     */
    @Parameter( property = "detectLinks", defaultValue = "false" )
    private boolean detectLinks;

    /**
     * Detect the links for all modules defined in the project.
     * <br/>
     * If {@link #reactorProjects} is defined in a non-aggregator way, it generates default offline links
     * between modules based on the defined project's urls. For instance, if a parent project has two projects
     * <code>module1</code> and <code>module2</code>, the <code>-linkoffline</code> will be:
     * <br/>
     * The added Javadoc <code>-linkoffline</code> parameter for <b>module1</b> will be
     * <code>/absolute/path/to/</code><b>module2</b><code>/target/site/apidocs</code>
     * <br/>
     * The added Javadoc <code>-linkoffline</code> parameter for <b>module2</b> will be
     * <code>/absolute/path/to/</code><b>module1</b><code>/target/site/apidocs</code>
     *
     * @see #offlineLinks
     * @since 2.6
     */
    @Parameter( property = "detectOfflineLinks", defaultValue = "true" )
    private boolean detectOfflineLinks;

    /**
     * Detect the Java API link for the current build, i.e. <code>https://docs.oracle.com/javase/1.4.2/docs/api/</code>
     * for Java source 1.4.
     * <br/>
     * By default, the goal detects the Javadoc API link depending the value of the <code>source</code>
     * parameter in the <code>org.apache.maven.plugins:maven-compiler-plugin</code>
     * (defined in <code>${project.build.plugins}</code> or in <code>${project.build.pluginManagement}</code>),
     * or try to compute it from the {@link #javadocExecutable} version.
     * <br/>
     * See
     * <a href="./apidocs/org/apache/maven/plugins/javadoc/AbstractJavadocMojo.html#DEFAULT_JAVA_API_LINKS">Javadoc</a>
     * for the default values.
     * <br/>
     *
     * @see #links
     * @see #javaApiLinks
     * @since 2.6
     */
    @Parameter( property = "detectJavaApiLink", defaultValue = "true" )
    private boolean detectJavaApiLink;

    /**
     * Use this parameter <b>only</b> if if you want to override the default URLs.
     *
     * The key should match {@code api_x}, where {@code x} matches the Java version.
     *
     *  For example:
     *  <dl>
     *   <dt>api_1.5</dt>
     *   <dd>https://docs.oracle.com/javase/1.5.0/docs/api/</dd>
     *   <dt>api_1.8<dt>
     *   <dd>https://docs.oracle.com/javase/8/docs/api/</dd>
     *   <dt>api_9</dd>
     *   <dd>https://docs.oracle.com/javase/9/docs/api/</dd>
     * </dl>
     * @since 2.6
     */
    @Parameter( property = "javaApiLinks" )
    private Properties javaApiLinks;

    /**
     * Flag controlling content validation of <code>package-list</code> resources. If set, the content of
     * <code>package-list</code> resources will be validated.
     *
     * @since 2.8
     */
    @Parameter( property = "validateLinks", defaultValue = "false" )
    private boolean validateLinks;

    // ----------------------------------------------------------------------
    // Javadoc Options - all alphabetical
    // ----------------------------------------------------------------------

    /**
     * Specifies the paths where the boot classes reside. The <code>bootclasspath</code> can contain multiple paths
     * by separating them with a colon (<code>:</code>) or a semi-colon (<code>;</code>).
     * <br/>
     * See <a href=
     *    "https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#bootclasspath">bootclasspath</a>.
     *
     * @since 2.5
     */
    @Parameter( property = "bootclasspath" )
    private String bootclasspath;

    /**
     * Specifies the artifacts where the boot classes reside.
     * <br/>
     * See <a href=
     *   "https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#bootclasspath">bootclasspath</a>.
     * <br/>
     * Example:
     * <pre>
     * &lt;bootclasspathArtifacts&gt;
     *   &lt;bootclasspathArtifact&gt;
     *     &lt;groupId&gt;my-groupId&lt;/groupId&gt;
     *     &lt;artifactId&gt;my-artifactId&lt;/artifactId&gt;
     *     &lt;version&gt;my-version&lt;/version&gt;
     *   &lt;/bootclasspathArtifact&gt;
     * &lt;/bootclasspathArtifacts&gt;
     * </pre>
     * <br/>
     * See <a href="./apidocs/org/apache/maven/plugins/javadoc/options/BootclasspathArtifact.html">Javadoc</a>.
     * <br/>
     *
     * @since 2.5
     */
    @Parameter( property = "bootclasspathArtifacts" )
    private BootclasspathArtifact[] bootclasspathArtifacts;

    /**
     * Uses the sentence break iterator to determine the end of the first sentence.
     * <br/>
     * See <a href=
     * "https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#breakiterator">breakiterator</a>.
     * <br/>
     * Since <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#summary">Java
     * 1.4</a>.
     * <br/>
     */
    @Parameter( property = "breakiterator", defaultValue = "false" )
    private boolean breakiterator;

    /**
     * Specifies the class file that starts the doclet used in generating the documentation.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#doclet">doclet</a>.
     */
    @Parameter( property = "doclet" )
    private String doclet;

    /**
     * Specifies the artifact containing the doclet starting class file (specified with the <code>-doclet</code>
     * option).
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#docletpath">docletpath</a>.
     * <br/>
     * Example:
     * <pre>
     * &lt;docletArtifact&gt;
     *   &lt;groupId&gt;com.sun.tools.doclets&lt;/groupId&gt;
     *   &lt;artifactId&gt;doccheck&lt;/artifactId&gt;
     *   &lt;version&gt;1.2b2&lt;/version&gt;
     * &lt;/docletArtifact&gt;
     * </pre>
     * <br/>
     * See <a href="./apidocs/org/apache/maven/plugins/javadoc/options/DocletArtifact.html">Javadoc</a>.
     * <br/>
     */
    @Parameter( property = "docletArtifact" )
    private DocletArtifact docletArtifact;

    /**
     * Specifies multiple artifacts containing the path for the doclet starting class file (specified with the
     * <code>-doclet</code> option).
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#docletpath">docletpath</a>.
     * <br/>
     * Example:
     * <pre>
     * &lt;docletArtifacts&gt;
     *   &lt;docletArtifact&gt;
     *     &lt;groupId&gt;com.sun.tools.doclets&lt;/groupId&gt;
     *     &lt;artifactId&gt;doccheck&lt;/artifactId&gt;
     *     &lt;version&gt;1.2b2&lt;/version&gt;
     *   &lt;/docletArtifact&gt;
     * &lt;/docletArtifacts&gt;
     * </pre>
     * <br/>
     * See <a href="./apidocs/org/apache/maven/plugins/javadoc/options/DocletArtifact.html">Javadoc</a>.
     * <br/>
     *
     * @since 2.1
     */
    @Parameter( property = "docletArtifacts" )
    private DocletArtifact[] docletArtifacts;

    /**
     * Specifies the path to the doclet starting class file (specified with the <code>-doclet</code> option) and
     * any jar files it depends on. The <code>docletPath</code> can contain multiple paths by separating them with
     * a colon (<code>:</code>) or a semi-colon (<code>;</code>).
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#docletpath">docletpath</a>.
     */
    @Parameter( property = "docletPath" )
    private String docletPath;

    /**
     * Specifies the encoding name of the source files. If not specificed, the encoding value will be the value of the
     * <code>file.encoding</code> system property.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#encoding">encoding</a>.
     * <br/>
     * <b>Note</b>: In 2.4, the default value was locked to <code>ISO-8859-1</code> to ensure reproducing build, but
     * this was reverted in 2.5.
     * <br/>
     */
    @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
    private String encoding;

    /**
     * Unconditionally excludes the specified packages and their subpackages from the list formed by
     * <code>-subpackages</code>. Multiple packages can be separated by commas (<code>,</code>), colons (<code>:</code>)
     * or semicolons (<code>;</code>).
     * <p>
     * Wildcards work as followed:
     * <ul>
     *   <li>a wildcard at the beginning should match 1 or more folders</li>
     *   <li>any other wildcard must match exactly one folder</li>
     * </ul>
     * </p>
     * <p>
     * Example:
     * <pre>
     * &lt;excludePackageNames&gt;*.internal:org.acme.exclude1.*:org.acme.exclude2&lt;/excludePackageNames&gt;
     * </pre>
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#exclude">exclude</a>.
     * <br/>
     * Since <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#summary">Java
     * 1.4</a>.
     * </p>
     */
    @Parameter( property = "excludePackageNames" )
    private String excludePackageNames;

    /**
     * Specifies the directories where extension classes reside. Separate directories in <code>extdirs</code> with a
     * colon (<code>:</code>) or a semi-colon (<code>;</code>).
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#extdirs">extdirs</a>.
     */
    @Parameter( property = "extdirs" )
    private String extdirs;

    /**
     * Specifies the locale that javadoc uses when generating documentation.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#locale">locale</a>.
     */
    @Parameter( property = "locale" )
    private String locale;

    /**
     * Specifies the maximum Java heap size to be used when launching the Javadoc tool.
     * JVMs refer to this property as the <code>-Xmx</code> parameter. Example: '512' or '512m'.
     * The memory unit depends on the JVM used. The units supported could be: <code>k</code>, <code>kb</code>,
     * <code>m</code>, <code>mb</code>, <code>g</code>, <code>gb</code>, <code>t</code>, <code>tb</code>.
     * If no unit specified, the default unit is <code>m</code>.
     */
    @Parameter( property = "maxmemory" )
    private String maxmemory;

    /**
     * Specifies the minimum Java heap size to be used when launching the Javadoc tool.
     * JVMs refer to this property as the <code>-Xms</code> parameter. Example: '512' or '512m'.
     * The memory unit depends on the JVM used. The units supported could be: <code>k</code>, <code>kb</code>,
     * <code>m</code>, <code>mb</code>, <code>g</code>, <code>gb</code>, <code>t</code>, <code>tb</code>.
     * If no unit specified, the default unit is <code>m</code>.
     */
    @Parameter( property = "minmemory" )
    private String minmemory;

    /**
     * This option creates documentation with the appearance and functionality of documentation generated by
     * Javadoc 1.1.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#1.1">1.1</a>.
     * <br/>
     */
    @Parameter( property = "old", defaultValue = "false" )
    private boolean old;

    /**
     * Specifies that javadoc should retrieve the text for the overview documentation from the "source" file
     * specified by path/filename and place it on the Overview page (overview-summary.html).
     * <br/>
     * <b>Note</b>: could be in conflict with &lt;nooverview/&gt;.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#overview">overview</a>.
     * <br/>
     */
    @Parameter( property = "overview", defaultValue = "${basedir}/src/main/javadoc/overview.html" )
    private File overview;

    /**
     * Shuts off non-error and non-warning messages, leaving only the warnings and errors appear, making them
     * easier to view.
     * <br/>
     * Note: was a standard doclet in Java 1.4.2 (refer to bug ID
     * <a href="https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4714350">4714350</a>).
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#quiet">quiet</a>.
     * <br/>
     * Since Java 5.0.
     * <br/>
     */
    @Parameter( property = "quiet", defaultValue = "false" )
    private boolean quiet;

    /**
     * Specifies the access level for classes and members to show in the Javadocs.
     * Possible values are:
     * <ul>
     * <li><a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#public">public</a>
     * (shows only public classes and members)</li>
     * <li><a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#protected">protected</a>
     * (shows only public and protected classes and members)</li>
     * <li><a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#package">package</a>
     * (shows all classes and members not marked private)</li>
     * <li><a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#private">private</a>
     * (shows all classes and members)</li>
     * </ul>
     * <br/>
     */
    @Parameter( property = "show", defaultValue = "protected" )
    private String show;

    /**
     * Necessary to enable javadoc to handle assertions introduced in J2SE v 1.4 source code or generics introduced in
     * J2SE v5.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#source">source</a>.
     * <br/>
     * Since <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#summary">Java
     * 1.4</a>.
     */
    @Parameter( property = "source", defaultValue = "${maven.compiler.source}" )
    private String source;

    /**
     * Provide source compatibility with specified release
     *
     * @since JDK 9
     * @since 3.1.0
     */
    @Parameter( defaultValue = "${maven.compiler.release}" )
    private String release;

    /**
     * Specifies the source paths where the subpackages are located. The <code>sourcepath</code> can contain
     * multiple paths by separating them with a colon (<code>:</code>) or a semi-colon (<code>;</code>).
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#sourcepath">sourcepath</a>.
     */
    @Parameter( property = "sourcepath" )
    private String sourcepath;

    /**
     * Specifies the package directory where javadoc will be executed. Multiple packages can be separated by
     * colons (<code>:</code>).
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#subpackages">subpackages</a>.
     * <br/>
     * Since <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#summary">Java
     * 1.4</a>.
     */
    @Parameter( property = "subpackages" )
    private String subpackages;

    /**
     * Provides more detailed messages while javadoc is running.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#verbose">verbose</a>.
     * <br/>
     */
    @Parameter( property = "verbose", defaultValue = "false" )
    private boolean verbose;

    // ----------------------------------------------------------------------
    // Standard Doclet Options - all alphabetical
    // ----------------------------------------------------------------------

    /**
     * Specifies whether or not the author text is included in the generated Javadocs.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#author">author</a>.
     * <br/>
     */
    @Parameter( property = "author", defaultValue = "true" )
    private boolean author;

    /**
     * Specifies the text to be placed at the bottom of each output file.<br/>
     * If you want to use html, you have to put it in a CDATA section, <br/>
     * e.g. <code>&lt;![CDATA[Copyright 2005, &lt;a href="http://www.mycompany.com">MyCompany, Inc.&lt;a>]]&gt;</code>
     * <br>
     * <strong>Note:<strong>If the project has the property <code>project.build.outputTimestamp</code>, its year will
     * be used as {currentYear}. This way it is possible to generate reproducible javadoc jars.
     * <br>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#bottom">bottom</a>.
     * <br>
     */
    @Parameter( property = "bottom",
                    defaultValue = "Copyright &#169; {inceptionYear}&#x2013;{currentYear} {organizationName}. "
                        + "All rights reserved." )
    private String bottom;

    /**
     * Specifies the HTML character set for this document. If not specificed, the charset value will be the value of
     * the <code>docencoding</code> parameter.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#charset">charset</a>.
     * <br/>
     */
    @Parameter( property = "charset" )
    private String charset;

    /**
     * Specifies the encoding of the generated HTML files. If not specificed, the docencoding value will be
     * <code>UTF-8</code>.
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#docencoding">docencoding</a>.
     */
    @Parameter( property = "docencoding", defaultValue = "${project.reporting.outputEncoding}" )
    private String docencoding;

    /**
     * Enables deep copying of the <code>&#42;&#42;/doc-files</code> directories and the specifc <code>resources</code>
     * directory from the <code>javadocDirectory</code> directory (for instance,
     * <code>src/main/javadoc/com/mycompany/myapp/doc-files</code> and <code>src/main/javadoc/resources</code>).
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#docfilessubdirs">
     * docfilessubdirs</a>.
     * <br/>
     * Since <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#summary">Java
     * 1.4</a>.
     * <br/>
     * See <a href="#javadocDirectory">javadocDirectory</a>.
     * <br/>
     *
     * @see #excludedocfilessubdir
     * @see #javadocDirectory
     */
    @Parameter( property = "docfilessubdirs", defaultValue = "false" )
    private boolean docfilessubdirs;

    /**
     * Specifies specific checks to be performed on Javadoc comments.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#BEJEFABE">doclint</a>.
     *
     * @since 3.0.0
     */
    @Parameter( property = "doclint" )
    private String doclint;

    /**
     * Specifies the title to be placed near the top of the overview summary file.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#doctitle">doctitle</a>.
     * <br/>
     */
    @Parameter( property = "doctitle", defaultValue = "${project.name} ${project.version} API" )
    private String doctitle;

    /**
     * Excludes any "doc-files" subdirectories with the given names. Multiple patterns can be excluded
     * by separating them with colons (<code>:</code>).
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#excludedocfilessubdir">
     * excludedocfilessubdir</a>.
     * <br/>
     * Since <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#summary">Java
     * 1.4</a>.
     *
     * @see #docfilessubdirs
     */
    @Parameter( property = "excludedocfilessubdir" )
    private String excludedocfilessubdir;

    /**
     * Specifies the footer text to be placed at the bottom of each output file.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#footer">footer</a>.
     */
    @Parameter( property = "footer" )
    private String footer;

    /**
     * Separates packages on the overview page into whatever groups you specify, one group per table. The
     * packages pattern can be any package name, or can be the start of any package name followed by an asterisk
     * (<code>*</code>) meaning "match any characters". Multiple patterns can be included in a group
     * by separating them with colons (<code>:</code>).
     * <br/>
     * Example:
     * <pre>
     * &lt;groups&gt;
     *   &lt;group&gt;
     *     &lt;title&gt;Core Packages&lt;/title&gt;
     *     &lt;!-- To includes java.lang, java.lang.ref,
     *     java.lang.reflect and only java.util
     *     (i.e. not java.util.jar) --&gt;
     *     &lt;packages&gt;java.lang*:java.util&lt;/packages&gt;
     *   &lt;/group&gt;
     *   &lt;group&gt;
     *     &lt;title&gt;Extension Packages&lt;/title&gt;
     *     &nbsp;&lt;!-- To include javax.accessibility,
     *     javax.crypto, ... (among others) --&gt;
     *     &lt;packages&gt;javax.*&lt;/packages&gt;
     *   &lt;/group&gt;
     * &lt;/groups&gt;
     * </pre>
     * <b>Note</b>: using <code>java.lang.*</code> for <code>packages</code> would omit the <code>java.lang</code>
     * package but using <code>java.lang*</code> will include it.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#group">group</a>.
     * <br/>
     * See <a href="./apidocs/org/apache/maven/plugins/javadoc/options/Group.html">Javadoc</a>.
     * <br/>
     */
    @Parameter
    private Group[] groups;

    /**
     * Specifies the header text to be placed at the top of each output file.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#header">header</a>.
     */
    @Parameter( property = "header" )
    private String header;

    /**
     * Specifies the path of an alternate help file path\filename that the HELP link in the top and bottom
     * navigation bars link to.
     * <br/>
     * <b>Note</b>: could be in conflict with &lt;nohelp/&gt;.
     * <br/>
     * The <code>helpfile</code> could be an absolute File path.
     * <br/>
     * Since 2.6, it could be also be a path from a resource in the current project source directories
     * (i.e. <code>src/main/java</code>, <code>src/main/resources</code> or <code>src/main/javadoc</code>)
     * or from a resource in the Javadoc plugin dependencies, for instance:
     * <pre>
     * &lt;helpfile&gt;path/to/your/resource/yourhelp-doc.html&lt;/helpfile&gt;
     * </pre>
     * Where <code>path/to/your/resource/yourhelp-doc.html</code> could be in <code>src/main/javadoc</code>.
     * <pre>
     * &lt;build&gt;
     *   &lt;plugins&gt;
     *     &lt;plugin&gt;
     *       &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
     *       &lt;artifactId&gt;maven-javadoc-plugin&lt;/artifactId&gt;
     *       &lt;configuration&gt;
     *         &lt;helpfile&gt;path/to/your/resource/yourhelp-doc.html&lt;/helpfile&gt;
     *         ...
     *       &lt;/configuration&gt;
     *       &lt;dependencies&gt;
     *         &lt;dependency&gt;
     *           &lt;groupId&gt;groupId&lt;/groupId&gt;
     *           &lt;artifactId&gt;artifactId&lt;/artifactId&gt;
     *           &lt;version&gt;version&lt;/version&gt;
     *         &lt;/dependency&gt;
     *       &lt;/dependencies&gt;
     *     &lt;/plugin&gt;
     *     ...
     *   &lt;plugins&gt;
     * &lt;/build&gt;
     * </pre>
     * Where <code>path/to/your/resource/yourhelp-doc.html</code> is defined in the
     * <code>groupId:artifactId:version</code> javadoc plugin dependency.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#helpfile">helpfile</a>.
     */
    @Parameter( property = "helpfile" )
    private String helpfile;

    /**
     * Adds HTML meta keyword tags to the generated file for each class.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#keywords">keywords</a>.
     * <br/>
     * Since
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.2.html#commandlineoptions">
     * Java 1.4.2</a>.
     * <br/>
     * Since
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.5.0.html#commandlineoptions">
     * Java 5.0</a>.
     * <br/>
     *
     * @since 2.1
     */
    @Parameter( property = "keywords", defaultValue = "false" )
    private boolean keywords;

    /**
     * Creates links to existing javadoc-generated documentation of external referenced classes.
     * <br>
     * <b>Notes</b>:
     * <ol>
     * <li>only used if {@link #isOffline} is set to <code>false</code>.</li>
     * <li>all given links should have a fetchable <code>/package-list</code> file. For instance:
     * <pre>
     * &lt;links&gt;
     *   &lt;link&gt;https://docs.oracle.com/javase/1.4.2/docs/api&lt;/link&gt;
     * &lt;links&gt;
     * </pre>
     * will be used because <code>https://docs.oracle.com/javase/1.4.2/docs/api/package-list</code> exists.</li>
     * <li>if {@link #detectLinks} is defined, the links between the project dependencies are
     * automatically added.</li>
     * <li>if {@link #detectJavaApiLink} is defined, a Java API link, based on the Java version of the
     * project's sources, will be added automatically.</li>
     * </ol>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#link">link</a>.
     *
     * @see #detectLinks
     * @see #detectJavaApiLink
     * @see #dependencyLinks
     */
    @Parameter( property = "links" )
    protected ArrayList<String> links;
    

    /**
     * Redefine the apidoc URL for specific dependencies when using {@link #detectLinks}.
     * Useful if the dependency wasn't build with Maven or when the apidocs have been moved.
     * <pre>
     * &lt;dependencyLinks&gt;
     *   &lt;dependencyLink&gt;
     *     &lt;groupId&gt;groupId&lt;/groupId&gt;
     *     &lt;artifactId&gt;artifactId&lt;/artifactId&gt;
     *     &lt;classifier&gt;classifier&lt;/classifier&gt; &lt;!-- optional --&gt; 
     *     &lt;url&gt;version&lt;/url&gt;
     *   &lt;/dependencyLink&gt;
     * &lt;/dependencyLinks&gt;
     * </pre>
     * 
     * @see #detectLinks
     * @since 3.3.0
     */
    @Parameter
    private List<DependencyLink> dependencyLinks = new ArrayList<>();

    /**
     * Creates an HTML version of each source file (with line numbers) and adds links to them from the standard
     * HTML documentation.
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#linksource">linksource</a>.
     * <br/>
     * Since <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#summary">Java
     * 1.4</a>.
     * <br/>
     */
    @Parameter( property = "linksource", defaultValue = "false" )
    private boolean linksource;

    /**
     * Suppress the entire comment body, including the main description and all tags, generating only declarations.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#nocomment">nocomment</a>.
     * <br/>
     * Since <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#summary">Java
     * 1.4</a>.
     * <br/>
     */
    @Parameter( property = "nocomment", defaultValue = "false" )
    private boolean nocomment;

    /**
     * Prevents the generation of any deprecated API at all in the documentation.
     * <br/>
     * See
     * <a
     * href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#nodeprecated">nodeprecated</a>.
     * <br/>
     */
    @Parameter( property = "nodeprecated", defaultValue = "false" )
    private boolean nodeprecated;

    /**
     * Prevents the generation of the file containing the list of deprecated APIs (deprecated-list.html) and the
     * link in the navigation bar to that page.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#nodeprecatedlist">
     * nodeprecatedlist</a>.
     * <br/>
     */
    @Parameter( property = "nodeprecatedlist", defaultValue = "false" )
    private boolean nodeprecatedlist;

    /**
     * Omits the HELP link in the navigation bars at the top and bottom of each page of output.
     * <br/>
     * <b>Note</b>: could be in conflict with &lt;helpfile/&gt;.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#nohelp">nohelp</a>.
     * <br/>
     */
    @Parameter( property = "nohelp", defaultValue = "false" )
    private boolean nohelp;

    /**
     * Omits the index from the generated docs.
     * <br/>
     * <b>Note</b>: could be in conflict with &lt;splitindex/&gt;.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#noindex">noindex</a>.
     * <br/>
     */
    @Parameter( property = "noindex", defaultValue = "false" )
    private boolean noindex;

    /**
     * Omits the navigation bar from the generated docs.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#nonavbar">nonavbar</a>.
     * <br/>
     */
    @Parameter( property = "nonavbar", defaultValue = "false" )
    private boolean nonavbar;

    /**
     * Omits the entire overview page from the generated docs.
     * <br/>
     * <b>Note</b>: could be in conflict with &lt;overview/&gt;.
     * <br/>
     * Standard Doclet undocumented option.
     * <br/>
     *
     * @since 2.4
     */
    @Parameter( property = "nooverview", defaultValue = "false" )
    private boolean nooverview;

    /**
     * Omits qualifying package name from ahead of class names in output.
     * Example:
     * <pre>
     * &lt;noqualifier&gt;all&lt;/noqualifier&gt;
     * or
     * &lt;noqualifier&gt;packagename1:packagename2&lt;/noqualifier&gt;
     * </pre>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#noqualifier">noqualifier</a>.
     * <br/>
     * Since <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#summary">Java
     * 1.4</a>.
     */
    @Parameter( property = "noqualifier" )
    private String noqualifier;

    /**
     * Omits from the generated docs the "Since" sections associated with the since tags.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#nosince">nosince</a>.
     * <br/>
     */
    @Parameter( property = "nosince", defaultValue = "false" )
    private boolean nosince;

    /**
     * Suppresses the timestamp, which is hidden in an HTML comment in the generated HTML near the top of each page.
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#notimestamp">notimestamp</a>.
     * <br/>
     * Since
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.5.0.html#commandlineoptions">
     * Java 5.0</a>.
     * <br/>
     *
     * @since 2.1
     */
    @Parameter( property = "notimestamp", defaultValue = "false" )
    private boolean notimestamp;

    /**
     * Omits the class/interface hierarchy pages from the generated docs.
     * <br>
     * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#notree">notree</a> option
     */
    @Parameter( property = "notree", defaultValue = "false" )
    private boolean notree;

    /**
     * This option is a variation of <code>-link</code>; they both create links to javadoc-generated documentation
     * for external referenced classes.
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#linkoffline">linkoffline</a>.
     * <br/>
     * Example:
     * <pre>
     * &lt;offlineLinks&gt;
     *   &lt;offlineLink&gt;
     *     &lt;url&gt;https://docs.oracle.com/javase/1.5.0/docs/api/&lt;/url&gt;
     *     &lt;location&gt;../javadoc/jdk-5.0/&lt;/location&gt;
     *   &lt;/offlineLink&gt;
     * &lt;/offlineLinks&gt;
     * </pre>
     * <br/>
     * <b>Note</b>: if {@link #detectOfflineLinks} is defined, the offline links between the project modules are
     * automatically added if the goal is calling in a non-aggregator way.
     * <br>
     * @see <a href="./apidocs/org/apache/maven/plugins/javadoc/options/OfflineLink.html">Javadoc</a>.
     */
    @Parameter( property = "offlineLinks" )
    private OfflineLink[] offlineLinks;

    /**
     * Specifies the destination directory where javadoc saves the generated HTML files.
     * <br>
     * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#d">javadoc d</a>
     */
    @Parameter( property = "destDir", alias = "destDir", defaultValue = "${project.build.directory}/apidocs",
                    required = true )
    protected File outputDirectory;

    /**
     * Specify the text for upper left frame.
     * <br/>
     * Since
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.2.html#commandlineoptions">
     * Java 1.4.2</a>.
     *
     * @since 2.1
     */
    @Parameter( property = "packagesheader" )
    private String packagesheader;

    /**
     * Generates compile-time warnings for missing serial tags.
     * <br/>
     * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#serialwarn">serialwarn</a> option
     */
    @Parameter( property = "serialwarn", defaultValue = "false" )
    private boolean serialwarn;

    /**
     * Specify the number of spaces each tab takes up in the source. If no tab is used in source, the default
     * space is used.
     * <br/>
     * Note: was <code>linksourcetab</code> in Java 1.4.2 (refer to bug ID
     * <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4788919">4788919</a>).
     * <br/>
     * Since
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.2.html#commandlineoptions">
     * 1.4.2</a>.
     * <br/>
     * Since Java 5.0.
     *
     * @since 2.1
     */
    @Parameter( property = "sourcetab", alias = "linksourcetab" )
    private int sourcetab;

    /**
     * Splits the index file into multiple files, alphabetically, one file per letter, plus a file for any index
     * entries that start with non-alphabetical characters.
     * <br/>
     * <b>Note</b>: could be in conflict with &lt;noindex/&gt;.
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#splitindex">splitindex</a>.
     * <br/>
     */
    @Parameter( property = "splitindex", defaultValue = "false" )
    private boolean splitindex;

    /**
     * Specifies whether the stylesheet to be used is the <code>maven</code>'s javadoc stylesheet or
     * <code>java</code>'s default stylesheet when a <i>stylesheetfile</i> parameter is not specified.
     * <br/>
     * Possible values: <code>maven<code> or <code>java</code>.
     * <br/>
     */
    @Parameter( property = "stylesheet", defaultValue = "java" )
    private String stylesheet;

    /**
     * Specifies the path of an alternate HTML stylesheet file.
     * <br/>
     * The <code>stylesheetfile</code> could be an absolute File path.
     * <br/>
     * Since 2.6, it could be also be a path from a resource in the current project source directories
     * (i.e. <code>src/main/java</code>, <code>src/main/resources</code> or <code>src/main/javadoc</code>)
     * or from a resource in the Javadoc plugin dependencies, for instance:
     * <pre>
     * &lt;stylesheetfile&gt;path/to/your/resource/yourstylesheet.css&lt;/stylesheetfile&gt;
     * </pre>
     * Where <code>path/to/your/resource/yourstylesheet.css</code> could be in <code>src/main/javadoc</code>.
     * <pre>
     * &lt;build&gt;
     *   &lt;plugins&gt;
     *     &lt;plugin&gt;
     *       &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
     *       &lt;artifactId&gt;maven-javadoc-plugin&lt;/artifactId&gt;
     *       &lt;configuration&gt;
     *         &lt;stylesheetfile&gt;path/to/your/resource/yourstylesheet.css&lt;/stylesheetfile&gt;
     *         ...
     *       &lt;/configuration&gt;
     *       &lt;dependencies&gt;
     *         &lt;dependency&gt;
     *           &lt;groupId&gt;groupId&lt;/groupId&gt;
     *           &lt;artifactId&gt;artifactId&lt;/artifactId&gt;
     *           &lt;version&gt;version&lt;/version&gt;
     *         &lt;/dependency&gt;
     *       &lt;/dependencies&gt;
     *     &lt;/plugin&gt;
     *     ...
     *   &lt;plugins&gt;
     * &lt;/build&gt;
     * </pre>
     * Where <code>path/to/your/resource/yourstylesheet.css</code> is defined in the
     * <code>groupId:artifactId:version</code> javadoc plugin dependency.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#stylesheetfile">
     * stylesheetfile</a>.
     */
    @Parameter( property = "stylesheetfile" )
    private String stylesheetfile;
    
    /**
     * Specifies the path of an additional HTML stylesheet file relative to the {@link #javadocDirectory}
     * Example:
     * <pre>
     *     &lt;addStylesheets&gt;
     *         &lt;resources/addstylesheet.css&lt;/addStylesheet&gt;
     *     &lt;/addStylesheets&gt;
     * </pre>
     * @since 3.3.0
     */
    @Parameter
    private String[] addStylesheets;
    
    /**
     * Specifies the class file that starts the taglet used in generating the documentation for that tag.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#taglet">taglet</a>.
     * <br/>
     * Since
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#summary">Java 1.4</a>.
     */
    @Parameter( property = "taglet" )
    private String taglet;

    /**
     * Specifies the Taglet artifact containing the taglet class files (.class).
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#tagletpath">tagletpath</a>.
     * <br/>
     * Example:
     * <pre>
     * &lt;taglets&gt;
     *   &lt;taglet&gt;
     *     &lt;tagletClass&gt;com.sun.tools.doclets.ToDoTaglet&lt;/tagletClass&gt;
     *   &lt;/taglet&gt;
     *   &lt;taglet&gt;
     *     &lt;tagletClass&gt;package.to.AnotherTagletClass&lt;/tagletClass&gt;
     *   &lt;/taglet&gt;
     *   ...
     * &lt;/taglets&gt;
     * &lt;tagletArtifact&gt;
     *   &lt;groupId&gt;group-Taglet&lt;/groupId&gt;
     *   &lt;artifactId&gt;artifact-Taglet&lt;/artifactId&gt;
     *   &lt;version&gt;version-Taglet&lt;/version&gt;
     * &lt;/tagletArtifact&gt;
     * </pre>
     * <br/>
     * See <a href="./apidocs/org/apache/maven/plugins/javadoc/options/TagletArtifact.html">Javadoc</a>.
     * <br/>
     *
     * @since 2.1
     */
    @Parameter( property = "tagletArtifact" )
    private TagletArtifact tagletArtifact;

    /**
     * Specifies several Taglet artifacts containing the taglet class files (.class). These taglets class names will be
     * auto-detect and so no need to specify them.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#taglet">taglet</a>.
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#tagletpath">tagletpath</a>.
     * <br/>
     * Example:
     * <pre>
     * &lt;tagletArtifacts&gt;
     *   &lt;tagletArtifact&gt;
     *     &lt;groupId&gt;group-Taglet&lt;/groupId&gt;
     *     &lt;artifactId&gt;artifact-Taglet&lt;/artifactId&gt;
     *     &lt;version&gt;version-Taglet&lt;/version&gt;
     *   &lt;/tagletArtifact&gt;
     *   ...
     * &lt;/tagletArtifacts&gt;
     * </pre>
     * <br/>
     * See <a href="./apidocs/org/apache/maven/plugins/javadoc/options/TagletArtifact.html">Javadoc</a>.
     * <br/>
     *
     * @since 2.5
     */
    @Parameter( property = "tagletArtifacts" )
    private TagletArtifact[] tagletArtifacts;

    /**
     * Specifies the search paths for finding taglet class files (.class). The <code>tagletpath</code> can contain
     * multiple paths by separating them with a colon (<code>:</code>) or a semi-colon (<code>;</code>).
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#tagletpath">tagletpath</a>.
     * <br/>
     * Since
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#summary">Java 1.4</a>.
     */
    @Parameter( property = "tagletpath" )
    private String tagletpath;

    /**
     * Enables the Javadoc tool to interpret multiple taglets.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#taglet">taglet</a>.
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#tagletpath">tagletpath</a>.
     * <br/>
     * Example:
     * <pre>
     * &lt;taglets&gt;
     *   &lt;taglet&gt;
     *     &lt;tagletClass&gt;com.sun.tools.doclets.ToDoTaglet&lt;/tagletClass&gt;
     *     &lt;!--&lt;tagletpath&gt;/home/taglets&lt;/tagletpath&gt;--&gt;
     *     &lt;tagletArtifact&gt;
     *       &lt;groupId&gt;group-Taglet&lt;/groupId&gt;
     *       &lt;artifactId&gt;artifact-Taglet&lt;/artifactId&gt;
     *       &lt;version&gt;version-Taglet&lt;/version&gt;
     *     &lt;/tagletArtifact&gt;
     *   &lt;/taglet&gt;
     * &lt;/taglets&gt;
     * </pre>
     * <br/>
     * See <a href="./apidocs/org/apache/maven/plugins/javadoc/options/Taglet.html">Javadoc</a>.
     * <br/>
     *
     * @since 2.1
     */
    @Parameter( property = "taglets" )
    private Taglet[] taglets;

    /**
     * Enables the Javadoc tool to interpret a simple, one-argument custom block tag tagname in doc comments.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#tag">tag</a>.
     * <br/>
     * Since
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#summary">Java 1.4</a>.
     * <br/>
     * Example:
     * <pre>
     * &lt;tags&gt;
     *   &lt;tag&gt;
     *     &lt;name&gt;todo&lt;/name&gt;
     *     &lt;placement&gt;a&lt;/placement&gt;
     *     &lt;head&gt;To Do:&lt;/head&gt;
     *   &lt;/tag&gt;
     * &lt;/tags&gt;
     * </pre>
     * <b>Note</b>: the placement should be a combinaison of Xaoptcmf letters:
     * <ul>
     * <li><b><code>X</code></b> (disable tag)</li>
     * <li><b><code>a</code></b> (all)</li>
     * <li><b><code>o</code></b> (overview)</li>
     * <li><b><code>p</code></b> (packages)</li>
     * <li><b><code>t</code></b> (types, that is classes and interfaces)</li>
     * <li><b><code>c</code></b> (constructors)</li>
     * <li><b><code>m</code></b> (methods)</li>
     * <li><b><code>f</code></b> (fields)</li>
     * </ul>
     * See <a href="./apidocs/org/apache/maven/plugins/javadoc/options/Tag.html">Javadoc</a>.
     * <br/>
     */
    @Parameter( property = "tags" )
    private Tag[] tags;

    /**
     * Specifies the top text to be placed at the top of each output file.
     * <br/>
     * See <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6227616">6227616</a>.
     * <br/>
     * Since Java 6.0
     *
     * @since 2.4
     */
    @Parameter( property = "top" )
    private String top;

    /**
     * Includes one "Use" page for each documented class and package.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#use">use</a>.
     * <br/>
     */
    @Parameter( property = "use", defaultValue = "true" )
    private boolean use;

    /**
     * Includes the version text in the generated docs.
     * <br/>
     * See <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#version">version</a>.
     * <br/>
     */
    @Parameter( property = "version", defaultValue = "true" )
    private boolean version;

    /**
     * Specifies the title to be placed in the HTML title tag.
     * <br/>
     * See
     * <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#windowtitle">windowtitle</a>.
     * <br/>
     */
    @Parameter( property = "windowtitle", defaultValue = "${project.name} ${project.version} API" )
    private String windowtitle;

    /**
     * Whether dependency -sources jars should be resolved and included as source paths for javadoc generation.
     * This is useful when creating javadocs for a distribution project.
     *
     * @since 2.7
     */
    @Parameter( defaultValue = "false" )
    private boolean includeDependencySources;

    /**
     * Directory where unpacked project sources / test-sources should be cached.
     *
     * @see #includeDependencySources
     * @since 2.7
     */
    @Parameter( defaultValue = "${project.build.directory}/distro-javadoc-sources" )
    private File sourceDependencyCacheDir;

    /**
     * Whether to include transitive dependencies in the list of dependency -sources jars to include in this javadoc
     * run.
     *
     * @see #includeDependencySources
     * @since 2.7
     * @deprecated if these sources depend on transitive dependencies, those dependencies should be added to the pom as
     *             direct dependencies
     */
    @Parameter( defaultValue = "false" )
    @Deprecated
    private boolean includeTransitiveDependencySources;

    /**
     * List of included dependency-source patterns. Example: <code>org.apache.maven:*</code>
     *
     * @see #includeDependencySources
     * @since 2.7
     */
    @Parameter
    private List<String> dependencySourceIncludes;

    /**
     * List of excluded dependency-source patterns. Example: <code>org.apache.maven.shared:*</code>
     *
     * @see #includeDependencySources
     * @since 2.7
     */
    @Parameter
    private List<String> dependencySourceExcludes;

    /**
     * Directory into which assembled {@link JavadocOptions} instances will be written before they
     * are added to javadoc resources bundles.
     *
     * @since 2.7
     */
    @Parameter( defaultValue = "${project.build.directory}/javadoc-bundle-options", readonly = true )
    private File javadocOptionsDir;

    /**
     * Transient variable to allow lazy-resolution of javadoc bundles from dependencies, so they can
     * be used at various points in the javadoc generation process.
     *
     * @since 2.7
     */
    private transient List<JavadocBundle> dependencyJavadocBundles;

    /**
     * Capability to add additional dependencies to the javadoc classpath.
     * Example:
     * <pre>
     * &lt;additionalDependencies&gt;
     *   &lt;additionalDependency&gt;
     *     &lt;groupId&gt;geronimo-spec&lt;/groupId&gt;
     *     &lt;artifactId&gt;geronimo-spec-jta&lt;/artifactId&gt;
     *     &lt;version&gt;1.0.1B-rc4&lt;/version&gt;
     *   &lt;/additionalDependency&gt;
     * &lt;/additionalDependencies&gt;
     * </pre>
     *
     * @since 2.8.1
     */
    @Parameter
    private List<AdditionalDependency> additionalDependencies;

    /**
     * Include filters on the source files. Default is **\/\*.java.
     * These are ignored if you specify subpackages or subpackage excludes.
     *
     * @since 2.9
     */
    @Parameter
    private List<String> sourceFileIncludes;

    /**
     * exclude filters on the source files.
     * These are ignored if you specify subpackages or subpackage excludes.
     *
     * @since 2.9
     */
    @Parameter
    private List<String> sourceFileExcludes;

    /**
     * To apply the security fix on generated javadoc see http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1571
     * @since 2.9.1
     */
    @Parameter( defaultValue = "true", property = "maven.javadoc.applyJavadocSecurityFix" )
    private boolean applyJavadocSecurityFix = true;

    /**
     * <p>
     * Allow for configuration of the javadoc tool via maven toolchains.
     * This overrules the toolchain selected by the maven-toolchain-plugin.
     * </p>
     *
     * <p>Examples:</p>
     * (see <a href="https://maven.apache.org/guides/mini/guide-using-toolchains.html">
     *     Guide to Toolchains</a> for more info)
     *
     * <pre>
     * {@code
     *    <configuration>
     *        ...
     *        <jdkToolchain>
     *            <version>11</version>
     *        </jdkToolchain>
     *    </configuration>
     *
     *    <configuration>
     *        ...
     *        <jdkToolchain>
     *            <version>1.8</version>
     *            <vendor>zulu</vendor>
     *        </jdkToolchain>
     *    </configuration>
     *    }
     * </pre>
     * 
     * <strong>note:</strong> requires at least Maven 3.3.1
     *
     * @since 3.0.0
     */
    @Parameter
    private Map<String, String> jdkToolchain;

    /**
     * <p>
     * Location of the file used to store the state of the previous javadoc run.
     * This is used to skip the generation if nothing has changed.
     * </p>
     *
     * @since 3.2.0
     */
    @Parameter( property = "staleDataPath",
            defaultValue = "${project.build.directory}/maven-javadoc-plugin-stale-data.txt" )
    private File staleDataPath;


    /**
     * <p>
     * Comma separated list of modules (artifactId) to not add in aggregated javadoc
     * </p>
     *
     * @since 3.2.0
     */
    @Parameter( property = "maven.javadoc.skippedModules" )
    private String skippedModules;

    /**
     * Timestamp for reproducible output archive entries, either formatted as ISO 8601
     * <code>yyyy-MM-dd'T'HH:mm:ssXXX</code> or as an int representing seconds since the epoch (like
     * <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
     *
     * @since 3.2.0
     */
    @Parameter( defaultValue = "${project.build.outputTimestamp}" )
    protected String outputTimestamp;

    // ----------------------------------------------------------------------
    // protected methods
    // ----------------------------------------------------------------------

    /**
     * Indicates whether this goal is flagged with <code>@aggregator</code>.
     *
     * @return <code>true</code> if the goal is designed as an aggregator, <code>false</code> otherwise.
     * @see AggregatorJavadocReport
     * @see AggregatorTestJavadocReport
     */
    protected boolean isAggregator()
    {
        return false;
    }

    /**
     * Indicates whether this goal generates documentation for the <code>Java Test code</code>.
     *
     * @return <code>true</code> if the goal generates Test Javadocs, <code>false</code> otherwise.
     */
    protected boolean isTest()
    {
        return false;
    }

    /**
     * @return the output directory
     */
    protected String getOutputDirectory()
    {
        return outputDirectory.getAbsoluteFile().toString();
    }

    protected MavenProject getProject()
    {
        return project;
    }

    /**
     * @param p not null maven project
     * @return the list of directories where compiled classes are placed for the given project. These dirs are
     *         added in the javadoc classpath.
     */
    protected List<File> getProjectBuildOutputDirs( MavenProject p )
    {
        if ( StringUtils.isEmpty( p.getBuild().getOutputDirectory() ) )
        {
            return Collections.emptyList();
        }

        return Collections.singletonList( new File( p.getBuild().getOutputDirectory() ) );
    }

    /**
     * Either returns the attached artifact file or outputDirectory
     * 
     * @param project
     * @return
     */
    protected File getClassesFile( MavenProject project )
    {
        if ( !isAggregator() && isTest() )
        {
            return null;
        }

        if ( project.getArtifact() != null && project.getArtifact().getFile() != null )
        {
            File artifactFile = project.getArtifact().getFile();
            if ( artifactFile.isDirectory() || artifactFile.getName().endsWith( ".jar" ) )
            {
                return artifactFile;
            }
        }
        else if ( project.getExecutionProject() != null 
                        && project.getExecutionProject().getArtifact() != null
                        && project.getExecutionProject().getArtifact().getFile() != null )
        {
            File artifactFile = project.getExecutionProject().getArtifact().getFile();
            if ( artifactFile.isDirectory() || artifactFile.getName().endsWith( ".jar" ) )
            {
                return artifactFile;
            }
        }
        
        if ( project.getBuild().getOutputDirectory() != null )
        {
            return new File( project.getBuild().getOutputDirectory() );    
        }
        else
        {
            return null;
        }
    }

    /**
     * @param p not null maven project
     * @return the list of source paths for the given project
     */
    protected List<String> getProjectSourceRoots( MavenProject p )
    {
        if ( "pom".equals( p.getPackaging().toLowerCase() ) )
        {
            return Collections.emptyList();
        }

        return ( p.getCompileSourceRoots() == null
            ? Collections.<String>emptyList()
            : new LinkedList<>( p.getCompileSourceRoots() ) );
    }

    /**
     * @param p not null maven project
     * @return the list of source paths for the execution project of the given project
     */
    protected List<String> getExecutionProjectSourceRoots( MavenProject p )
    {
        if ( "pom".equals( p.getExecutionProject().getPackaging().toLowerCase() ) )
        {
            return Collections.emptyList();
        }

        return ( p.getExecutionProject().getCompileSourceRoots() == null
            ? Collections.<String>emptyList()
            : new LinkedList<>( p.getExecutionProject().getCompileSourceRoots() ) );
    }

    /**
     * @return the current javadoc directory
     */
    protected File getJavadocDirectory()
    {
        return javadocDirectory;
    }

    /**
     * @return the doclint specific checks configuration
     */
    protected String getDoclint()
    {
        return doclint;
    }

    /**
     * @return the title to be placed near the top of the overview summary file
     */
    protected String getDoctitle()
    {
        return doctitle;
    }

    /**
     * @return the overview documentation file from the user parameter or from the <code>javadocdirectory</code>
     */
    protected File getOverview()
    {
        return overview;
    }

    /**
     * @return the title to be placed in the HTML title tag
     */
    protected String getWindowtitle()
    {
        return windowtitle;
    }

    /**
     * @return the charset attribute or the value of {@link #getDocencoding()} if <code>null</code>.
     */
    private String getCharset()
    {
        return ( StringUtils.isEmpty( charset ) ) ? getDocencoding() : charset;
    }

    /**
     * @return the docencoding attribute or <code>UTF-8</code> if <code>null</code>.
     */
    private String getDocencoding()
    {
        return ( StringUtils.isEmpty( docencoding ) ) ? ReaderFactory.UTF_8 : docencoding;
    }

    /**
     * @return the encoding attribute or the value of <code>file.encoding</code> system property if <code>null</code>.
     */
    private String getEncoding()
    {
        return ( StringUtils.isEmpty( encoding ) ) ? ReaderFactory.FILE_ENCODING : encoding;
    }

    @Override
    public void execute()
        throws MojoExecutionException
    {
        verifyRemovedParameter( "aggregator" );
        verifyRemovedParameter( "proxyHost" );
        verifyRemovedParameter( "proxyPort" );
        verifyReplacedParameter( "additionalparam", "additionalOptions" );

        doExecute();
    }

    abstract void doExecute() throws MojoExecutionException;

    protected final void verifyRemovedParameter( String paramName )
    {
        Xpp3Dom configDom = mojo.getConfiguration();
        if ( configDom != null )
        {
            if ( configDom.getChild( paramName ) != null )
            {
                throw new IllegalArgumentException( "parameter '" + paramName
                    + "' has been removed from the plugin, please verify documentation." );
            }
        }
    }

    private void verifyReplacedParameter( String oldParamName, String newParamNew )
    {
        Xpp3Dom configDom = mojo.getConfiguration();
        if ( configDom != null )
        {
            if ( configDom.getChild( oldParamName ) != null )
            {
                throw new IllegalArgumentException( "parameter '" + oldParamName
                    + "' has been replaced with " + newParamNew + ", please verify documentation." );
            }
        }
    }

    /**
     * The <a href="package-summary.html">package documentation</a> details the
     * Javadoc Options used by this Plugin.
     *
     * @param unusedLocale the wanted locale (actually unused).
     * @throws MavenReportException if any
     */
    protected void executeReport( Locale unusedLocale )
        throws MavenReportException
    {
        if ( skip )
        {
            getLog().info( "Skipping javadoc generation" );
            return;
        }

        if ( getLog().isDebugEnabled() )
        {
            this.debug = true;
        }

        // NOTE: Always generate this file, to allow javadocs from modules to be aggregated via
        // useDependencySources in a distro module build.
        try
        {
            buildJavadocOptions();
        }
        catch ( IOException e )
        {
            throw new MavenReportException( "Failed to generate javadoc options file: " + e.getMessage(), e );
        }

        Collection<JavadocModule> sourcePaths = getSourcePaths();

        Collection<Path> collectedSourcePaths = sourcePaths.stream()
                                                           .flatMap( e -> e.getSourcePaths().stream() )
                                                           .collect( Collectors.toList() );

        Map<Path, Collection<String>> files = getFiles( collectedSourcePaths );
        if ( !canGenerateReport( files ) )
        {
            return;
        }

        // ----------------------------------------------------------------------
        // Find the javadoc executable and version
        // ----------------------------------------------------------------------

        String jExecutable;
        try
        {
            jExecutable = getJavadocExecutable();
        }
        catch ( IOException e )
        {
            throw new MavenReportException( "Unable to find javadoc command: " + e.getMessage(), e );
        }
        setFJavadocVersion( new File( jExecutable ) );

        Collection<String> packageNames;
        if ( javadocRuntimeVersion.isAtLeast( "9" ) )
        {
            packageNames = getPackageNamesRespectingJavaModules( sourcePaths );
        }
        else
        {
            packageNames = getPackageNames( files );
        }

        // ----------------------------------------------------------------------
        // Javadoc output directory as File
        // ----------------------------------------------------------------------

        File javadocOutputDirectory = new File( getOutputDirectory() );
        if ( javadocOutputDirectory.exists() && !javadocOutputDirectory.isDirectory() )
        {
            throw new MavenReportException( "IOException: " + getOutputDirectory() + " is not a directory." );
        }
        if ( javadocOutputDirectory.exists() && !javadocOutputDirectory.canWrite() )
        {
            throw new MavenReportException( "IOException: " + getOutputDirectory() + " is not writable." );
        }
        javadocOutputDirectory.mkdirs();

        // ----------------------------------------------------------------------
        // Copy all resources
        // ----------------------------------------------------------------------

        copyAllResources( javadocOutputDirectory );

        // ----------------------------------------------------------------------
        // Create command line for Javadoc
        // ----------------------------------------------------------------------

        Commandline cmd = new Commandline();
        cmd.getShell().setQuotedArgumentsEnabled( false ); // for Javadoc JVM args
        cmd.setWorkingDirectory( javadocOutputDirectory.getAbsolutePath() );
        cmd.setExecutable( jExecutable );

        // ----------------------------------------------------------------------
        // Wrap Javadoc JVM args
        // ----------------------------------------------------------------------

        addMemoryArg( cmd, "-Xmx", this.maxmemory );
        addMemoryArg( cmd, "-Xms", this.minmemory );
        addProxyArg( cmd );

        if ( StringUtils.isNotEmpty( additionalJOption ) )
        {
            cmd.createArg().setValue( additionalJOption );
        }

        if ( additionalJOptions != null && additionalJOptions.length != 0 )
        {
            for ( String jo : additionalJOptions )
            {
                cmd.createArg().setValue( jo );
            }
        }

        // ----------------------------------------------------------------------
        // Wrap Standard doclet Options
        // ----------------------------------------------------------------------
        List<String> standardDocletArguments = new ArrayList<>();

        Set<OfflineLink> offlineLinks;
        if ( StringUtils.isEmpty( doclet ) || useStandardDocletOptions )
        {
            offlineLinks = getLinkofflines();
            addStandardDocletOptions( javadocOutputDirectory, standardDocletArguments, offlineLinks );
        }
        else
        {
            offlineLinks = Collections.emptySet();
        }

        // ----------------------------------------------------------------------
        // Wrap Javadoc options
        // ----------------------------------------------------------------------
        List<String> javadocArguments = new ArrayList<>();

        addJavadocOptions( javadocOutputDirectory, javadocArguments, sourcePaths, offlineLinks );

        // ----------------------------------------------------------------------
        // Write options file and include it in the command line
        // ----------------------------------------------------------------------

        List<String> arguments = new ArrayList<>( javadocArguments.size() + standardDocletArguments.size() );
        arguments.addAll( javadocArguments );
        arguments.addAll( standardDocletArguments );

        if ( arguments.size() > 0 )
        {
            addCommandLineOptions( cmd, arguments, javadocOutputDirectory );
        }

        // ----------------------------------------------------------------------
        // Write packages file and include it in the command line
        // ----------------------------------------------------------------------

        // MJAVADOC-365 if includes/excludes are specified, these take precedence over the default
        // package-based mode and force javadoc into file-based mode unless subpackages are
        // specified. Subpackages take precedence over file-based include/excludes. Why? Because
        // getFiles(...) returns an empty list when subpackages are specified.
        boolean includesExcludesActive =
            ( sourceFileIncludes != null && !sourceFileIncludes.isEmpty() )
                || ( sourceFileExcludes != null && !sourceFileExcludes.isEmpty() );
        if ( includesExcludesActive && !StringUtils.isEmpty( subpackages ) )
        {
            getLog().warn( "sourceFileIncludes and sourceFileExcludes have no effect when subpackages are specified!" );
            includesExcludesActive = false;
        }
        if ( !packageNames.isEmpty() && !includesExcludesActive )
        {
            addCommandLinePackages( cmd, javadocOutputDirectory, packageNames );

            // ----------------------------------------------------------------------
            // Write argfile file and include it in the command line
            // ----------------------------------------------------------------------

            List<String> specialFiles = getSpecialFiles( files );

            if ( !specialFiles.isEmpty() )
            {
                addCommandLineArgFile( cmd, javadocOutputDirectory, specialFiles );
            }
        }
        else
        {
            // ----------------------------------------------------------------------
            // Write argfile file and include it in the command line
            // ----------------------------------------------------------------------

            List<String> allFiles = new ArrayList<>();
            for ( Map.Entry<Path, Collection<String>> filesEntry : files.entrySet() )
            {
                for ( String file : filesEntry.getValue() )
                {
                    allFiles.add( filesEntry.getKey().resolve( file ).toString() );
                }
            }

            if ( !files.isEmpty() )
            {
                addCommandLineArgFile( cmd, javadocOutputDirectory, allFiles );
            }
        }

        // ----------------------------------------------------------------------
        // Execute command line
        // ----------------------------------------------------------------------

        executeJavadocCommandLine( cmd, javadocOutputDirectory );

        // delete generated javadoc files only if no error and no debug mode
        // [MJAVADOC-336] Use File.delete() instead of File.deleteOnExit() to
        // prevent these files from making their way into archives.
        if ( !debug )
        {
            for ( int i = 0; i < cmd.getArguments().length; i++ )
            {
                String arg = cmd.getArguments()[i].trim();

                if ( !arg.startsWith( "@" ) )
                {
                    continue;
                }

                File argFile = new File( javadocOutputDirectory, arg.substring( 1 ) );
                if ( argFile.exists() )
                {
                    argFile.delete();
                }
            }

            File scriptFile = new File( javadocOutputDirectory, DEBUG_JAVADOC_SCRIPT_NAME );
            if ( scriptFile.exists() )
            {
                scriptFile.delete();
            }
        }
        if ( applyJavadocSecurityFix )
        {
            // finally, patch the Javadoc vulnerability in older Javadoc tools (CVE-2013-1571):
            try
            {
                final int patched = fixFrameInjectionBug( javadocOutputDirectory, getDocencoding() );
                if ( patched > 0 )
                {
                    getLog().info(
                        String.format( "Fixed Javadoc frame injection vulnerability (CVE-2013-1571) in %d files.",
                                       patched ) );
                }
            }
            catch ( IOException e )
            {
                throw new MavenReportException( "Failed to patch javadocs vulnerability: " + e.getMessage(), e );
            }
        }
        else
        {
          getLog().info( "applying javadoc security fix has been disabled" );
        }
    }

    /**
     * Method to get the files on the specified source paths
     *
     * @param sourcePaths a Collection that contains the paths to the source files
     * @return a List that contains the specific path for every source file
     * @throws MavenReportException {@link MavenReportException} issue while generating report
     */
    protected Map<Path, Collection<String>> getFiles( Collection<Path> sourcePaths )
        throws MavenReportException
    {
        Map<Path, Collection<String>> mappedFiles = new LinkedHashMap<>( sourcePaths.size() );
        if ( StringUtils.isEmpty( subpackages ) )
        {
            Collection<String> excludedPackages = getExcludedPackages();
            
            final boolean autoExclude;
            if ( release != null )
            {
                autoExclude = JavaVersion.parse( release ).isBefore( "9" );
            }
            else if ( source != null )
            {
                autoExclude = JavaVersion.parse( source ).isBefore( "9" );
            }
            else
            {
                autoExclude = false;
            }

            for ( Path sourcePath : sourcePaths )
            {
                File sourceDirectory = sourcePath.toFile();
                List<String> files = new ArrayList<>( JavadocUtil.getFilesFromSource( sourceDirectory,
                        sourceFileIncludes, sourceFileExcludes,
                        excludedPackages ) );

                if ( autoExclude && files.remove( "module-info.java" ) )
                {
                    getLog().debug( "Auto exclude module-info.java due to source value" );
                }
                mappedFiles.put( sourcePath, files );
            }
        }

        return mappedFiles;
    }

    /**
     * Method to get the source paths per reactorProject. If no source path is specified in the parameter, the compile
     * source roots of the project will be used.
     *
     * @return a Map of the project absolute source paths per projects key (G:A)
     * @throws MavenReportException {@link MavenReportException} issue while generating report
     * @see JavadocUtil#pruneDirs(MavenProject, Collection)
     */
    protected Collection<JavadocModule> getSourcePaths()
        throws MavenReportException
    {
        Collection<JavadocModule> mappedSourcePaths = new ArrayList<>();

        if ( StringUtils.isEmpty( sourcepath ) )
        {
            if ( !"pom".equals( project.getPackaging()  ) )
            {
                Set<Path> sourcePaths =
                    new LinkedHashSet<>( JavadocUtil.pruneDirs( project, getProjectSourceRoots( project ) ) );

                if ( project.getExecutionProject() != null )
                {
                    sourcePaths.addAll( JavadocUtil.pruneDirs( project, getExecutionProjectSourceRoots( project ) ) );
                }

                /*
                 * Should be after the source path (i.e. -sourcepath '.../src/main/java;.../src/main/javadoc') and *not*
                 * the opposite. If not, the javadoc tool always copies doc files, even if -docfilessubdirs is not
                 * setted.
                 */
                if ( getJavadocDirectory() != null )
                {
                    File javadocDir = getJavadocDirectory();
                    if ( javadocDir.exists() && javadocDir.isDirectory() )
                    {
                        Collection<Path> l =
                            JavadocUtil.pruneDirs( project,
                                               Collections.singletonList( getJavadocDirectory().getAbsolutePath() ) );
                        sourcePaths.addAll( l );
                    }
                }
                if ( !sourcePaths.isEmpty() )
                {
                    mappedSourcePaths.add( buildJavadocModule( project, sourcePaths ) );
                }
            }

            if ( isAggregator() )
            {
                for ( MavenProject subProject : getAggregatedProjects() )
                {
                    if ( subProject != project )
                    {
                        Collection<Path> additionalSourcePaths = new ArrayList<>();

                        List<String> sourceRoots = getProjectSourceRoots( subProject );

                        if ( subProject.getExecutionProject() != null )
                        {
                            sourceRoots.addAll( getExecutionProjectSourceRoots( subProject ) );
                        }

                        ArtifactHandler artifactHandler = subProject.getArtifact().getArtifactHandler();
                        if ( "java".equals( artifactHandler.getLanguage() ) )
                        {
                            additionalSourcePaths.addAll( JavadocUtil.pruneDirs( subProject, sourceRoots ) );
                        }

                        if ( getJavadocDirectory() != null )
                        {
                            String javadocDirRelative =
                                PathUtils.toRelative( project.getBasedir(),
                                                      getJavadocDirectory().getAbsolutePath() );
                            File javadocDir = new File( subProject.getBasedir(), javadocDirRelative );
                            if ( javadocDir.exists() && javadocDir.isDirectory() )
                            {
                                Collection<Path> l = JavadocUtil.pruneDirs( subProject, Collections.singletonList(
                                        javadocDir.getAbsolutePath() ) );
                                additionalSourcePaths.addAll( l );
                            }
                        }
                        
                        if ( !additionalSourcePaths.isEmpty() )
                        {
                            mappedSourcePaths.add( buildJavadocModule( subProject , additionalSourcePaths ) );
                        }
                    }
                }
            }

            if ( includeDependencySources )
            {
                mappedSourcePaths.addAll( getDependencySourcePaths() );
            }
        }
        else
        {
            Collection<Path> sourcePaths =
                JavadocUtil.pruneDirs( project,
                                       new ArrayList<>( Arrays.asList( JavadocUtil.splitPath( sourcepath ) ) ) );
            if ( getJavadocDirectory() != null )
            {
                Collection<Path> l = JavadocUtil.pruneDirs( project, Collections.singletonList(
                    getJavadocDirectory().getAbsolutePath() ) );
                sourcePaths.addAll( l );
            }
            
            if ( !sourcePaths.isEmpty() )
            {
                mappedSourcePaths.add( new JavadocModule( ArtifactUtils.versionlessKey( project.getGroupId(),
                                                                                        project.getArtifactId() ),
                                                          getClassesFile( project ),
                                                          sourcePaths ) );
            }
        }

        return mappedSourcePaths;
    }
    
    private JavadocModule buildJavadocModule( MavenProject project, Collection<Path> sourcePaths )
    {
        File classessFile = getClassesFile( project );
        ResolvePathResult resolvePathResult = getResolvePathResult( classessFile );
        if ( resolvePathResult == null )
        {
            return new JavadocModule( ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ),
                                      classessFile, 
                                      sourcePaths );
        }
        else
        {
            return new JavadocModule( ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ),
                                      classessFile, 
                                      sourcePaths, 
                                      resolvePathResult.getModuleDescriptor(),
                                      resolvePathResult.getModuleNameSource() );
        }
    }

    /**
     * Recursively add the modules of the aggregatedProject to the set of aggregatedModules.
     *
     * @param aggregatedProject the project being aggregated
     * @param reactorProjectsMap map of (still) available reactor projects
     */
    private Set<MavenProject> modulesForAggregatedProject( MavenProject aggregatedProject,
                                                           Map<Path, MavenProject> reactorProjectsMap )
    {
        // Maven does not supply an easy way to get the projects representing
        // the modules of a project. So we will get the paths to the base
        // directories of the modules from the project and compare with the
        // base directories of the projects in the reactor.

        if ( aggregatedProject.getModules().isEmpty() )
        {
            return Collections.singleton( aggregatedProject );
        }

        Path basePath = aggregatedProject.getBasedir().toPath();
        List<Path> modulePaths = new LinkedList<>();
        for ( String module :  aggregatedProject.getModules() )
        {
            modulePaths.add( basePath.resolve( module ).normalize() );
        }

        Set<MavenProject> aggregatedModules = new LinkedHashSet<>();

        for ( Path modulePath : modulePaths )
        {
            MavenProject module = reactorProjectsMap.remove( modulePath );
            if ( module != null )
            {
                aggregatedModules.addAll( modulesForAggregatedProject( module, reactorProjectsMap ) );
            }
        }

        return aggregatedModules;
    }

    /**
     * Override this method to customize the configuration for resolving dependency sources. The default
     * behavior enables the resolution of -sources jar files.
     * @param config {@link SourceResolverConfig}
     * @return {@link SourceResolverConfig}
     */
    protected SourceResolverConfig configureDependencySourceResolution( final SourceResolverConfig config )
    {
        return config.withCompileSources();
    }

    /**
     * Resolve dependency sources so they can be included directly in the javadoc process. To customize this,
     * override {@link AbstractJavadocMojo#configureDependencySourceResolution(SourceResolverConfig)}.
     * @return List of source paths.
     * @throws MavenReportException {@link MavenReportException}
     */
    protected final Collection<JavadocModule> getDependencySourcePaths()
        throws MavenReportException
    {
        try
        {
            if ( sourceDependencyCacheDir.exists() )
            {
                FileUtils.forceDelete( sourceDependencyCacheDir );
                sourceDependencyCacheDir.mkdirs();
            }
        }
        catch ( IOException e )
        {
            throw new MavenReportException(
                "Failed to delete cache directory: " + sourceDependencyCacheDir + "\nReason: " + e.getMessage(), e );
        }

        final SourceResolverConfig config = getDependencySourceResolverConfig();

        try
        {
            return resourceResolver.resolveDependencySourcePaths( config );
        }
        catch ( final ArtifactResolutionException | ArtifactNotFoundException e )
        {
            throw new MavenReportException(
                "Failed to resolve one or more javadoc source/resource artifacts:\n\n" + e.getMessage(), e );
        }
    }

    /**
     * Returns a ArtifactFilter that only includes direct dependencies of this project
     * (verified via groupId and artifactId).
     *
     * @return
     */
    private TransformableFilter createDependencyArtifactFilter()
    {
        Set<Artifact> dependencyArtifacts = project.getDependencyArtifacts();

        List<String> artifactPatterns = new ArrayList<>( dependencyArtifacts.size() );
        for ( Artifact artifact : dependencyArtifacts )
        {
            artifactPatterns.add( artifact.getGroupId() + ":" + artifact.getArtifactId() );
        }

        return new PatternInclusionsFilter( artifactPatterns );
    }

    /**
     * Construct a SourceResolverConfig for resolving dependency sources and resources in a consistent
     * way, so it can be reused for both source and resource resolution.
     *
     * @since 2.7
     */
    private SourceResolverConfig getDependencySourceResolverConfig()
    {
        final List<TransformableFilter> andFilters = new ArrayList<>();

        final List<String> dependencyIncludes = dependencySourceIncludes;
        final List<String> dependencyExcludes = dependencySourceExcludes;

        if ( !includeTransitiveDependencySources || isNotEmpty( dependencyIncludes ) || isNotEmpty(
            dependencyExcludes ) )
        {
            if ( !includeTransitiveDependencySources )
            {
                andFilters.add( createDependencyArtifactFilter() );
            }

            if ( isNotEmpty( dependencyIncludes ) )
            {
                andFilters.add( new PatternInclusionsFilter( dependencyIncludes ) );
            }

            if ( isNotEmpty( dependencyExcludes ) )
            {
                andFilters.add( new PatternExclusionsFilter( dependencyExcludes ) );
            }
        }
        
        return configureDependencySourceResolution( new SourceResolverConfig( project,
                                                  getProjectBuildingRequest( project ),
                                                  sourceDependencyCacheDir )
                                                  .withReactorProjects( this.reactorProjects ) )
                                                  .withFilter( new AndFilter( andFilters ) );
        
    }
    
    private ProjectBuildingRequest getProjectBuildingRequest( MavenProject currentProject )
    {
        return new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() )
                          .setRemoteRepositories( currentProject.getRemoteArtifactRepositories() );
    }

    /**
     * Method that indicates whether the javadoc can be generated or not. If the project does not contain any source
     * files and no subpackages are specified, the plugin will terminate.
     *
     * @param files the project files
     * @return a boolean that indicates whether javadoc report can be generated or not
     */
    protected boolean canGenerateReport( Map<Path, Collection<String>> files )
    {
        for ( Collection<String> filesValues : files.values() )
        {
            if ( !filesValues.isEmpty() )
            {
                return true;
            }
        }

        return !StringUtils.isEmpty( subpackages );
    }

    // ----------------------------------------------------------------------
    // private methods
    // ----------------------------------------------------------------------

    /**
     * Method to get the excluded source files from the javadoc and create the argument string
     * that will be included in the javadoc commandline execution.
     *
     * @param sourcePaths the collection of paths to the source files
     * @return a String that contains the exclude argument that will be used by javadoc
     * @throws MavenReportException
     */
    private String getExcludedPackages( Collection<Path> sourcePaths )
        throws MavenReportException
    {
        List<String> excludedNames = null;

        if ( StringUtils.isNotEmpty( sourcepath ) && StringUtils.isNotEmpty( subpackages ) )
        {
            Collection<String> excludedPackages = getExcludedPackages();

            excludedNames = JavadocUtil.getExcludedPackages( sourcePaths, excludedPackages );
        }

        String excludeArg = "";
        if ( StringUtils.isNotEmpty( subpackages ) && excludedNames != null )
        {
            // add the excludedpackage names
            excludeArg = StringUtils.join( excludedNames.iterator(), ":" );
        }

        return excludeArg;
    }

    /**
     * Method to format the specified source paths that will be accepted by the javadoc tool.
     *
     * @param sourcePaths the list of paths to the source files that will be included in the javadoc.
     * @return a String that contains the formatted source path argument, separated by the System pathSeparator
     *         string (colon (<code>:</code>) on Solaris or semi-colon (<code>;</code>) on Windows).
     * @see File#pathSeparator
     */
    private String getSourcePath( Collection<Path> sourcePaths )
    {
        String sourcePath = null;

        if ( StringUtils.isEmpty( subpackages ) || StringUtils.isNotEmpty( sourcepath ) )
        {
            sourcePath = StringUtils.join( sourcePaths.iterator(), File.pathSeparator );
        }

        return sourcePath;
    }

    /**
     * Method to get the packages specified in the <code>excludePackageNames</code> parameter. The packages are split
     * with ',', ':', or ';' and then formatted.
     *
     * @return an array of String objects that contain the package names
     * @throws MavenReportException
     */
    private Collection<String> getExcludedPackages()
        throws MavenReportException
    {
        Set<String> excluded = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getExcludePackageNames() ) )
                    {
                        excluded.addAll( options.getExcludePackageNames() );
                    }
                }
            }
        }

        // for the specified excludePackageNames
        if ( StringUtils.isNotEmpty( excludePackageNames ) )
        {
            List<String> packageNames = Arrays.asList( excludePackageNames.split( "[,:;]" ) );
            excluded.addAll( trimValues( packageNames ) );
        }

        return excluded;
    }

    private static List<String> trimValues( List<String> items )
    {
        List<String> result = new ArrayList<>( items.size() );
        for ( String item : items )
        {
            String trimmed = item.trim();
            if ( StringUtils.isEmpty( trimmed ) )
            {
                continue;
            }
            result.add( trimmed );
        }
        return result;
    }

    /**
     * Method that gets the classpath and modulepath elements that will be specified in the javadoc
     * <code>-classpath</code> and <code>--module-path</code> parameter.
     * Since we have all the sources of the current reactor, it is sufficient to consider the
     * dependencies of the reactor modules, excluding the module artifacts which may not yet be available
     * when the reactor project is built for the first time.
     *
     * @return all classpath elements
     * @throws MavenReportException if any.
     */
    private Collection<File> getPathElements()
        throws MavenReportException
    {
        Set<File> classpathElements = new LinkedHashSet<>();
        Map<String, Artifact> compileArtifactMap = new LinkedHashMap<>();

        if ( isTest() )
        {
            classpathElements.addAll( getProjectBuildOutputDirs( project ) );
        }

        populateCompileArtifactMap( compileArtifactMap, project.getArtifacts() );

        if ( isAggregator() )
        {
            Collection<MavenProject> aggregatorProjects = getAggregatedProjects();

            List<String> reactorArtifacts = new ArrayList<>();
            for ( MavenProject p : aggregatorProjects )
            {
                reactorArtifacts.add( p.getGroupId() + ':' + p.getArtifactId() );
            }

            TransformableFilter dependencyFilter = new AndFilter( Arrays.asList(
                                                                     new PatternExclusionsFilter( reactorArtifacts ),
                                                                     getDependencyScopeFilter() ) );

            for ( MavenProject subProject : aggregatorProjects )
            {
                if ( subProject != project )
                {
                    File projectArtifactFile = getClassesFile( subProject );
                    if ( projectArtifactFile != null )
                    {
                        classpathElements.add( projectArtifactFile );
                    }
                    else
                    {
                        classpathElements.addAll( getProjectBuildOutputDirs( subProject ) );
                    }

                    try
                    {
                        StringBuilder sb = new StringBuilder();

                        sb.append( "Compiled artifacts for " );
                        sb.append( subProject.getGroupId() ).append( ":" );
                        sb.append( subProject.getArtifactId() ).append( ":" );
                        sb.append( subProject.getVersion() ).append( '\n' );

                        ProjectBuildingRequest buildingRequest = getProjectBuildingRequest( subProject );

                        List<Dependency> managedDependencies = null;
                        if ( subProject.getDependencyManagement() != null )
                        {
                            managedDependencies = subProject.getDependencyManagement().getDependencies();
                        }

                        for ( ArtifactResult artifactResult
                                    : dependencyResolver.resolveDependencies( buildingRequest,
                                                                              subProject.getDependencies(),
                                                                              managedDependencies,
                                                                              dependencyFilter ) )
                        {
                            populateCompileArtifactMap( compileArtifactMap,
                                                        Collections.singletonList( artifactResult.getArtifact() ) );

                            sb.append( artifactResult.getArtifact().getFile() ).append( '\n' );
                        }

                        if ( getLog().isDebugEnabled() )
                        {
                            getLog().debug( sb.toString() );
                        }

                    }
                    catch ( DependencyResolverException e )
                    {
                        throw new MavenReportException( e.getMessage(), e );
                    }
                }
            }
        }

        for ( Artifact a : compileArtifactMap.values() )
        {
            classpathElements.add( a.getFile() );
        }

        if ( additionalDependencies != null )
        {
            for ( Dependency dependency : additionalDependencies )
            {
                Artifact artifact = resolveDependency( dependency );
                getLog().debug( "add additional artifact with path " + artifact.getFile() );
                classpathElements.add( artifact.getFile() );
            }
        }

        return classpathElements;
    }

    protected ScopeFilter getDependencyScopeFilter()
    {
        return ScopeFilter.including( Artifact.SCOPE_COMPILE, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_SYSTEM );
    }

    /**
     * @param dependency {@link Dependency}
     * @return {@link Artifact}
     * @throws MavenReportException when artifact could not be resolved
     */
    public Artifact resolveDependency( Dependency dependency )
        throws MavenReportException
    {
        DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate();
        coordinate.setGroupId( dependency.getGroupId() );
        coordinate.setArtifactId( dependency.getArtifactId() );
        coordinate.setVersion( dependency.getVersion() );
        coordinate.setClassifier( dependency.getClassifier() );
        coordinate.setExtension( artifactHandlerManager.getArtifactHandler( dependency.getType() ).getExtension() );

        try
        {
            return artifactResolver.resolveArtifact( getProjectBuildingRequest( project ), coordinate ).getArtifact();
        }
        catch ( ArtifactResolverException e )
        {
            throw new MavenReportException( "artifact resolver problem - " + e.getMessage(), e );
        }
    }


    //TODO remove the part with ToolchainManager lookup once we depend on
    //3.0.9 (have it as prerequisite). Define as regular component field then.
    protected final Toolchain getToolchain()
    {
        Toolchain tc = null;

        if ( jdkToolchain != null )
        {
            // Maven 3.3.1 has plugin execution scoped Toolchain Support
            try
            {
                Method getToolchainsMethod =
                    toolchainManager.getClass().getMethod( "getToolchains", MavenSession.class, String.class,
                                                           Map.class );

                @SuppressWarnings( "unchecked" )
                List<Toolchain> tcs =
                    (List<Toolchain>) getToolchainsMethod.invoke( toolchainManager, session, "jdk",
                                                                  jdkToolchain );

                if ( tcs != null && tcs.size() > 0 )
                {
                    tc = tcs.get( 0 );
                }
            }
            catch ( SecurityException | ReflectiveOperationException e )
            {
                // ignore
            }
        }

        if ( tc == null )
        {
            tc = toolchainManager.getToolchainFromBuildContext( "jdk", session );
        }

        return tc;
    }

    /**
     * Method to put the artifacts in the hashmap.
     *
     * @param compileArtifactMap the hashmap that will contain the artifacts
     * @param artifactList       the list of artifacts that will be put in the map
     * @throws MavenReportException if any
     */
    private void populateCompileArtifactMap( Map<String, Artifact> compileArtifactMap,
                                             Collection<Artifact> artifactList )
        throws MavenReportException
    {
        if ( artifactList == null )
        {
            return;
        }

        for ( Artifact newArtifact : artifactList )
        {
            File file = newArtifact.getFile();

            if ( file == null )
            {
                throw new MavenReportException(
                    "Error in plugin descriptor - " + "dependency was not resolved for artifact: "
                        + newArtifact.getGroupId() + ":" + newArtifact.getArtifactId() + ":"
                        + newArtifact.getVersion() );
            }

            if ( compileArtifactMap.get( newArtifact.getDependencyConflictId() ) != null )
            {
                Artifact oldArtifact = compileArtifactMap.get( newArtifact.getDependencyConflictId() );

                ArtifactVersion oldVersion = new DefaultArtifactVersion( oldArtifact.getVersion() );
                ArtifactVersion newVersion = new DefaultArtifactVersion( newArtifact.getVersion() );
                if ( newVersion.compareTo( oldVersion ) > 0 )
                {
                    compileArtifactMap.put( newArtifact.getDependencyConflictId(), newArtifact );
                }
            }
            else
            {
                compileArtifactMap.put( newArtifact.getDependencyConflictId(), newArtifact );
            }
        }
    }

    /**
     * Method that sets the bottom text that will be displayed on the bottom of the
     * javadocs.
     *
     * @return a String that contains the text that will be displayed at the bottom of the javadoc
     */
    private String getBottomText()
    {
        final String inceptionYear = project.getInceptionYear();

        // get Reproducible Builds outputTimestamp value
        final Calendar currentYearCal = Calendar.getInstance();
        final Date reproducibleDate = new MavenArchiver().parseOutputTimestamp( outputTimestamp );
        if ( reproducibleDate != null )
        {
            currentYearCal.setTime( reproducibleDate );
        }
        final String currentYear = String.valueOf( currentYearCal.get( Calendar.YEAR ) );

        String theBottom = StringUtils.replace( this.bottom, "{currentYear}", currentYear );

        if ( ( inceptionYear == null ) || inceptionYear.equals( currentYear ) )
        {
            theBottom = StringUtils.replace( theBottom, "{inceptionYear}&#x2013;", "" );
        }
        else
        {
            theBottom = StringUtils.replace( theBottom, "{inceptionYear}", inceptionYear );
        }

        if ( project.getOrganization() == null )
        {
            theBottom = StringUtils.replace( theBottom, " {organizationName}", "" );
        }
        else
        {
            if ( StringUtils.isNotEmpty( project.getOrganization().getName() ) )
            {
                if ( StringUtils.isNotEmpty( project.getOrganization().getUrl() ) )
                {
                    theBottom = StringUtils.replace( theBottom, "{organizationName}",
                                                     "<a href=\"" + project.getOrganization().getUrl() + "\">"
                                                         + project.getOrganization().getName() + "</a>" );
                }
                else
                {
                    theBottom =
                        StringUtils.replace( theBottom, "{organizationName}", project.getOrganization().getName() );
                }
            }
            else
            {
                theBottom = StringUtils.replace( theBottom, " {organizationName}", "" );
            }
        }

        return theBottom;
    }

    /**
     * Method to get the stylesheet path file to be used by the Javadoc Tool.
     * <br/>
     * If the {@link #stylesheetfile} is empty, return the file as String definded by {@link #stylesheet} value.
     * <br/>
     * If the {@link #stylesheetfile} is defined, return the file as String.
     * <br/>
     * Note: since 2.6, the {@link #stylesheetfile} could be a path from a resource in the project source
     * directories (i.e. <code>src/main/java</code>, <code>src/main/resources</code> or <code>src/main/javadoc</code>)
     * or from a resource in the Javadoc plugin dependencies.
     *
     * @param javadocOutputDirectory the output directory
     * @return the stylesheet file absolute path as String.
     * @see #getResource(List, String)
     */
    private Optional<File> getStylesheetFile( final File javadocOutputDirectory )
    {
        if ( StringUtils.isEmpty( stylesheetfile ) )
        {
            if ( "java".equalsIgnoreCase( stylesheet ) )
            {
                // use the default Javadoc tool stylesheet
                return Optional.empty();
            }

            // maven, see #copyDefaultStylesheet(File)
            return Optional.of( new File( javadocOutputDirectory, DEFAULT_CSS_NAME ) );
        }

        if ( new File( stylesheetfile ).exists() )
        {
            return Optional.of( new File( stylesheetfile ) );
        }

        return getResource( new File( javadocOutputDirectory, DEFAULT_CSS_NAME ), stylesheetfile );
    }
    
    private void addAddStyleSheets( List<String> arguments ) throws MavenReportException
    {
        if ( addStylesheets == null )
        {
            return;
        }
        
        for ( String addStylesheet : addStylesheets )
        {
            Optional<File> styleSheet = getAddStylesheet( getJavadocDirectory(), addStylesheet );
            
            if ( styleSheet.isPresent() )
            {
                addArgIfNotEmpty( arguments, "--add-stylesheet",
                                  JavadocUtil.quotedPathArgument( styleSheet.get().getAbsolutePath() ),
                                  JavaVersion.parse( "10" ) );
            }
        }
    }
    
    
    private Optional<File> getAddStylesheet( final File javadocOutputDirectory, final String stylesheet )
            throws MavenReportException
    {
        if ( StringUtils.isEmpty( stylesheet ) )
        {
            return Optional.empty();
        }
        
        File addstylesheetfile = new File( getJavadocDirectory(), stylesheet );
        if ( addstylesheetfile.exists() )
        {
            Optional<File> stylesheetfile = getStylesheetFile( javadocOutputDirectory );
            if ( stylesheetfile.isPresent() )
            {
                if ( stylesheetfile.get().getName().equals( addstylesheetfile.getName() ) )
                {
                    throw new MavenReportException( "additional stylesheet must have a different name "
                                                        + "than stylesheetfile: " + stylesheetfile.get().getName() );
                }
            }
            
            return Optional.of( addstylesheetfile );
        }

        throw new MavenReportException( "additional stylesheet file does not exist: " 
                                            + addstylesheetfile.getAbsolutePath() );
    }

    /**
     * Method to get the help file to be used by the Javadoc Tool.
     * <br/>
     * Since 2.6, the {@link #helpfile} could be a path from a resource in the project source
     * directories (i.e. <code>src/main/java</code>, <code>src/main/resources</code> or <code>src/main/javadoc</code>)
     * or from a resource in the Javadoc plugin dependencies.
     *
     * @param javadocOutputDirectory the output directory.
     * @return the help file absolute path as String.
     * @see #getResource(File, String)
     * @since 2.6
     */
    private Optional<File> getHelpFile( final File javadocOutputDirectory )
    {
        if ( StringUtils.isEmpty( helpfile ) )
        {
            return Optional.empty();
        }

        if ( new File( helpfile ).exists() )
        {
            return Optional.of( new File( helpfile ) );
        }

        return getResource( new File( javadocOutputDirectory, "help-doc.html" ), helpfile );
    }

    /**
     * Method to get the access level for the classes and members to be shown in the generated javadoc.
     * If the specified access level is not public, protected, package or private, the access level
     * is set to protected.
     *
     * @return the access level
     */
    private String getAccessLevel()
    {
        String accessLevel;
        if ( "public".equalsIgnoreCase( show ) || "protected".equalsIgnoreCase( show ) || "package".equalsIgnoreCase(
            show ) || "private".equalsIgnoreCase( show ) )
        {
            accessLevel = "-" + show;
        }
        else
        {
            if ( getLog().isErrorEnabled() )
            {
                getLog().error( "Unrecognized access level to show '" + show + "'. Defaulting to protected." );
            }
            accessLevel = "-protected";
        }

        return accessLevel;
    }

    /**
     * Method to get the path of the bootclass artifacts used in the <code>-bootclasspath</code> option.
     *
     * @return a string that contains bootclass path, separated by the System pathSeparator string
     *         (colon (<code>:</code>) on Solaris or semi-colon (<code>;</code>) on Windows).
     * @throws MavenReportException if any
     * @see File#pathSeparator
     */
    private String getBootclassPath()
        throws MavenReportException
    {
        Set<BootclasspathArtifact> bootclasspathArtifacts = collectBootClasspathArtifacts();

        List<String> bootclassPath = new ArrayList<>();
        for ( BootclasspathArtifact aBootclasspathArtifact : bootclasspathArtifacts )
        {
            if ( ( StringUtils.isNotEmpty( aBootclasspathArtifact.getGroupId() ) ) && ( StringUtils.isNotEmpty(
                aBootclasspathArtifact.getArtifactId() ) ) && ( StringUtils.isNotEmpty(
                aBootclasspathArtifact.getVersion() ) ) )
            {
                bootclassPath.addAll( getArtifactsAbsolutePath( aBootclasspathArtifact ) );
            }
        }

        bootclassPath = JavadocUtil.pruneFiles( bootclassPath );

        StringBuilder path = new StringBuilder();
        path.append( StringUtils.join( bootclassPath.iterator(), File.pathSeparator ) );

        if ( StringUtils.isNotEmpty( bootclasspath ) )
        {
            path.append( JavadocUtil.unifyPathSeparator( bootclasspath ) );
        }

        return path.toString();
    }

    /**
     * Method to get the path of the doclet artifacts used in the <code>-docletpath</code> option.
     * <p/>
     * Either docletArtifact or doclectArtifacts can be defined and used, not both, docletArtifact
     * takes precedence over doclectArtifacts. docletPath is always appended to any result path
     * definition.
     *
     * @return a string that contains doclet path, separated by the System pathSeparator string
     *         (colon (<code>:</code>) on Solaris or semi-colon (<code>;</code>) on Windows).
     * @throws MavenReportException if any
     * @see File#pathSeparator
     */
    private String getDocletPath()
        throws MavenReportException
    {
        Set<DocletArtifact> docletArtifacts = collectDocletArtifacts();
        List<String> pathParts = new ArrayList<>();

        for ( DocletArtifact docletArtifact : docletArtifacts )
        {
            if ( !isDocletArtifactEmpty( docletArtifact ) )
            {
                pathParts.addAll( getArtifactsAbsolutePath( docletArtifact ) );
            }
        }

        if ( !StringUtils.isEmpty( docletPath ) )
        {
            pathParts.add( JavadocUtil.unifyPathSeparator( docletPath ) );
        }

        String path = StringUtils.join( pathParts.iterator(), File.pathSeparator );

        if ( StringUtils.isEmpty( path ) && getLog().isWarnEnabled() )
        {
            getLog().warn( "No docletpath option was found. Please review <docletpath/> or <docletArtifact/>"
                               + " or <doclets/>." );
        }

        return path;
    }

    /**
     * Verify if a doclet artifact is empty or not
     *
     * @param aDocletArtifact could be null
     * @return <code>true</code> if aDocletArtifact or the groupId/artifactId/version of the doclet artifact is null,
     *         <code>false</code> otherwise.
     */
    private boolean isDocletArtifactEmpty( DocletArtifact aDocletArtifact )
    {
        if ( aDocletArtifact == null )
        {
            return true;
        }

        return StringUtils.isEmpty( aDocletArtifact.getGroupId() ) && StringUtils.isEmpty(
            aDocletArtifact.getArtifactId() ) && StringUtils.isEmpty( aDocletArtifact.getVersion() );
    }

    /**
     * Method to get the path of the taglet artifacts used in the <code>-tagletpath</code> option.
     *
     * @return a string that contains taglet path, separated by the System pathSeparator string
     *         (colon (<code>:</code>) on Solaris or semi-colon (<code>;</code>) on Windows).
     * @throws MavenReportException if any
     * @see File#pathSeparator
     */
    private String getTagletPath()
        throws MavenReportException
    {
        Set<TagletArtifact> tArtifacts = collectTagletArtifacts();
        Collection<String> pathParts = new ArrayList<>();

        for ( TagletArtifact tagletArtifact : tArtifacts )
        {
            if ( ( tagletArtifact != null ) && ( StringUtils.isNotEmpty( tagletArtifact.getGroupId() ) )
                && ( StringUtils.isNotEmpty( tagletArtifact.getArtifactId() ) ) && ( StringUtils.isNotEmpty(
                tagletArtifact.getVersion() ) ) )
            {
                pathParts.addAll( getArtifactsAbsolutePath( tagletArtifact ) );
            }
        }

        Set<Taglet> taglets = collectTaglets();
        for ( Taglet taglet : taglets )
        {
            if ( taglet == null )
            {
                continue;
            }

            if ( ( taglet.getTagletArtifact() != null ) && ( StringUtils.isNotEmpty(
                taglet.getTagletArtifact().getGroupId() ) ) && ( StringUtils.isNotEmpty(
                taglet.getTagletArtifact().getArtifactId() ) ) && ( StringUtils.isNotEmpty(
                taglet.getTagletArtifact().getVersion() ) ) )
            {
                pathParts.addAll( JavadocUtil.pruneFiles( getArtifactsAbsolutePath( taglet.getTagletArtifact() ) ) );
            }
            else if ( StringUtils.isNotEmpty( taglet.getTagletpath() ) )
            {
                for ( Path dir : JavadocUtil.pruneDirs( project, Collections.singletonList( taglet.getTagletpath() ) ) )
                {
                    pathParts.add( dir.toString()  );
                }
            }
        }

        StringBuilder path = new StringBuilder();
        path.append( StringUtils.join( pathParts.iterator(), File.pathSeparator ) );

        if ( StringUtils.isNotEmpty( tagletpath ) )
        {
            path.append( JavadocUtil.unifyPathSeparator( tagletpath ) );
        }

        return path.toString();
    }

    private Set<String> collectLinks()
        throws MavenReportException
    {
        Set<String> links = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getLinks() ) )
                    {
                        links.addAll( options.getLinks() );
                    }
                }
            }
        }

        if ( isNotEmpty( this.links ) )
        {
            links.addAll( this.links );
        }

        links.addAll( getDependenciesLinks() );

        return followLinks( links );
    }

    private Set<Group> collectGroups()
        throws MavenReportException
    {
        Set<Group> groups = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getGroups() ) )
                    {
                        groups.addAll( options.getGroups() );
                    }
                }
            }
        }

        if ( this.groups != null && this.groups.length > 0 )
        {
            groups.addAll( Arrays.asList( this.groups ) );
        }

        return groups;
    }

    private Set<ResourcesArtifact> collectResourcesArtifacts()
        throws MavenReportException
    {
        Set<ResourcesArtifact> result = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getResourcesArtifacts() ) )
                    {
                        result.addAll( options.getResourcesArtifacts() );
                    }
                }
            }
        }

        if ( this.resourcesArtifacts != null && this.resourcesArtifacts.length > 0 )
        {
            result.addAll( Arrays.asList( this.resourcesArtifacts ) );
        }

        return result;
    }

    private Set<BootclasspathArtifact> collectBootClasspathArtifacts()
        throws MavenReportException
    {
        Set<BootclasspathArtifact> result = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getBootclasspathArtifacts() ) )
                    {
                        result.addAll( options.getBootclasspathArtifacts() );
                    }
                }
            }
        }

        if ( this.bootclasspathArtifacts != null && this.bootclasspathArtifacts.length > 0 )
        {
            result.addAll( Arrays.asList( this.bootclasspathArtifacts ) );
        }

        return result;
    }

    private Set<OfflineLink> collectOfflineLinks()
        throws MavenReportException
    {
        Set<OfflineLink> result = new LinkedHashSet<>();

        OfflineLink javaApiLink = getDefaultJavadocApiLink();
        if ( javaApiLink != null )
        {
            result.add( javaApiLink );
        }

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getOfflineLinks() ) )
                    {
                        result.addAll( options.getOfflineLinks() );
                    }
                }
            }
        }

        if ( this.offlineLinks != null && this.offlineLinks.length > 0 )
        {
            result.addAll( Arrays.asList( this.offlineLinks ) );
        }

        return result;
    }

    private Set<Tag> collectTags()
        throws MavenReportException
    {
        Set<Tag> tags = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getTags() ) )
                    {
                        tags.addAll( options.getTags() );
                    }
                }
            }
        }

        if ( this.tags != null && this.tags.length > 0 )
        {
            tags.addAll( Arrays.asList( this.tags ) );
        }

        return tags;
    }

    private Set<TagletArtifact> collectTagletArtifacts()
        throws MavenReportException
    {
        Set<TagletArtifact> tArtifacts = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getTagletArtifacts() ) )
                    {
                        tArtifacts.addAll( options.getTagletArtifacts() );
                    }
                }
            }
        }

        if ( tagletArtifact != null )
        {
            tArtifacts.add( tagletArtifact );
        }

        if ( tagletArtifacts != null && tagletArtifacts.length > 0 )
        {
            tArtifacts.addAll( Arrays.asList( tagletArtifacts ) );
        }

        return tArtifacts;
    }

    private Set<DocletArtifact> collectDocletArtifacts()
        throws MavenReportException
    {
        Set<DocletArtifact> dArtifacts = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getDocletArtifacts() ) )
                    {
                        dArtifacts.addAll( options.getDocletArtifacts() );
                    }
                }
            }
        }

        if ( docletArtifact != null )
        {
            dArtifacts.add( docletArtifact );
        }

        if ( docletArtifacts != null && docletArtifacts.length > 0 )
        {
            dArtifacts.addAll( Arrays.asList( docletArtifacts ) );
        }

        return dArtifacts;
    }

    private Set<Taglet> collectTaglets()
        throws MavenReportException
    {
        Set<Taglet> result = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getTaglets() ) )
                    {
                        result.addAll( options.getTaglets() );
                    }
                }
            }
        }

        if ( taglets != null && taglets.length > 0 )
        {
            result.addAll( Arrays.asList( taglets ) );
        }

        return result;
    }

    /**
     * Return the Javadoc artifact path and its transitive dependencies path from the local repository
     *
     * @param javadocArtifact not null
     * @return a list of locale artifacts absolute path
     * @throws MavenReportException if any
     */
    private List<String> getArtifactsAbsolutePath( JavadocPathArtifact javadocArtifact )
        throws MavenReportException
    {
        if ( ( StringUtils.isEmpty( javadocArtifact.getGroupId() ) ) && ( StringUtils.isEmpty(
            javadocArtifact.getArtifactId() ) ) && ( StringUtils.isEmpty( javadocArtifact.getVersion() ) ) )
        {
            return Collections.emptyList();
        }

        List<String> path = new ArrayList<>();

        try
        {
            Artifact artifact = createAndResolveArtifact( javadocArtifact );
            path.add( artifact.getFile().getAbsolutePath() );

            DefaultDependableCoordinate coordinate = new DefaultDependableCoordinate();
            coordinate.setGroupId( javadocArtifact.getGroupId() );
            coordinate.setArtifactId( javadocArtifact.getArtifactId() );
            coordinate.setVersion( javadocArtifact.getVersion() );

            Iterable<ArtifactResult> deps =
                dependencyResolver.resolveDependencies( getProjectBuildingRequest( project ), coordinate,
                                                        ScopeFilter.including( "compile", "provided" ) );
            for ( ArtifactResult a : deps )
            {
                path.add( a.getArtifact().getFile().getAbsolutePath() );
            }

            return path;
        }
        catch ( ArtifactResolverException e )
        {
            throw new MavenReportException( "Unable to resolve artifact:" + javadocArtifact, e );
        }
        catch ( DependencyResolverException e )
        {
            throw new MavenReportException( "Unable to resolve dependencies for:" + javadocArtifact, e );
        }
    }

    /**
     * creates an {@link Artifact} representing the configured {@link JavadocPathArtifact} and resolves it.
     *
     * @param javadocArtifact the {@link JavadocPathArtifact} to resolve
     * @return a resolved {@link Artifact}
     * @throws ArtifactResolverException issue while resolving artifact
     */
    private Artifact createAndResolveArtifact( JavadocPathArtifact javadocArtifact )
        throws ArtifactResolverException
    {
        DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate();
        coordinate.setGroupId( javadocArtifact.getGroupId() );
        coordinate.setArtifactId( javadocArtifact.getArtifactId() );
        coordinate.setVersion( javadocArtifact.getVersion() );
        coordinate.setClassifier( javadocArtifact.getClassifier() );

        return artifactResolver.resolveArtifact( getProjectBuildingRequest( project ), coordinate ).getArtifact();
    }

    /**
     * Method that adds/sets the java memory parameters in the command line execution.
     *
     * @param cmd    the command line execution object where the argument will be added
     * @param arg    the argument parameter name
     * @param memory the JVM memory value to be set
     * @see JavadocUtil#parseJavadocMemory(String)
     */
    private void addMemoryArg( Commandline cmd, String arg, String memory )
    {
        if ( StringUtils.isNotEmpty( memory ) )
        {
            try
            {
                cmd.createArg().setValue( "-J" + arg + JavadocUtil.parseJavadocMemory( memory ) );
            }
            catch ( IllegalArgumentException e )
            {
                if ( getLog().isErrorEnabled() )
                {
                    getLog().error( "Malformed memory pattern for '" + arg + memory + "'. Ignore this option." );
                }
            }
        }
    }

    /**
     * Method that adds/sets the javadoc proxy parameters in the command line execution.
     *
     * @param cmd the command line execution object where the argument will be added
     */
    private void addProxyArg( Commandline cmd )
    {
        if ( settings == null || settings.getProxies().isEmpty() )
        {
            return;
        }

        Map<String, Proxy> activeProxies = new HashMap<>();

        for ( Proxy proxy : settings.getProxies() )
        {
            if ( proxy.isActive() )
            {
                String protocol = proxy.getProtocol();

                if ( !activeProxies.containsKey( protocol ) )
            {
                    activeProxies.put( protocol, proxy );
                }
            }
            }

        if ( activeProxies.containsKey( "https" ) )
        {
            Proxy httpsProxy = activeProxies.get( "https" );
            if ( StringUtils.isNotEmpty( httpsProxy.getHost() ) )
            {
                cmd.createArg().setValue( "-J-Dhttps.proxyHost=" + httpsProxy.getHost() );
                cmd.createArg().setValue( "-J-Dhttps.proxyPort=" + httpsProxy.getPort() );

                if ( StringUtils.isNotEmpty( httpsProxy.getNonProxyHosts() )
                     && ( !activeProxies.containsKey( "http" )
                          || StringUtils.isEmpty( activeProxies.get( "http" ).getNonProxyHosts() ) ) )
                {
                    cmd.createArg().setValue( "-J-Dhttp.nonProxyHosts=\""
                                              + httpsProxy.getNonProxyHosts().replace( "|", "^|" ) + "\"" );
                }
            }
        }

        if ( activeProxies.containsKey( "http" ) )
        {
            Proxy httpProxy = activeProxies.get( "http" );
            if ( StringUtils.isNotEmpty( httpProxy.getHost() ) )
            {
                cmd.createArg().setValue( "-J-Dhttp.proxyHost=" + httpProxy.getHost() );
                cmd.createArg().setValue( "-J-Dhttp.proxyPort=" + httpProxy.getPort() );

                if ( !activeProxies.containsKey( "https" ) )
            {
                    cmd.createArg().setValue( "-J-Dhttps.proxyHost=" + httpProxy.getHost() );
                    cmd.createArg().setValue( "-J-Dhttps.proxyPort=" + httpProxy.getPort() );
                }

                if ( StringUtils.isNotEmpty( httpProxy.getNonProxyHosts() ) )
                {
                    cmd.createArg().setValue( "-J-Dhttp.nonProxyHosts=\""
                                              + httpProxy.getNonProxyHosts().replace( "|", "^|" ) + "\"" );
                }
            }
        }

        // We bravely ignore FTP because no one (probably) uses FTP for Javadoc
    }

    /**
     * Get the path of the Javadoc tool executable depending the user entry or try to find it depending the OS
     * or the <code>java.home</code> system property or the <code>JAVA_HOME</code> environment variable.
     *
     * @return the path of the Javadoc tool
     * @throws IOException if not found
     */
    private String getJavadocExecutable()
        throws IOException
    {
        Toolchain tc = getToolchain();

        if ( tc != null )
        {
            getLog().info( "Toolchain in maven-javadoc-plugin: " + tc );
            if ( javadocExecutable != null )
            {
                getLog().warn( "Toolchains are ignored, 'javadocExecutable' parameter is set to " + javadocExecutable );
            }
            else
            {
                javadocExecutable = tc.findTool( "javadoc" );
            }
        }

        String javadocCommand = "javadoc" + ( SystemUtils.IS_OS_WINDOWS ? ".exe" : "" );

        File javadocExe;

        // ----------------------------------------------------------------------
        // The javadoc executable is defined by the user
        // ----------------------------------------------------------------------
        if ( StringUtils.isNotEmpty( javadocExecutable ) )
        {
            javadocExe = new File( javadocExecutable );

            if ( javadocExe.isDirectory() )
            {
                javadocExe = new File( javadocExe, javadocCommand );
            }

            if ( SystemUtils.IS_OS_WINDOWS && javadocExe.getName().indexOf( '.' ) < 0 )
            {
                javadocExe = new File( javadocExe.getPath() + ".exe" );
            }

            if ( !javadocExe.isFile() )
            {
                throw new IOException( "The javadoc executable '" + javadocExe
                    + "' doesn't exist or is not a file. Verify the <javadocExecutable/> parameter." );
            }

            return javadocExe.getAbsolutePath();
        }
        // CHECKSTYLE_OFF: LineLength
        // ----------------------------------------------------------------------
        // Try to find javadocExe from System.getProperty( "java.home" )
        // "java.home" is the "Installation directory for Java Runtime
        // Environment (JRE)" used to run this code. I.e. it is the parent of
        // the directory containing the `java` command used to start this
        // application. It does not necessarily have any relation to the
        // environment variable JAVA_HOME.
        //
        // In Java 8 and below the JRE is separate from the JDK. When
        // installing the JDK to my-dir/ the javadoc command is installed in
        // my-dir/bin/javadoc, the JRE is installed to my-dir/jre, and hence
        // the java command is installed to my-dir/jre/bin/java. In this
        // configuration "java.home" is mydir/jre/, threfore the relative path
        // to the javadoc command is ../bin/javadoc.
        //
        // In Java 9 and above the JRE is no longer in a subdirectory of the
        // JDK, i.e. the JDK and the JDK are merged. In this case the java
        // command is installed to my-dir/bin/java along side the javadoc
        // command. So the relative path from "java.home" to the javadoc
        // command is bin/javadoc.
        //
        // References
        //
        // "System Properties" in "The Java Tutorials"
        // https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
        //
        // "Changes to the Installed JDK/JRE Image" in "JDK 9 Migration Guide"
        // https://docs.oracle.com/javase/9/migrate/toc.htm?xd_co_f=122a7174-9132-4acd-b122-fac02f8c4fef#JSMIG-GUID-D867DCCC-CEB5-4AFA-9D11-9C62B7A3FAB1
        //
        // "JEP 220: Modular Run-Time Images"
        // http://openjdk.java.net/jeps/220
        // ----------------------------------------------------------------------
        // For IBM's JDK 1.2
        // CHECKSTYLE_ON: LineLength
        if ( SystemUtils.IS_OS_AIX )
        {
            javadocExe =
                new File( SystemUtils.getJavaHome() + File.separator + ".." + File.separator + "sh", javadocCommand );
        }
        // For Apple's JDK 1.6.x (and older?) on Mac OSX
        // CHECKSTYLE_OFF: MagicNumber
        else if ( SystemUtils.IS_OS_MAC_OSX && !JavaVersion.JAVA_SPECIFICATION_VERSION.isAtLeast( "1.7" ) )
        // CHECKSTYLE_ON: MagicNumber
        {
            javadocExe = new File( SystemUtils.getJavaHome() + File.separator + "bin", javadocCommand );
        }
        else if ( isJavaVersionAtLeast( org.apache.commons.lang3.JavaVersion.JAVA_9 ) )
        {
            javadocExe =
                new File( SystemUtils.getJavaHome() + File.separator + "bin", javadocCommand );
        }
        else
        {
            // Java <= 8
            javadocExe =
                new File( SystemUtils.getJavaHome() + File.separator + ".." + File.separator + "bin", javadocCommand );
        }

        // ----------------------------------------------------------------------
        // Try to find javadocExe from JAVA_HOME environment variable
        // ----------------------------------------------------------------------
        if ( !javadocExe.exists() || !javadocExe.isFile() )
        {
            Properties env = CommandLineUtils.getSystemEnvVars();
            String javaHome = env.getProperty( "JAVA_HOME" );
            if ( StringUtils.isEmpty( javaHome ) )
            {
                throw new IOException( "The environment variable JAVA_HOME is not correctly set." );
            }
            if ( ( !new File( javaHome ).getCanonicalFile().exists() )
                || ( new File( javaHome ).getCanonicalFile().isFile() ) )
            {
                throw new IOException( "The environment variable JAVA_HOME=" + javaHome
                    + " doesn't exist or is not a valid directory." );
            }

            javadocExe = new File( javaHome + File.separator + "bin", javadocCommand );
        }

        if ( !javadocExe.getCanonicalFile().exists() || !javadocExe.getCanonicalFile().isFile() )
        {
            throw new IOException( "The javadoc executable '" + javadocExe
                + "' doesn't exist or is not a file. Verify the JAVA_HOME environment variable." );
        }

        return javadocExe.getAbsolutePath();
    }

    /**
     * Set a new value for <code>javadocRuntimeVersion</code>
     *
     * @param jExecutable not null
     * @throws MavenReportException if not found
     * @see JavadocUtil#getJavadocVersion(File)
     */
    private void setFJavadocVersion( File jExecutable )
        throws MavenReportException
    {
        JavaVersion jVersion;
        try
        {
            jVersion = JavadocUtil.getJavadocVersion( jExecutable );
        }
        catch ( IOException | CommandLineException | IllegalArgumentException e )
        {
            if ( getLog().isWarnEnabled() )
            {
                getLog().warn( "Unable to find the javadoc version: " + e.getMessage() );
                getLog().warn( "Using the Java version instead of, i.e. " + JAVA_VERSION );
            }
            jVersion = JAVA_VERSION;
        }

        if ( StringUtils.isNotEmpty( javadocVersion ) )
        {
            try
            {
                javadocRuntimeVersion = JavaVersion.parse( javadocVersion );
            }
            catch ( NumberFormatException e )
            {
                throw new MavenReportException( "Unable to parse javadoc version: " + e.getMessage(), e );
            }

            if ( javadocRuntimeVersion.compareTo( jVersion ) != 0 && getLog().isWarnEnabled() )
            {
                getLog().warn( "Are you sure about the <javadocVersion/> parameter? It seems to be " + jVersion );
            }
        }
        else
        {
            javadocRuntimeVersion = jVersion;
        }
    }

    /**
     * Is the Javadoc version at least the requested version.
     *
     * @param requiredVersion the required version, for example 1.5f
     * @return <code>true</code> if the javadoc version is equal or greater than the
     *         required version
     */
    private boolean isJavaDocVersionAtLeast( JavaVersion requiredVersion )
    {
        return JAVA_VERSION.compareTo( requiredVersion ) >= 0;
    }

    /**
     * Convenience method to add an argument to the <code>command line</code>
     * conditionally based on the given flag.
     *
     * @param arguments a list of arguments, not null
     * @param b         the flag which controls if the argument is added or not.
     * @param value     the argument value to be added.
     */
    private void addArgIf( List<String> arguments, boolean b, String value )
    {
        if ( b )
        {
            arguments.add( value );
        }
    }

    /**
     * Convenience method to add an argument to the <code>command line</code>
     * regarding the requested Java version.
     *
     * @param arguments           a list of arguments, not null
     * @param b                   the flag which controls if the argument is added or not.
     * @param value               the argument value to be added.
     * @param requiredJavaVersion the required Java version, for example 1.31f or 1.4f
     * @see #addArgIf(List, boolean, String)
     * @see #isJavaDocVersionAtLeast(JavaVersion)
     */
    private void addArgIf( List<String> arguments, boolean b, String value, JavaVersion requiredJavaVersion )
    {
        if ( b )
        {
            if ( isJavaDocVersionAtLeast( requiredJavaVersion ) )
            {
                addArgIf( arguments, true, value );
            }
            else
            {
                if ( getLog().isWarnEnabled() )
                {
                    getLog().warn( value + " option is not supported on Java version < " + requiredJavaVersion
                                       + ". Ignore this option." );
                }
            }
        }
    }

    /**
     * Convenience method to add an argument to the <code>command line</code>
     * if the the value is not null or empty.
     * <p/>
     * Moreover, the value could be comma separated.
     *
     * @param arguments a list of arguments, not null
     * @param key       the argument name.
     * @param value     the argument value to be added.
     * @see #addArgIfNotEmpty(List, String, String, boolean)
     */
    private void addArgIfNotEmpty( List<String> arguments, String key, String value )
    {
        addArgIfNotEmpty( arguments, key, value, false );
    }

    /**
     * Convenience method to add an argument to the <code>command line</code>
     * if the the value is not null or empty.
     * <p/>
     * Moreover, the value could be comma separated.
     *
     * @param arguments           a list of arguments, not null
     * @param key                 the argument name.
     * @param value               the argument value to be added.
     * @param repeatKey           repeat or not the key in the command line
     * @param splitValue          if <code>true</code> given value will be tokenized by comma
     * @param requiredJavaVersion the required Java version, for example 1.31f or 1.4f
     * @see #addArgIfNotEmpty(List, String, String, boolean, boolean)
     * @see #isJavaDocVersionAtLeast(JavaVersion)
     */
    private void addArgIfNotEmpty( List<String> arguments, String key, String value, boolean repeatKey,
                                   boolean splitValue, JavaVersion requiredJavaVersion )
    {
        if ( StringUtils.isNotEmpty( value ) )
        {
            if ( isJavaDocVersionAtLeast( requiredJavaVersion ) )
            {
                addArgIfNotEmpty( arguments, key, value, repeatKey, splitValue );
            }
            else
            {
                if ( getLog().isWarnEnabled() )
                {
                    getLog().warn( key + " option is not supported on Java version < " + requiredJavaVersion
                                       + ". Ignore this option." );
                }
            }
        }
    }

    /**
     * Convenience method to add an argument to the <code>command line</code>
     * if the the value is not null or empty.
     * <p/>
     * Moreover, the value could be comma separated.
     *
     * @param arguments  a list of arguments, not null
     * @param key        the argument name.
     * @param value      the argument value to be added.
     * @param repeatKey  repeat or not the key in the command line
     * @param splitValue if <code>true</code> given value will be tokenized by comma
     */
    private void addArgIfNotEmpty( List<String> arguments, String key, String value, boolean repeatKey,
                                   boolean splitValue )
    {
        if ( StringUtils.isNotEmpty( value ) )
        {
            if ( StringUtils.isNotEmpty( key ) )
            {
                arguments.add( key );
            }

            if ( splitValue )
            {
                StringTokenizer token = new StringTokenizer( value, "," );
                while ( token.hasMoreTokens() )
                {
                    String current = token.nextToken().trim();

                    if ( StringUtils.isNotEmpty( current ) )
                    {
                        arguments.add( current );

                        if ( token.hasMoreTokens() && repeatKey )
                        {
                            arguments.add( key );
                        }
                    }
                }
            }
            else
            {
                arguments.add( value );
            }
        }
    }

    /**
     * Convenience method to add an argument to the <code>command line</code>
     * if the the value is not null or empty.
     * <p/>
     * Moreover, the value could be comma separated.
     *
     * @param arguments a list of arguments, not null
     * @param key       the argument name.
     * @param value     the argument value to be added.
     * @param repeatKey repeat or not the key in the command line
     */
    private void addArgIfNotEmpty( List<String> arguments, String key, String value, boolean repeatKey )
    {
        addArgIfNotEmpty( arguments, key, value, repeatKey, true );
    }

    /**
     * Convenience method to add an argument to the <code>command line</code>
     * regarding the requested Java version.
     *
     * @param arguments           a list of arguments, not null
     * @param key                 the argument name.
     * @param value               the argument value to be added.
     * @param requiredJavaVersion the required Java version, for example 1.31f or 1.4f
     * @see #addArgIfNotEmpty(List, String, String, JavaVersion, boolean)
     */
    private void addArgIfNotEmpty( List<String> arguments, String key, String value,
                                   JavaVersion requiredJavaVersion )
    {
        addArgIfNotEmpty( arguments, key, value, requiredJavaVersion, false );
    }

    /**
     * Convenience method to add an argument to the <code>command line</code>
     * regarding the requested Java version.
     *
     * @param arguments           a list of arguments, not null
     * @param key                 the argument name.
     * @param value               the argument value to be added.
     * @param requiredJavaVersion the required Java version, for example 1.31f or 1.4f
     * @param repeatKey           repeat or not the key in the command line
     * @see #addArgIfNotEmpty(List, String, String)
     * @see #isJavaDocVersionAtLeast
     */
    private void addArgIfNotEmpty( List<String> arguments, String key, String value, JavaVersion requiredJavaVersion,
                                   boolean repeatKey )
    {
        if ( StringUtils.isNotEmpty( value ) )
        {
            if ( isJavaDocVersionAtLeast( requiredJavaVersion ) )
            {
                addArgIfNotEmpty( arguments, key, value, repeatKey );
            }
            else
            {
                if ( getLog().isWarnEnabled() )
                {
                    getLog().warn( key + " option is not supported on Java version < " + requiredJavaVersion );
                }
            }
        }
    }

    /**
     * Convenience method to process {@link #offlineLinks} values as individual <code>-linkoffline</code>
     * javadoc options.
     * <br/>
     * If {@link #detectOfflineLinks}, try to add javadoc apidocs according Maven conventions for all modules given
     * in the project.
     *
     * @param arguments a list of arguments, not null
     * @throws MavenReportException if any
     * @see #offlineLinks
     * @see #getModulesLinks()
     * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#package-list">package-list spec</a>
     */
    private void addLinkofflineArguments( List<String> arguments, Set<OfflineLink> offlineLinksList )
        throws MavenReportException
    {
        for ( OfflineLink offlineLink : offlineLinksList )
        {
            String url = offlineLink.getUrl();
            if ( StringUtils.isEmpty( url ) )
            {
                continue;
            }
            url = cleanUrl( url );

            String location = offlineLink.getLocation();
            if ( StringUtils.isEmpty( location ) )
            {
                continue;
            }
            if ( isValidJavadocLink( location, false ) )
            {
                addArgIfNotEmpty( arguments, "-linkoffline",
                                  JavadocUtil.quotedPathArgument( url ) + " " + JavadocUtil.quotedPathArgument(
                                      location ), true );
            }
        }
    }

    private Set<OfflineLink> getLinkofflines() throws MavenReportException
    {
        Set<OfflineLink> offlineLinksList = collectOfflineLinks();

        offlineLinksList.addAll( getModulesLinks() );

        return offlineLinksList;
    }

    /**
     * Convenience method to process {@link #links} values as individual <code>-link</code> javadoc options.
     * If {@link #detectLinks}, try to add javadoc apidocs according Maven conventions for all dependencies given
     * in the project.
     * <br/>
     * According the Javadoc documentation, all defined link should have <code>${link}/package-list</code> fetchable.
     * <br/>
     * <b>Note</b>: when a link is not fetchable:
     * <ul>
     * <li>Javadoc 1.4 and less throw an exception</li>
     * <li>Javadoc 1.5 and more display a warning</li>
     * </ul>
     *
     * @param arguments a list of arguments, not null
     * @throws MavenReportException issue while generating report
     * @see #detectLinks
     * @see #getDependenciesLinks()
     * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#package-list">package-list spec</a>
     */
    private void addLinkArguments( List<String> arguments )
        throws MavenReportException
    {
        Set<String> links = collectLinks();

        for ( String link : links )
        {
            if ( StringUtils.isEmpty( link ) )
            {
                continue;
            }

            if ( isOffline && !link.startsWith( "file:" ) )
            {
                continue;
            }

            while ( link.endsWith( "/" ) )
            {
                link = link.substring( 0, link.lastIndexOf( "/" ) );
            }

            addArgIfNotEmpty( arguments, "-link", JavadocUtil.quotedPathArgument( link ), true, false );
        }
    }

    /**
     * Coppy all resources to the output directory
     *
     * @param javadocOutputDirectory not null
     * @throws MavenReportException if any
     * @see #copyDefaultStylesheet(File)
     * @see #copyJavadocResources(File)
     * @see #copyAdditionalJavadocResources(File)
     */
    private void copyAllResources( File javadocOutputDirectory )
        throws MavenReportException
    {
        // ----------------------------------------------------------------------
        // Copy default resources
        // ----------------------------------------------------------------------

        try
        {
            copyDefaultStylesheet( javadocOutputDirectory );
        }
        catch ( IOException e )
        {
            throw new MavenReportException( "Unable to copy default stylesheet: " + e.getMessage(), e );
        }

        // ----------------------------------------------------------------------
        // Copy javadoc resources
        // ----------------------------------------------------------------------

        if ( docfilessubdirs )
        {
            /*
             * Workaround since -docfilessubdirs doesn't seem to be used correctly by the javadoc tool
             * (see other note about -sourcepath). Take care of the -excludedocfilessubdir option.
             */
            try
            {
                copyJavadocResources( javadocOutputDirectory );
            }
            catch ( IOException e )
            {
                throw new MavenReportException( "Unable to copy javadoc resources: " + e.getMessage(), e );
            }
        }

        // ----------------------------------------------------------------------
        // Copy additional javadoc resources in artifacts
        // ----------------------------------------------------------------------

        copyAdditionalJavadocResources( javadocOutputDirectory );
    }

    /**
     * Copies the {@link #DEFAULT_CSS_NAME} css file from the current class
     * loader to the <code>outputDirectory</code> only if {@link #stylesheetfile} is empty and
     * {@link #stylesheet} is equals to <code>maven</code>.
     *
     * @param anOutputDirectory the output directory
     * @throws java.io.IOException if any
     * @see #DEFAULT_CSS_NAME
     * @see JavadocUtil#copyResource(java.net.URL, java.io.File)
     */
    private void copyDefaultStylesheet( File anOutputDirectory )
        throws IOException
    {
        if ( StringUtils.isNotEmpty( stylesheetfile ) )
        {
            return;
        }

        if ( !stylesheet.equalsIgnoreCase( "maven" ) )
        {
            return;
        }

        URL url = getClass().getClassLoader().getResource( RESOURCE_CSS_DIR + "/" + DEFAULT_CSS_NAME );
        File outFile = new File( anOutputDirectory, DEFAULT_CSS_NAME );
        JavadocUtil.copyResource( url, outFile );
    }

    /**
     * Method that copy all <code>doc-files</code> directories from <code>javadocDirectory</code> of
     * the current project or of the projects in the reactor to the <code>outputDirectory</code>.
     *
     * @param anOutputDirectory the output directory
     * @throws java.io.IOException if any
     * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.2.html#docfiles">Reference
     *      Guide, Copies new "doc-files" directory for holding images and examples</a>
     * @see #docfilessubdirs
     */
    private void copyJavadocResources( File anOutputDirectory )
        throws IOException
    {
        if ( anOutputDirectory == null || !anOutputDirectory.exists() )
        {
            throw new IOException( "The outputDirectory " + anOutputDirectory + " doesn't exists." );
        }

        if ( includeDependencySources )
        {
            resolveDependencyBundles();
            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    File dir = bundle.getResourcesDirectory();
                    JavadocOptions options = bundle.getOptions();
                    if ( dir != null && dir.isDirectory() )
                    {
                        JavadocUtil.copyJavadocResources( anOutputDirectory, dir, options == null
                            ? null
                            : options.getExcludedDocfilesSubdirs() );
                    }
                }
            }
        }

        if ( getJavadocDirectory() != null )
        {
            JavadocUtil.copyJavadocResources( anOutputDirectory, getJavadocDirectory(), excludedocfilessubdir );
        }

        if ( isAggregator() )
        {
            for ( MavenProject subProject : getAggregatedProjects()  )
            {
                if ( subProject != project && getJavadocDirectory() != null )
                {
                    String javadocDirRelative =
                        PathUtils.toRelative( project.getBasedir(), getJavadocDirectory().getAbsolutePath() );
                    File javadocDir = new File( subProject.getBasedir(), javadocDirRelative );
                    JavadocUtil.copyJavadocResources( anOutputDirectory, javadocDir, excludedocfilessubdir );
                }
            }
        }
    }

    private synchronized void resolveDependencyBundles()
        throws IOException
    {
        if ( dependencyJavadocBundles == null )
        {
            dependencyJavadocBundles =
                resourceResolver.resolveDependencyJavadocBundles( getDependencySourceResolverConfig() );
            if ( dependencyJavadocBundles == null )
            {
                dependencyJavadocBundles = new ArrayList<>();
            }
        }
    }

    /**
     * Method that copy additional Javadoc resources from given artifacts.
     *
     * @param anOutputDirectory the output directory
     * @throws MavenReportException if any
     * @see #resourcesArtifacts
     */
    private void copyAdditionalJavadocResources( File anOutputDirectory )
        throws MavenReportException
    {
        Set<ResourcesArtifact> resourcesArtifacts = collectResourcesArtifacts();
        if ( isEmpty( resourcesArtifacts ) )
        {
            return;
        }

        UnArchiver unArchiver;
        try
        {
            unArchiver = archiverManager.getUnArchiver( "jar" );
        }
        catch ( NoSuchArchiverException e )
        {
            throw new MavenReportException(
                "Unable to extract resources artifact. " + "No archiver for 'jar' available.", e );
        }

        for ( ResourcesArtifact item : resourcesArtifacts )
        {
            Artifact artifact;
            try
            {
                artifact = createAndResolveArtifact( item );
            }
            catch ( ArtifactResolverException e )
            {
                throw new MavenReportException( "Unable to resolve artifact:" + item, e );
            }

            unArchiver.setSourceFile( artifact.getFile() );
            unArchiver.setDestDirectory( anOutputDirectory );
            // remove the META-INF directory from resource artifact
            IncludeExcludeFileSelector[] selectors =
                new IncludeExcludeFileSelector[]{ new IncludeExcludeFileSelector() };
            selectors[0].setExcludes( new String[]{ "META-INF/**" } );
            unArchiver.setFileSelectors( selectors );

            getLog().info( "Extracting contents of resources artifact: " + artifact.getArtifactId() );
            try
            {
                unArchiver.extract();
            }
            catch ( ArchiverException e )
            {
                throw new MavenReportException(
                    "Extraction of resources failed. Artifact that failed was: " + artifact.getArtifactId(), e );
            }
        }
    }

    /**
     * @param sourcePaths could be null
     * @return the list of package names for files in the sourcePaths
     */
    private List<String> getPackageNames( Map<Path, Collection<String>> sourcePaths )
    {
        List<String> returnList = new ArrayList<>();

        if ( !StringUtils.isEmpty( sourcepath ) )
        {
            return returnList;
        }

        for ( Entry<Path, Collection<String>> currentPathEntry : sourcePaths.entrySet() )
        {
            for ( String currentFile : currentPathEntry.getValue() )
            {
                /*
                 * Remove the miscellaneous files
                 * https://docs.oracle.com/javase/1.4.2/docs/tooldocs/solaris/javadoc.html#unprocessed
                 */
                if ( currentFile.contains( "doc-files" ) )
                {
                    continue;
                }

                int lastIndexOfSeparator = currentFile.lastIndexOf( "/" );
                if ( lastIndexOfSeparator != -1 )
                {
                    String packagename = currentFile.substring( 0, lastIndexOfSeparator ).replace( '/', '.' );

                    if ( !returnList.contains( packagename ) )
                    {
                        returnList.add( packagename );
                    }
                }
            }
        }

        return returnList;
    }

    /**
     * @param allSourcePaths     not null, containing absolute and relative paths
     * @return a list of exported package names for files in allSourcePaths
     * @throws MavenReportException if any
     * @see #getFiles
     * @see #getSourcePaths()
     */
    private Collection<String> getPackageNamesRespectingJavaModules( Collection<JavadocModule> javadocModules )
            throws MavenReportException
    {
        if ( !StringUtils.isEmpty( sourcepath ) )
        {
            return Collections.emptyList();
        }

        Set<String> returnList = new LinkedHashSet<>();
        for ( JavadocModule javadocModule  : javadocModules )
        {
            Collection<Path> artifactSourcePaths = javadocModule.getSourcePaths();
            Set<String> exportedPackages = new HashSet<>();
            boolean exportAllPackages;
            ResolvePathResult resolvedPath = getResolvePathResult( javadocModule.getArtifactFile() );
            if ( resolvedPath != null && resolvedPath.getModuleNameSource() == ModuleNameSource.MODULEDESCRIPTOR )
            {
                Set<JavaModuleDescriptor.JavaExports> exports = resolvedPath.getModuleDescriptor().exports();
                if ( exports.isEmpty() )
                {
                    continue;
                }
                for ( JavaModuleDescriptor.JavaExports export : exports )
                {
                    exportedPackages.add( export.source() );
                }
                exportAllPackages = false;
            }
            else
            {
                exportAllPackages = true;
            }

            for ( Map.Entry<Path, Collection<String>> currentPathEntry : getFiles( artifactSourcePaths ).entrySet() )
            {
                for ( String currentFile : currentPathEntry.getValue() )
                {
                    /*
                     * Remove the miscellaneous files
                     * https://docs.oracle.com/javase/1.4.2/docs/tooldocs/solaris/javadoc.html#unprocessed
                     */
                    if ( currentFile.contains( "doc-files" ) )
                    {
                        continue;
                    }

                    int lastIndexOfSeparator = currentFile.lastIndexOf( '/' );
                    if ( lastIndexOfSeparator != -1 )
                    {
                        String packagename =
                            currentFile.substring( 0, lastIndexOfSeparator ).replace( '/', '.' );

                        if ( exportAllPackages || exportedPackages.contains( packagename ) )
                        {
                            returnList.add( packagename );
                        }
                    }
                }
            }
        }

        return returnList;
    }

    /**
     * @param sourcePaths could be null
     * @return a list files with unnamed package names for files in the sourcePaths
     */
    private List<String> getFilesWithUnnamedPackages( Map<Path, Collection<String>> sourcePaths )
    {
        List<String> returnList = new ArrayList<>();

        if ( !StringUtils.isEmpty( sourcepath ) )
        {
            return returnList;
        }

        for ( Entry<Path, Collection<String>> currentPathEntry : sourcePaths.entrySet() )
        {
            Path currentSourcePath = currentPathEntry.getKey();

            for ( String currentFile : currentPathEntry.getValue() )
            {
                /*
                 * Remove the miscellaneous files
                 * https://docs.oracle.com/javase/1.4.2/docs/tooldocs/solaris/javadoc.html#unprocessed
                 */
                if ( currentFile.contains( "doc-files" ) )
                {
                    continue;
                }

                if ( currentFile.indexOf( File.separatorChar ) == -1 )
                {
                    returnList.add( currentSourcePath.resolve( currentFile ).toAbsolutePath().toString() );
                }
            }
        }

        return returnList;
    }

    /**
     * Either return only the module descriptor or all sourcefiles per sourcepath
     * @param sourcePaths could be null
     * @return a list of files
     */
    private List<String> getSpecialFiles( Map<Path, Collection<String>> sourcePaths )
    {
        if ( !StringUtils.isEmpty( sourcepath ) )
        {
            return new ArrayList<>();
        }

        boolean containsModuleDescriptor = false;
        for ( Collection<String> sourcepathFiles : sourcePaths.values() )
        {
            containsModuleDescriptor = sourcepathFiles.contains( "module-info.java" );
            if ( containsModuleDescriptor )
            {
                break;
            }
        }

        if ( containsModuleDescriptor )
        {
            return getModuleSourcePathFiles( sourcePaths );
        }
        else
        {
            return getFilesWithUnnamedPackages( sourcePaths );
        }
    }

    private List<String> getModuleSourcePathFiles( Map<Path, Collection<String>> sourcePaths )
    {
        List<String> returnList = new ArrayList<>();

        for ( Entry<Path, Collection<String>> currentPathEntry : sourcePaths.entrySet() )
        {
            Path currentSourcePath = currentPathEntry.getKey();
            if ( currentPathEntry.getValue().contains( "module-info.java" ) )
            {
                returnList.add( currentSourcePath.resolve( "module-info.java" ).toAbsolutePath().toString() );
            }
            else
            {
                for ( String currentFile : currentPathEntry.getValue() )
                {
                    /*
                     * Remove the miscellaneous files
                     * https://docs.oracle.com/javase/1.4.2/docs/tooldocs/solaris/javadoc.html#unprocessed
                     */
                    if ( currentFile.contains( "doc-files" ) )
                    {
                        continue;
                    }

                    returnList.add( currentSourcePath.resolve( currentFile ).toAbsolutePath().toString() );
                }
            }
        }
        return returnList;
    }

    /**
     * Generate an <code>options</code> file for all options and arguments and add the <code>@options</code> in the
     * command line.
     *
     * @param cmd                    not null
     * @param arguments              not null
     * @param javadocOutputDirectory not null
     * @throws MavenReportException if any
     * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#argumentfiles">
     *      Reference Guide, Command line argument files</a>
     * @see #OPTIONS_FILE_NAME
     */
    private void addCommandLineOptions( Commandline cmd, List<String> arguments, File javadocOutputDirectory )
        throws MavenReportException
    {
        File optionsFile = new File( javadocOutputDirectory, OPTIONS_FILE_NAME );

        StringBuilder options = new StringBuilder();
        options.append( StringUtils.join( arguments.iterator(),
                                          SystemUtils.LINE_SEPARATOR ) );

        Charset outputFileEncoding;
        if ( JAVA_VERSION.isAtLeast( "9" ) && JAVA_VERSION.isBefore( "12" ) )
        {
            outputFileEncoding = StandardCharsets.UTF_8;
        }
        else
        {
            outputFileEncoding = Charset.defaultCharset();
        }
        try
        {
            Files.write( optionsFile.toPath(), Collections.singleton( options ), outputFileEncoding );
        }
        catch ( IOException e )
        {
            throw new MavenReportException(
                "Unable to write '" + optionsFile.getName() + "' temporary file for command execution", e );
        }

        cmd.createArg().setValue( "@" + OPTIONS_FILE_NAME );
    }

    /**
     * Generate a file called <code>argfile</code> (or <code>files</code>, depending the JDK) to hold files and add
     * the <code>@argfile</code> (or <code>@file</code>, depending the JDK) in the command line.
     *
     * @param cmd                    not null
     * @param javadocOutputDirectory not null
     * @param files                  not null
     * @throws MavenReportException if any
     * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#argumentfiles">
     *      Reference Guide, Command line argument files
     *      </a>
     * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#runningjavadoc">
     *      What s New in Javadoc 1.4
     *      </a>
     * @see #isJavaDocVersionAtLeast(JavaVersion)
     * @see #ARGFILE_FILE_NAME
     * @see #FILES_FILE_NAME
     */
    private void addCommandLineArgFile( Commandline cmd, File javadocOutputDirectory, List<String> files )
        throws MavenReportException
    {
        File argfileFile;
        if ( JAVA_VERSION.compareTo( SINCE_JAVADOC_1_4 ) >= 0 )
        {
            argfileFile = new File( javadocOutputDirectory, ARGFILE_FILE_NAME );
            cmd.createArg().setValue( "@" + ARGFILE_FILE_NAME );
        }
        else
        {
            argfileFile = new File( javadocOutputDirectory, FILES_FILE_NAME );
            cmd.createArg().setValue( "@" + FILES_FILE_NAME );
        }

        List<String> quotedFiles = new ArrayList<>( files.size() );
        for ( String file : files )
        {
            quotedFiles.add( JavadocUtil.quotedPathArgument( file ) );
        }

        Charset cs;
        if ( JavaVersion.JAVA_SPECIFICATION_VERSION.isAtLeast( "9" )
            && JavaVersion.JAVA_SPECIFICATION_VERSION.isBefore( "12" ) )
        {
            cs = StandardCharsets.UTF_8;
        }
        else
        {
            cs = Charset.defaultCharset();
        }

        try
        {
            Files.write( argfileFile.toPath(), quotedFiles, cs );
        }
        catch ( IOException e )
        {
            throw new MavenReportException(
                "Unable to write '" + argfileFile.getName() + "' temporary file for command execution", e );
        }
    }

    /**
     * Generate a file called <code>packages</code> to hold all package names and add the <code>@packages</code> in
     * the command line.
     *
     * @param cmd                    not null
     * @param javadocOutputDirectory not null
     * @param packageNames           not null
     * @throws MavenReportException if any
     * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#argumentfiles">
     *      Reference Guide, Command line argument files</a>
     * @see #PACKAGES_FILE_NAME
     */
    private void addCommandLinePackages( Commandline cmd, File javadocOutputDirectory, Collection<String> packageNames )
        throws MavenReportException
    {
        File packagesFile = new File( javadocOutputDirectory, PACKAGES_FILE_NAME );

        try
        {
            FileUtils.fileWrite( packagesFile.getAbsolutePath(), null /* platform encoding */,
                                 StringUtils.join( packageNames.iterator(), SystemUtils.LINE_SEPARATOR ) );
        }
        catch ( IOException e )
        {
            throw new MavenReportException(
                "Unable to write '" + packagesFile.getName() + "' temporary file for command execution", e );
        }

        cmd.createArg().setValue( "@" + PACKAGES_FILE_NAME );
    }

    /**
     * Checks for the validity of the Javadoc options used by the user.
     *
     * @throws MavenReportException if error
     */
    private void validateJavadocOptions()
        throws MavenReportException
    {
        // encoding
        if ( StringUtils.isNotEmpty( getEncoding() ) && !JavadocUtil.validateEncoding( getEncoding() ) )
        {
            throw new MavenReportException( "Unsupported option <encoding/> '" + getEncoding() + "'" );
        }

        // locale
        if ( StringUtils.isNotEmpty( this.locale ) )
        {
            StringTokenizer tokenizer = new StringTokenizer( this.locale, "_" );
            final int maxTokens = 3;
            if ( tokenizer.countTokens() > maxTokens )
            {
                throw new MavenReportException(
                    "Unsupported option <locale/> '" + this.locale + "', should be language_country_variant." );
            }

            Locale localeObject = null;
            if ( tokenizer.hasMoreTokens() )
            {
                String language = tokenizer.nextToken().toLowerCase( Locale.ENGLISH );
                if ( !Arrays.asList( Locale.getISOLanguages() ).contains( language ) )
                {
                    throw new MavenReportException(
                        "Unsupported language '" + language + "' in option <locale/> '" + this.locale + "'" );
                }
                localeObject = new Locale( language );

                if ( tokenizer.hasMoreTokens() )
                {
                    String country = tokenizer.nextToken().toUpperCase( Locale.ENGLISH );
                    if ( !Arrays.asList( Locale.getISOCountries() ).contains( country ) )
                    {
                        throw new MavenReportException(
                            "Unsupported country '" + country + "' in option <locale/> '" + this.locale + "'" );
                    }
                    localeObject = new Locale( language, country );

                    if ( tokenizer.hasMoreTokens() )
                    {
                        String variant = tokenizer.nextToken();
                        localeObject = new Locale( language, country, variant );
                    }
                }
            }

            if ( localeObject == null )
            {
                throw new MavenReportException(
                    "Unsupported option <locale/> '" + this.locale + "', should be language_country_variant." );
            }

            this.locale = localeObject.toString();
            final List<Locale> availableLocalesList = Arrays.asList( Locale.getAvailableLocales() );
            if ( StringUtils.isNotEmpty( localeObject.getVariant() ) && !availableLocalesList.contains( localeObject ) )
            {
                StringBuilder sb = new StringBuilder();
                sb.append( "Unsupported option <locale/> with variant '" ).append( this.locale );
                sb.append( "'" );

                localeObject = new Locale( localeObject.getLanguage(), localeObject.getCountry() );
                this.locale = localeObject.toString();

                sb.append( ", trying to use <locale/> without variant, i.e. '" ).append( this.locale ).append( "'" );
                if ( getLog().isWarnEnabled() )
                {
                    getLog().warn( sb.toString() );
                }
            }

            if ( !availableLocalesList.contains( localeObject ) )
            {
                throw new MavenReportException( "Unsupported option <locale/> '" + this.locale + "'" );
            }
        }
    }

    /**
     * Checks for the validity of the Standard Doclet options.
     * <br/>
     * For example, throw an exception if &lt;nohelp/&gt; and &lt;helpfile/&gt; options are used together.
     *
     * @throws MavenReportException if error or conflict found
     */
    private void validateStandardDocletOptions()
        throws MavenReportException
    {
        // docencoding
        if ( StringUtils.isNotEmpty( getDocencoding() ) && !JavadocUtil.validateEncoding( getDocencoding() ) )
        {
            throw new MavenReportException( "Unsupported option <docencoding/> '" + getDocencoding() + "'" );
        }

        // charset
        if ( StringUtils.isNotEmpty( getCharset() ) && !JavadocUtil.validateEncoding( getCharset() ) )
        {
            throw new MavenReportException( "Unsupported option <charset/> '" + getCharset() + "'" );
        }

        // helpfile
        if ( StringUtils.isNotEmpty( helpfile ) && nohelp )
        {
            throw new MavenReportException( "Option <nohelp/> conflicts with <helpfile/>" );
        }

        // overview
        if ( getOverview() != null && getOverview().exists() && nooverview )
        {
            throw new MavenReportException( "Option <nooverview/> conflicts with <overview/>" );
        }

        // index
        if ( splitindex && noindex )
        {
            throw new MavenReportException( "Option <noindex/> conflicts with <splitindex/>" );
        }

        // stylesheet
        if ( StringUtils.isNotEmpty( stylesheet ) && !( stylesheet.equalsIgnoreCase( "maven" )
            || stylesheet.equalsIgnoreCase( "java" ) ) )
        {
            throw new MavenReportException( "Option <stylesheet/> supports only \"maven\" or \"java\" value." );
        }
    }

    /**
     * Add Standard Javadoc Options.
     * <br/>
     * The <a href="package-summary.html#Standard_Javadoc_Options">package documentation</a> details the
     * Standard Javadoc Options wrapped by this Plugin.
     *
     * @param javadocOutputDirectory not null
     * @param arguments              not null
     * @param allSourcePaths         not null
     * @throws MavenReportException if any
     * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#javadocoptions">https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#javadocoptions</a>
     */
    private void addJavadocOptions( File javadocOutputDirectory,
                                    List<String> arguments,
                                    Collection<JavadocModule> allSourcePaths,
                                    Set<OfflineLink> offlineLinks )
        throws MavenReportException
    {
        Collection<Path> sourcePaths = allSourcePaths.stream()
                                                     .flatMap( e -> e.getSourcePaths().stream() )
                                                     .collect( Collectors.toList() );

        validateJavadocOptions();

        // see com.sun.tools.javadoc.Start#parseAndExecute(String argv[])
        addArgIfNotEmpty( arguments, "-locale", JavadocUtil.quotedArgument( this.locale ) );

        // all options in alphabetical order

        if ( old && isJavaDocVersionAtLeast( SINCE_JAVADOC_1_4 ) )
        {
            if ( getLog().isWarnEnabled() )
            {
                getLog().warn( "Javadoc 1.4+ doesn't support the -1.1 switch anymore. Ignore this option." );
            }
        }
        else
        {
            addArgIf( arguments, old, "-1.1" );
        }

        addArgIfNotEmpty( arguments, "-bootclasspath", JavadocUtil.quotedPathArgument( getBootclassPath() ) );

        if ( isJavaDocVersionAtLeast( SINCE_JAVADOC_1_5 ) )
        {
            addArgIf( arguments, breakiterator, "-breakiterator", SINCE_JAVADOC_1_5 );
        }

        List<MavenProject> aggregatedProjects = reactorProjects; // getAggregatedProjects();
        Map<String, MavenProject> reactorKeys = new HashMap<>( aggregatedProjects.size() );
        for ( MavenProject reactorProject : aggregatedProjects )
        {
            reactorKeys.put( ArtifactUtils.versionlessKey( reactorProject.getGroupId(),
                                                           reactorProject.getArtifactId() ), reactorProject );
        }

        Map<String, JavaModuleDescriptor> allModuleDescriptors = new HashMap<>();

        boolean supportModulePath = javadocRuntimeVersion.isAtLeast( "9" );
        if ( release != null ) 
        {
            supportModulePath &= JavaVersion.parse( release ).isAtLeast( "9" );
        }
        else if ( source != null )
        {
            supportModulePath &= JavaVersion.parse( source ).isAtLeast( "9" );
        }

        if ( supportModulePath )
        {
            for ( JavadocModule entry : allSourcePaths )
            {
                if ( entry.getModuleNameSource() == null || entry.getModuleNameSource() == ModuleNameSource.FILENAME )
                {
                    Path moduleDescriptor = findMainDescriptor( entry.getSourcePaths() );

                    if ( moduleDescriptor != null )
                    {
                        try
                        {
                            allModuleDescriptors.put( entry.getGa(),
                                      locationManager.parseModuleDescriptor( moduleDescriptor ).getModuleDescriptor() );
                        }
                        catch ( IOException e )
                        {
                            throw new MavenReportException( e.getMessage(), e );
                        }
                    }
                }
                else
                {
                    allModuleDescriptors.put( entry.getGa(), entry.getModuleDescriptor() );
                }
            }
        }

        Collection<String> additionalModules = new ArrayList<>();

        ResolvePathResult mainResolvePathResult = null;

        Map<String, Collection<Path>> patchModules = new HashMap<>();

        Path moduleSourceDir = null;
        if ( supportModulePath && !allModuleDescriptors.isEmpty() )
        {
            Collection<String> unnamedProjects = new ArrayList<>();
            for ( JavadocModule javadocModule : allSourcePaths )
            {
                MavenProject aggregatedProject = reactorKeys.get( javadocModule.getGa() );
                if ( aggregatedProject != null && !"pom".equals( aggregatedProject.getPackaging() ) )
                {
                    ResolvePathResult result = null;

                    // Prefer jar over outputDirectory, since it may may contain an automatic module name
                    File artifactFile = getClassesFile( aggregatedProject );
                    if ( artifactFile != null )
                    {
                        ResolvePathRequest<File> request = ResolvePathRequest.ofFile( artifactFile );
                        try
                        {
                            result = locationManager.resolvePath( request );
                        }
                        catch ( RuntimeException e )
                        {
                            // most likely an invalid module name based on filename
                            if ( !"java.lang.module.FindException".equals( e.getClass().getName() ) )
                            {
                                throw e;
                            }
                        }
                        catch ( IOException e )
                        {
                            throw new MavenReportException( e.getMessage(), e );
                        }
                    }
                    else
                    {
                        Path moduleDescriptor = findMainDescriptor( javadocModule.getSourcePaths() );

                        if ( moduleDescriptor != null )
                        {
                            try
                            {
                                result = locationManager.parseModuleDescriptor( moduleDescriptor );
                            }
                            catch ( IOException e )
                            {
                                throw new MavenReportException( e.getMessage(), e );
                            }
                        }
                    }

                    if ( result != null && result.getModuleDescriptor() != null )
                    {
                        moduleSourceDir = javadocOutputDirectory.toPath().resolve( "src" );
                        try
                        {
                            moduleSourceDir = Files.createDirectories( moduleSourceDir );

                            additionalModules.add( result.getModuleDescriptor().name() );

                            patchModules.put( result.getModuleDescriptor().name(), javadocModule.getSourcePaths() );

                            Path modulePath = moduleSourceDir.resolve( result.getModuleDescriptor().name() );
                            if ( !Files.isDirectory( modulePath ) )
                            {
                                Files.createDirectory( modulePath );
                            }
                        }
                        catch ( IOException e )
                        {
                            throw new MavenReportException( e.getMessage(), e );
                        }
                    }
                    else
                    {
                        unnamedProjects.add( javadocModule.getGa() );
                    }

                    if ( aggregatedProject.equals( getProject() ) )
                    {
                        mainResolvePathResult = result;
                    }
                }
                else
                {
                    // todo
                    getLog().error( "no reactor project: " + javadocModule.getGa() );
                }
            }

            if ( !unnamedProjects.isEmpty() )
            {
                getLog().error( "Creating an aggregated report for both named and unnamed modules is not possible." );
                getLog().error( "Ensure that every module has a module descriptor or is a jar with a MANIFEST.MF "
                    + "containing an Automatic-Module-Name." );
                getLog().error( "Fix the following projects:" );
                for ( String unnamedProject : unnamedProjects )
                {
                    getLog().error( " - " + unnamedProject );
                }
                throw new MavenReportException( "Aggregator report contains named and unnamed modules" );
            }

            if ( mainResolvePathResult != null
                && ModuleNameSource.MANIFEST.equals( mainResolvePathResult.getModuleNameSource() ) )
            {
                arguments.add( "--add-modules" );
                arguments.add( "ALL-MODULE-PATH" );
            }
        }

        // MJAVADOC-506
        boolean moduleDescriptorSource = false;
        for ( Path sourcepath : sourcePaths )
        {
            if ( Files.isRegularFile( sourcepath.resolve( "module-info.java" ) ) )
            {
                moduleDescriptorSource = true;
                break;
            }
        }

        final ModuleNameSource mainModuleNameSource;
        if ( mainResolvePathResult != null )
        {
            mainModuleNameSource = mainResolvePathResult.getModuleNameSource();
        }
        else
        {
            mainModuleNameSource = null;
        }

        if ( supportModulePath
             && ( isAggregator()
                  || ModuleNameSource.MODULEDESCRIPTOR.equals( mainModuleNameSource )
                  || ModuleNameSource.MANIFEST.equals( mainModuleNameSource ) ) )
        {
            List<File> pathElements = new ArrayList<>( getPathElements() );
            File artifactFile = getClassesFile( project );
            if ( artifactFile != null )
            {
                pathElements.add( 0, artifactFile );
            }

            ResolvePathsRequest<File> request =
                ResolvePathsRequest.ofFiles( pathElements );

            String mainModuleName = null;
            if ( mainResolvePathResult != null )
            {
                request.setModuleDescriptor( mainResolvePathResult.getModuleDescriptor() );
                mainModuleName = mainResolvePathResult.getModuleDescriptor().name();
            }

            request.setAdditionalModules( additionalModules );
            request.setIncludeStatic( isAggregator() );

            try
            {
                ResolvePathsResult<File> result = locationManager.resolvePaths( request );

                Set<File> modulePathElements = new HashSet<>( result.getModulepathElements().keySet() )  ;

                Collection<File> classPathElements = new ArrayList<>( result.getClasspathElements().size() );

                for ( File file : result.getClasspathElements() )
                {
                    if ( file.isDirectory() && new File( file, "module-info.class" ).exists() )
                    {
                        modulePathElements.add( file );
                    }
                    else if ( ModuleNameSource.MANIFEST.equals( mainModuleNameSource ) )
                    {
                        ModuleNameSource depModuleNameSource =
                            locationManager.resolvePath( ResolvePathRequest.ofFile( file ) ).getModuleNameSource();
                        if ( ModuleNameSource.MODULEDESCRIPTOR.equals( depModuleNameSource )
                            || ModuleNameSource.MANIFEST.equals( depModuleNameSource ) )
                        {
                            modulePathElements.add( file );
                        }
                        else
                        {
                            patchModules.get( mainModuleName ).add( file.toPath() );
                        }
                    }
                    else
                    {
                        classPathElements.add( file );
                    }
                }

                /* MJAVADOC-620: also add all JARs where module-name-guessing leads to a FindException: */
                for ( Entry<File, Exception> pathExceptionEntry : result.getPathExceptions().entrySet() )
                {
                    Exception exception = pathExceptionEntry.getValue();
                    // For Java < 9 compatibility, reference FindException by name:
                    if ( "java.lang.module.FindException".equals( exception.getClass().getName() ) )
                    {
                        File jarPath = pathExceptionEntry.getKey();
                        classPathElements.add( jarPath );
                    }
                }

                String classpath = StringUtils.join( classPathElements.iterator(), File.pathSeparator );
                addArgIfNotEmpty( arguments, "--class-path", JavadocUtil.quotedPathArgument( classpath ), false,
                                  false );

                String modulepath =
                    StringUtils.join( modulePathElements.iterator(), File.pathSeparator );
                addArgIfNotEmpty( arguments, "--module-path", JavadocUtil.quotedPathArgument( modulepath ), false,
                                  false );
            }
            catch ( IOException e )
            {
                throw new MavenReportException( e.getMessage(), e );
            }
        }
        else if ( supportModulePath && moduleDescriptorSource && !isTest() )
        {
            String modulepath = StringUtils.join( getPathElements().iterator(), File.pathSeparator );
            addArgIfNotEmpty( arguments, "--module-path", JavadocUtil.quotedPathArgument( modulepath ) , false, false );
        }
        else
        {
            String classpath = StringUtils.join( getPathElements().iterator(), File.pathSeparator );
            addArgIfNotEmpty( arguments, "-classpath", JavadocUtil.quotedPathArgument( classpath ) , false, false );
        }

        for ( Entry<String, Collection<Path>> entry : patchModules.entrySet() )
        {
            addArgIfNotEmpty( arguments, "--patch-module", entry.getKey() + '='
                              + JavadocUtil.quotedPathArgument( getSourcePath( entry.getValue() ) ),
                                false, false );
        }

        if ( StringUtils.isNotEmpty( doclet ) )
        {
            addArgIfNotEmpty( arguments, "-doclet", JavadocUtil.quotedArgument( doclet ) );
            addArgIfNotEmpty( arguments, "-docletpath", JavadocUtil.quotedPathArgument( getDocletPath() ) );
        }

        if ( StringUtils.isEmpty( encoding ) )
        {
            getLog().warn(
                "Source files encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
                    + ", i.e. build is platform dependent!" );
        }
        addArgIfNotEmpty( arguments, "-encoding", JavadocUtil.quotedArgument( getEncoding() ) );

        addArgIfNotEmpty( arguments, "-extdirs",
                          JavadocUtil.quotedPathArgument( JavadocUtil.unifyPathSeparator( extdirs ) ) );

        if ( ( getOverview() != null ) && ( getOverview().exists() ) )
        {
            addArgIfNotEmpty( arguments, "-overview",
                              JavadocUtil.quotedPathArgument( getOverview().getAbsolutePath() ) );
        }

        arguments.add( getAccessLevel() );

        if ( isJavaDocVersionAtLeast( SINCE_JAVADOC_1_5 ) )
        {
            addArgIf( arguments, quiet, "-quiet", SINCE_JAVADOC_1_5 );
        }

        if ( release != null )
        {
            arguments.add( "--release" );
            arguments.add( release );
        }
        else
        {
            addArgIfNotEmpty( arguments, "-source", JavadocUtil.quotedArgument( source ), SINCE_JAVADOC_1_4 );
        }

        if ( ( StringUtils.isEmpty( sourcepath ) ) && ( StringUtils.isNotEmpty( subpackages ) ) )
        {
            sourcepath = StringUtils.join( sourcePaths.iterator(), File.pathSeparator );
        }

        if ( moduleSourceDir == null )
        {
            addArgIfNotEmpty( arguments, "-sourcepath",
                              JavadocUtil.quotedPathArgument( getSourcePath( sourcePaths ) ), false, false );
        }
        else if ( mainResolvePathResult == null
            || ModuleNameSource.MODULEDESCRIPTOR.equals( mainResolvePathResult.getModuleNameSource() ) )
        {
            addArgIfNotEmpty( arguments, "--module-source-path",
                              JavadocUtil.quotedPathArgument( moduleSourceDir.toString() ) );
        }


        if ( StringUtils.isNotEmpty( sourcepath ) && isJavaDocVersionAtLeast( SINCE_JAVADOC_1_5 ) )
        {
            addArgIfNotEmpty( arguments, "-subpackages", subpackages, SINCE_JAVADOC_1_5 );
        }

        // [MJAVADOC-497] must be after sourcepath is recalculated, since getExcludedPackages() depends on it
        addArgIfNotEmpty( arguments, "-exclude", getExcludedPackages( sourcePaths ), SINCE_JAVADOC_1_4 );

        addArgIf( arguments, verbose, "-verbose" );

        if ( additionalOptions != null && additionalOptions.length > 0 )
        {
            for ( String additionalOption : additionalOptions )
            {
                arguments.add( additionalOption.replaceAll( "(?<!\\\\)\\\\(?!\\\\|:)", "\\\\" ) );
            }
        }
    }

    private ResolvePathResult getResolvePathResult( File artifactFile )
    {
        if ( artifactFile == null )
        {
            return null;
        }

        ResolvePathResult resolvePathResult = null;
        ResolvePathRequest<File> resolvePathRequest = ResolvePathRequest.ofFile( artifactFile );
        try
        {
            resolvePathResult = locationManager.resolvePath( resolvePathRequest );

            // happens when artifactFile is a directory without module descriptor
            if ( resolvePathResult.getModuleDescriptor() == null )
            {
                return null;
            }
        }
        catch ( IOException | RuntimeException /* e.g java.lang.module.FindException */ e )
        {
            if ( getLog().isDebugEnabled() )
            {
                Throwable cause = e;
                while ( cause.getCause() != null )
                {
                    cause = cause.getCause();
                }

                getLog().debug( "resolve path for: " + artifactFile + " cause error: " + cause );
            }
        }
        return resolvePathResult;
    }

    private Path findMainDescriptor( Collection<Path> roots ) throws MavenReportException
    {
        for ( Map.Entry<Path, Collection<String>> entry : getFiles( roots ).entrySet() )
        {
            if ( entry.getValue().contains( "module-info.java" ) )
            {
                return entry.getKey().resolve( "module-info.java" );
            }
        }
        return null;
    }

    /**
     * Add Standard Doclet Options.
     * <br/>
     * The <a href="package-summary.html#Standard_Doclet_Options">package documentation</a> details the
     * Standard Doclet Options wrapped by this Plugin.
     *
     * @param javadocOutputDirectory not null
     * @param arguments              not null
     * @throws MavenReportException if any
     * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#standard">
     *      https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#standard</a>
     */
    private void addStandardDocletOptions( File javadocOutputDirectory,
                                           List<String> arguments,
                                           Set<OfflineLink> offlineLinks )
        throws MavenReportException
    {
        validateStandardDocletOptions();

        // all options in alphabetical order

        addArgIf( arguments, author, "-author" );

        addArgIfNotEmpty( arguments, "-bottom", JavadocUtil.quotedArgument( getBottomText() ), false, false );

        if ( !isJavaDocVersionAtLeast( SINCE_JAVADOC_1_5 ) )
        {
            addArgIf( arguments, breakiterator, "-breakiterator", SINCE_JAVADOC_1_4 );
        }

        addArgIfNotEmpty( arguments, "-charset", JavadocUtil.quotedArgument( getCharset() ) );

        addArgIfNotEmpty( arguments, "-d", JavadocUtil.quotedPathArgument( javadocOutputDirectory.toString() ) );

        addArgIfNotEmpty( arguments, "-docencoding", JavadocUtil.quotedArgument( getDocencoding() ) );

        addArgIf( arguments, docfilessubdirs, "-docfilessubdirs", SINCE_JAVADOC_1_4 );

        addArgIf( arguments, StringUtils.isNotEmpty( doclint ), "-Xdoclint:" + getDoclint(), SINCE_JAVADOC_1_8 );

        addArgIfNotEmpty( arguments, "-doctitle", JavadocUtil.quotedArgument( getDoctitle() ), false, false );

        if ( docfilessubdirs )
        {
            addArgIfNotEmpty( arguments, "-excludedocfilessubdir",
                              JavadocUtil.quotedPathArgument( excludedocfilessubdir ), SINCE_JAVADOC_1_4 );
        }

        addArgIfNotEmpty( arguments, "-footer", JavadocUtil.quotedArgument( footer ), false, false );

        addGroups( arguments );

        addArgIfNotEmpty( arguments, "-header", JavadocUtil.quotedArgument( header ), false, false );

        Optional<File> helpFile = getHelpFile( javadocOutputDirectory );
        if ( helpFile.isPresent() )
        {
            addArgIfNotEmpty( arguments, "-helpfile",
                              JavadocUtil.quotedPathArgument( helpFile.get().getAbsolutePath() ) );
        }

        addArgIf( arguments, keywords, "-keywords", SINCE_JAVADOC_1_4_2 );

        addLinkArguments( arguments );

        addLinkofflineArguments( arguments, offlineLinks );

        addArgIf( arguments, linksource, "-linksource", SINCE_JAVADOC_1_4 );

        if ( sourcetab > 0 )
        {
            if ( javadocRuntimeVersion == SINCE_JAVADOC_1_4_2 )
            {
                addArgIfNotEmpty( arguments, "-linksourcetab", String.valueOf( sourcetab ) );
            }
            addArgIfNotEmpty( arguments, "-sourcetab", String.valueOf( sourcetab ), SINCE_JAVADOC_1_5 );
        }

        addArgIf( arguments, nocomment, "-nocomment", SINCE_JAVADOC_1_4 );

        addArgIf( arguments, nodeprecated, "-nodeprecated" );

        addArgIf( arguments, nodeprecatedlist, "-nodeprecatedlist" );

        addArgIf( arguments, nohelp, "-nohelp" );

        addArgIf( arguments, noindex, "-noindex" );

        addArgIf( arguments, nonavbar, "-nonavbar" );

        addArgIf( arguments, nooverview, "-nooverview" );

        addArgIfNotEmpty( arguments, "-noqualifier", JavadocUtil.quotedArgument( noqualifier ), SINCE_JAVADOC_1_4 );

        addArgIf( arguments, nosince, "-nosince" );

        addArgIf( arguments, notimestamp, "-notimestamp", SINCE_JAVADOC_1_5 );

        addArgIf( arguments, notree, "-notree" );

        addArgIfNotEmpty( arguments, "-packagesheader", JavadocUtil.quotedArgument( packagesheader ),
                          SINCE_JAVADOC_1_4_2 );

        if ( !isJavaDocVersionAtLeast( SINCE_JAVADOC_1_5 ) ) // Sun bug: 4714350
        {
            addArgIf( arguments, quiet, "-quiet", SINCE_JAVADOC_1_4 );
        }

        addArgIf( arguments, serialwarn, "-serialwarn" );

        addArgIf( arguments, splitindex, "-splitindex" );

        Optional<File> stylesheetfile = getStylesheetFile( javadocOutputDirectory );
        
        if ( stylesheetfile.isPresent() )
        {
            addArgIfNotEmpty( arguments, "-stylesheetfile",
                              JavadocUtil.quotedPathArgument( stylesheetfile.get().getAbsolutePath() ) );
        }
        
        addAddStyleSheets( arguments ); 

        if ( StringUtils.isNotEmpty( sourcepath ) && !isJavaDocVersionAtLeast( SINCE_JAVADOC_1_5 ) )
        {
            addArgIfNotEmpty( arguments, "-subpackages", subpackages, SINCE_JAVADOC_1_4 );
        }

        addArgIfNotEmpty( arguments, "-taglet", JavadocUtil.quotedArgument( taglet ), SINCE_JAVADOC_1_4 );
        addTaglets( arguments );
        addTagletsFromTagletArtifacts( arguments );
        addArgIfNotEmpty( arguments, "-tagletpath", JavadocUtil.quotedPathArgument( getTagletPath() ),
                          SINCE_JAVADOC_1_4 );

        addTags( arguments );

        addArgIfNotEmpty( arguments, "-top", JavadocUtil.quotedArgument( top ), false, false, SINCE_JAVADOC_1_6 );

        addArgIf( arguments, use, "-use" );

        addArgIf( arguments, version, "-version" );

        addArgIfNotEmpty( arguments, "-windowtitle", JavadocUtil.quotedArgument( getWindowtitle() ), false, false );
    }

    /**
     * Add <code>groups</code> parameter to arguments.
     *
     * @param arguments not null
     * @throws MavenReportException
     */
    private void addGroups( List<String> arguments )
        throws MavenReportException
    {
        Set<Group> groups = collectGroups();
        if ( isEmpty( groups ) )
        {
            return;
        }

        for ( Group group : groups )
        {
            if ( group == null || StringUtils.isEmpty( group.getTitle() ) || StringUtils.isEmpty(
                group.getPackages() ) )
            {
                if ( getLog().isWarnEnabled() )
                {
                    getLog().warn( "A group option is empty. Ignore this option." );
                }
            }
            else
            {
                String groupTitle = StringUtils.replace( group.getTitle(), ",", "&#44;" );
                addArgIfNotEmpty( arguments, "-group",
                                  JavadocUtil.quotedArgument( groupTitle ) + " " + JavadocUtil.quotedArgument(
                                      group.getPackages() ), true );
            }
        }
    }

    /**
     * Add <code>tags</code> parameter to arguments.
     *
     * @param arguments not null
     * @throws MavenReportException
     */
    private void addTags( List<String> arguments )
        throws MavenReportException
    {
        final String lineSeparator;
        if ( javadocRuntimeVersion.isBefore( "9" ) )
        {
            lineSeparator = " ";
        }
        else
        {
            lineSeparator = " \\\\" + SystemUtils.LINE_SEPARATOR;
        }

        for ( Tag tag : collectTags() )
        {
            if ( StringUtils.isEmpty( tag.getName() ) )
            {
                if ( getLog().isWarnEnabled() )
                {
                    getLog().warn( "A tag name is empty. Ignore this option." );
                }
            }
            else
            {
                String value = "\"" + tag.getName();
                if ( StringUtils.isNotEmpty( tag.getPlacement() ) )
                {
                    value += ":" + tag.getPlacement().replaceAll( "\\R", lineSeparator );
                    if ( StringUtils.isNotEmpty( tag.getHead() ) )
                    {
                        value += ":" + tag.getHead().replaceAll( "\\R", lineSeparator );
                    }
                }
                value += "\"";
                addArgIfNotEmpty( arguments, "-tag", value, SINCE_JAVADOC_1_4 );
            }
        }
    }

    /**
     * Add <code>taglets</code> parameter to arguments.
     *
     * @param arguments not null
     */
    private void addTaglets( List<String> arguments )
    {
        if ( taglets == null )
        {
            return;
        }

        for ( Taglet taglet1 : taglets )
        {
            if ( ( taglet1 == null ) || ( StringUtils.isEmpty( taglet1.getTagletClass() ) ) )
            {
                if ( getLog().isWarnEnabled() )
                {
                    getLog().warn( "A taglet option is empty. Ignore this option." );
                }
            }
            else
            {
                addArgIfNotEmpty( arguments, "-taglet", JavadocUtil.quotedArgument( taglet1.getTagletClass() ),
                                  SINCE_JAVADOC_1_4 );
            }
        }
    }

    /**
     * Auto-detect taglets class name from <code>tagletArtifacts</code> and add them to arguments.
     *
     * @param arguments not null
     * @throws MavenReportException if any
     * @see JavadocUtil#getTagletClassNames(File)
     */
    private void addTagletsFromTagletArtifacts( List<String> arguments )
        throws MavenReportException
    {
        Set<TagletArtifact> tArtifacts = new LinkedHashSet<>();
        if ( tagletArtifacts != null && tagletArtifacts.length > 0 )
        {
            tArtifacts.addAll( Arrays.asList( tagletArtifacts ) );
        }

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getTagletArtifacts() ) )
                    {
                        tArtifacts.addAll( options.getTagletArtifacts() );
                    }
                }
            }
        }

        if ( isEmpty( tArtifacts ) )
        {
            return;
        }

        List<String> tagletsPath = new ArrayList<>();

        for ( TagletArtifact aTagletArtifact : tArtifacts )
        {
            if ( ( StringUtils.isNotEmpty( aTagletArtifact.getGroupId() ) ) && ( StringUtils.isNotEmpty(
                aTagletArtifact.getArtifactId() ) ) && ( StringUtils.isNotEmpty( aTagletArtifact.getVersion() ) ) )
            {
                Artifact artifact;
                try
                {
                    artifact = createAndResolveArtifact( aTagletArtifact );
                }
                catch ( ArtifactResolverException e )
                {
                    throw new MavenReportException( "Unable to resolve artifact:" + aTagletArtifact, e );
                }

                tagletsPath.add( artifact.getFile().getAbsolutePath() );
            }
        }

        tagletsPath = JavadocUtil.pruneFiles( tagletsPath );

        for ( String tagletJar : tagletsPath )
        {
            if ( !tagletJar.toLowerCase( Locale.ENGLISH ).endsWith( ".jar" ) )
            {
                continue;
            }

            List<String> tagletClasses;
            try
            {
                tagletClasses = JavadocUtil.getTagletClassNames( new File( tagletJar ) );
            }
            catch ( IOException e )
            {
                if ( getLog().isWarnEnabled() )
                {
                    getLog().warn( "Unable to auto-detect Taglet class names from '" + tagletJar
                                       + "'. Try to specify them with <taglets/>." );
                }
                if ( getLog().isDebugEnabled() )
                {
                    getLog().debug( "IOException: " + e.getMessage(), e );
                }
                continue;
            }
            catch ( ClassNotFoundException e )
            {
                if ( getLog().isWarnEnabled() )
                {
                    getLog().warn( "Unable to auto-detect Taglet class names from '" + tagletJar
                                       + "'. Try to specify them with <taglets/>." );
                }
                if ( getLog().isDebugEnabled() )
                {
                    getLog().debug( "ClassNotFoundException: " + e.getMessage(), e );
                }
                continue;
            }
            catch ( NoClassDefFoundError e )
            {
                if ( getLog().isWarnEnabled() )
                {
                    getLog().warn( "Unable to auto-detect Taglet class names from '" + tagletJar
                                       + "'. Try to specify them with <taglets/>." );
                }
                if ( getLog().isDebugEnabled() )
                {
                    getLog().debug( "NoClassDefFoundError: " + e.getMessage(), e );
                }
                continue;
            }

            if ( tagletClasses != null && !tagletClasses.isEmpty() )
            {
                for ( String tagletClass : tagletClasses )
                {
                    addArgIfNotEmpty( arguments, "-taglet", JavadocUtil.quotedArgument( tagletClass ),
                                      SINCE_JAVADOC_1_4 );
                }
            }
        }
    }

    /**
     * Execute the Javadoc command line
     *
     * @param cmd                    not null
     * @param javadocOutputDirectory not null
     * @throws MavenReportException if any errors occur
     */
    private void executeJavadocCommandLine( Commandline cmd, File javadocOutputDirectory )
            throws MavenReportException
    {
        if ( staleDataPath != null )
        {
            if ( !isUpToDate( cmd ) )
            {
                doExecuteJavadocCommandLine( cmd, javadocOutputDirectory );
                StaleHelper.writeStaleData( cmd, staleDataPath.toPath() );
            }
        }
        else
        {
            doExecuteJavadocCommandLine( cmd, javadocOutputDirectory );
        }
    }

    /**
     * Check if the javadoc is uptodate or not
     *
     * @param cmd                    not null
     * @return <code>true</code> is the javadoc is uptodate, <code>false</code> otherwise
     * @throws MavenReportException  if any error occur
     */
    private boolean isUpToDate( Commandline cmd )
            throws MavenReportException
    {
        try
        {
            String curdata = StaleHelper.getStaleData( cmd );
            Path cacheData = staleDataPath.toPath();
            String prvdata;
            if ( Files.isRegularFile( cacheData ) )
            {
                prvdata = new String( Files.readAllBytes( cacheData ), StandardCharsets.UTF_8 );
            }
            else
            {
                prvdata = null;
            }
            if ( curdata.equals( prvdata ) )
            {
                getLog().info( "Skipping javadoc generation, everything is up to date." );
                return true;
            }
            else
            {
                if ( prvdata == null )
                {
                    getLog().info( "No previous run data found, generating javadoc." );
                }
                else
                {
                    getLog().info( "Configuration changed, re-generating javadoc." );
                }
            }
        }
        catch ( IOException e )
        {
            throw new MavenReportException( "Error checking uptodate status", e );
        }
        return false;
    }

    /**
     * Execute the Javadoc command line
     *
     * @param cmd                    not null
     * @param javadocOutputDirectory not null
     * @throws MavenReportException if any errors occur
     */
    private void doExecuteJavadocCommandLine( Commandline cmd, File javadocOutputDirectory )
        throws MavenReportException
    {
        if ( getLog().isDebugEnabled() )
        {
            // no quoted arguments
            getLog().debug( CommandLineUtils.toString( cmd.getCommandline() ).replaceAll( "'", "" ) );
        }

        String cmdLine = null;
        if ( debug )
        {
            cmdLine = CommandLineUtils.toString( cmd.getCommandline() ).replaceAll( "'", "" );

            writeDebugJavadocScript( cmdLine, javadocOutputDirectory );
        }

        CommandLineUtils.StringStreamConsumer err = new JavadocUtil.JavadocOutputStreamConsumer();
        CommandLineUtils.StringStreamConsumer out = new JavadocUtil.JavadocOutputStreamConsumer();
        try
        {
            int exitCode = CommandLineUtils.executeCommandLine( cmd, out, err );

            String output = ( StringUtils.isEmpty( out.getOutput() ) ? null : '\n' + out.getOutput().trim() );

            if ( exitCode != 0 )
            {
                if ( cmdLine == null )
                {
                    cmdLine = CommandLineUtils.toString( cmd.getCommandline() ).replaceAll( "'", "" );
                }
                writeDebugJavadocScript( cmdLine, javadocOutputDirectory );

                if ( StringUtils.isNotEmpty( output ) && StringUtils.isEmpty( err.getOutput() )
                    && isJavadocVMInitError( output ) )
                {
                    throw new MavenReportException( output + '\n' + '\n' + JavadocUtil.ERROR_INIT_VM + '\n'
                        + "Or, try to reduce the Java heap size for the Javadoc goal using "
                        + "-Dminmemory=<size> and -Dmaxmemory=<size>." + '\n' + '\n' + "Command line was: " + cmdLine
                        + '\n' + '\n' + "Refer to the generated Javadoc files in '" + javadocOutputDirectory
                        + "' dir.\n" );
                }

                if ( StringUtils.isNotEmpty( output ) )
                {
                    getLog().info( output );
                }

                StringBuilder msg = new StringBuilder( "\nExit code: " );
                msg.append( exitCode );
                if ( StringUtils.isNotEmpty( err.getOutput() ) )
                {
                    msg.append( " - " ).append( err.getOutput() );
                }
                msg.append( '\n' );
                msg.append( "Command line was: " ).append( cmdLine ).append( '\n' ).append( '\n' );

                msg.append( "Refer to the generated Javadoc files in '" ).append( javadocOutputDirectory )
                .append( "' dir.\n" );

                throw new MavenReportException( msg.toString() );
            }

            if ( StringUtils.isNotEmpty( output ) )
            {
                getLog().info( output );
            }
        }
        catch ( CommandLineException e )
        {
            throw new MavenReportException( "Unable to execute javadoc command: " + e.getMessage(), e );
        }

        // ----------------------------------------------------------------------
        // Handle Javadoc warnings
        // ----------------------------------------------------------------------

        if ( containsWarnings( err.getOutput() ) )
        {
            if ( getLog().isWarnEnabled() )
            {
                getLog().warn( "Javadoc Warnings" );

                StringTokenizer token = new StringTokenizer( err.getOutput(), "\n" );
                while ( token.hasMoreTokens() )
                {
                    String current = token.nextToken().trim();

                    getLog().warn( current );
                }
            }

            if ( failOnWarnings )
            {
                throw new MavenReportException( "Project contains Javadoc Warnings" );
            }
        }
    }

    private boolean containsWarnings( String output )
    {
        // JDK-8268774 / JDK-8270831
        if ( this.javadocRuntimeVersion.isBefore( "17" ) )
        {
            return StringUtils.isNotEmpty( output );
        }
        else
        {
            return Arrays.stream( output.split( "\\R" ) )
                            .reduce( ( first, second ) -> second ) // last line
                            .filter( line -> line.matches( "\\d+ warnings?" ) )
                            .isPresent();
        }
    }

    /**
     * Patches the given Javadoc output directory to work around CVE-2013-1571
     * (see http://www.kb.cert.org/vuls/id/225657).
     *
     * @param javadocOutputDirectory directory to scan for vulnerabilities
     * @param outputEncoding         encoding used by the javadoc tool (-docencoding parameter).
     *                               If {@code null}, the platform's default encoding is used (like javadoc does).
     * @return the number of patched files
     */
    private int fixFrameInjectionBug( File javadocOutputDirectory, String outputEncoding )
        throws IOException
    {
        final String fixData;

        try ( InputStream in = this.getClass().getResourceAsStream( "frame-injection-fix.txt" ) )
        {
            if ( in == null )
            {
                throw new FileNotFoundException( "Missing resource 'frame-injection-fix.txt' in classpath." );
            }
            fixData = org.codehaus.plexus.util.StringUtils
                .unifyLineSeparators( IOUtil.toString( in, "US-ASCII" ) ).trim();
        }

        final DirectoryScanner ds = new DirectoryScanner();
        ds.setBasedir( javadocOutputDirectory );
        ds.setCaseSensitive( false );
        ds.setIncludes( new String[]{ "**/index.html", "**/index.htm", "**/toc.html", "**/toc.htm" } );
        ds.addDefaultExcludes();
        ds.scan();
        int patched = 0;
        for ( String f : ds.getIncludedFiles() )
        {
            final File file = new File( javadocOutputDirectory, f );
            // we load the whole file as one String (toc/index files are
            // generally small, because they only contain frameset declaration):
            final String fileContents = FileUtils.fileRead( file, outputEncoding );
            // check if file may be vulnerable because it was not patched with "validURL(url)":
            if ( !StringUtils.contains( fileContents, "function validURL(url) {" ) )
            {
                // we need to patch the file!
                final String patchedFileContents =
                    StringUtils.replaceOnce( fileContents, "function loadFrames() {", fixData );
                if ( !patchedFileContents.equals( fileContents ) )
                {
                    FileUtils.fileWrite( file, outputEncoding, patchedFileContents );
                    patched++;
                }
            }
        }
        return patched;
    }

    /**
     * @param outputFile        not nul
     * @param inputResourceName a not null resource in <code>src/main/java</code>, <code>src/main/resources</code> or
     *                          <code>src/main/javadoc</code> or in the Javadoc plugin dependencies.
     * @return the resource file absolute path as String
     * @since 2.6
     */
    private Optional<File> getResource( File outputFile, String inputResourceName )
    {
        if ( inputResourceName.startsWith( "/" ) )
        {
            inputResourceName = inputResourceName.replaceFirst( "//*", "" );
        }

        List<String> classPath = new ArrayList<>();
        classPath.add( project.getBuild().getSourceDirectory() );

        URL resourceURL = getResource( classPath, inputResourceName );
        if ( resourceURL != null )
        {
            getLog().debug( inputResourceName + " found in the main src directory of the project." );
            return Optional.of( FileUtils.toFile( resourceURL ) );
        }

        classPath.clear();
        List<Resource> resources = project.getBuild().getResources();
        for ( Resource resource : resources )
        {
            classPath.add( resource.getDirectory() );
        }
        resourceURL = getResource( classPath, inputResourceName );
        if ( resourceURL != null )
        {
            getLog().debug( inputResourceName + " found in the main resources directories of the project." );
            return Optional.of( FileUtils.toFile( resourceURL ) );
        }

        if ( javadocDirectory.exists() )
        {
            classPath.clear();
            classPath.add( javadocDirectory.getAbsolutePath() );
            resourceURL = getResource( classPath, inputResourceName );
            if ( resourceURL != null )
            {
                getLog().debug( inputResourceName + " found in the main javadoc directory of the project." );
                return Optional.of( FileUtils.toFile( resourceURL ) );
            }
        }

        classPath.clear();
        final String pluginId = "org.apache.maven.plugins:maven-javadoc-plugin";
        Plugin javadocPlugin = getPlugin( project, pluginId );
        if ( javadocPlugin != null && javadocPlugin.getDependencies() != null )
        {
            List<Dependency> dependencies = javadocPlugin.getDependencies();
            for ( Dependency dependency : dependencies )
            {
                ResourcesArtifact resourceArtifact = new ResourcesArtifact();
                resourceArtifact.setGroupId( dependency.getGroupId() );
                resourceArtifact.setArtifactId( dependency.getArtifactId() );
                resourceArtifact.setVersion( dependency.getVersion() );
                resourceArtifact.setClassifier( dependency.getClassifier() );
                Artifact artifact = null;
                try
                {
                    artifact = createAndResolveArtifact( resourceArtifact );
                }
                catch ( Exception e )
                {
                    logError( "Unable to retrieve the dependency: " + dependency + ". Ignored.", e );
                }

                if ( artifact != null && artifact.getFile().exists() )
                {
                    classPath.add( artifact.getFile().getAbsolutePath() );
                }
            }
            resourceURL = getResource( classPath, inputResourceName );
            if ( resourceURL != null )
            {
                getLog().debug( inputResourceName + " found in javadoc plugin dependencies." );
                try
                {
                    JavadocUtil.copyResource( resourceURL, outputFile );

                    return Optional.of( outputFile );
                }
                catch ( IOException e )
                {
                    logError( "IOException: " + e.getMessage(), e );
                }
            }
        }

        getLog().warn( "Unable to find the resource '" + inputResourceName + "'. Using default Javadoc resources." );

        return Optional.empty();
    }

    /**
     * @param classPath a not null String list of files where resource will be looked up
     * @param resource a not null resource to find in the class path
     * @return the resource from the given classpath or null if not found
     * @see ClassLoader#getResource(String)
     * @since 2.6
     */
    private URL getResource( final List<String> classPath, final String resource )
    {
        List<URL> urls = new ArrayList<>( classPath.size() );
        for ( String filename : classPath )
        {
            try
            {
                urls.add( new File( filename ).toURI().toURL() );
            }
            catch ( MalformedURLException e )
            {
                getLog().error( "MalformedURLException: " + e.getMessage() );
            }
        }

        URLClassLoader javadocClassLoader = new URLClassLoader( urls.toArray( new URL[urls.size()] ), null );
        try
        {
            return javadocClassLoader.getResource( resource );
        }
        finally
        {
            try
            {
                javadocClassLoader.close();
            }
            catch ( IOException ex )
            {
                // ignore
            }
        }
    }

    /**
     * Get the full javadoc goal. Loads the plugin's pom.properties to get the current plugin version.
     *
     * @return <code>org.apache.maven.plugins:maven-javadoc-plugin:CURRENT_VERSION:[test-]javadoc</code>
     */
    private String getFullJavadocGoal()
    {
        String javadocPluginVersion = null;
        String resource = "META-INF/maven/org.apache.maven.plugins/maven-javadoc-plugin/pom.properties";
        try ( InputStream resourceAsStream 
                        = AbstractJavadocMojo.class.getClassLoader().getResourceAsStream( resource ) )
        {
            if ( resourceAsStream != null )
            {
                Properties properties = new Properties();
                properties.load( resourceAsStream );
                if ( StringUtils.isNotEmpty( properties.getProperty( "version" ) ) )
                {
                    javadocPluginVersion = properties.getProperty( "version" );
                }
            }
        }
        catch ( IOException e )
        {
            // nop
        }

        StringBuilder sb = new StringBuilder();

        sb.append( "org.apache.maven.plugins:maven-javadoc-plugin:" );
        if ( StringUtils.isNotEmpty( javadocPluginVersion ) )
        {
            sb.append( javadocPluginVersion ).append( ":" );
        }

        if ( this instanceof TestJavadocReport )
        {
            sb.append( "test-javadoc" );
        }
        else
        {
            sb.append( "javadoc" );
        }

        return sb.toString();
    }

    /**
     * Using Maven, a Javadoc link is given by <code>${project.url}/apidocs</code>.
     *
     * @return the detected Javadoc links using the Maven conventions for all modules defined in the current project
     *         or an empty list
     * @throws MavenReportException if any
     * @see #detectOfflineLinks
     * @see #reactorProjects
     * @since 2.6
     */
    private List<OfflineLink> getModulesLinks()
        throws MavenReportException
    {
        List<MavenProject> aggregatedProjects = reactorProjects;
        if ( !detectOfflineLinks || isAggregator() || aggregatedProjects.isEmpty() )
        {
            return Collections.emptyList();
        }

        getLog().debug( "Trying to add links for modules..." );

        Set<String> dependencyArtifactIds = new HashSet<>();
        final Set<Artifact> dependencyArtifacts = project.getDependencyArtifacts();
        for ( Artifact artifact : dependencyArtifacts )
        {
            dependencyArtifactIds.add( artifact.getId() );
        }

        List<OfflineLink> modulesLinks = new ArrayList<>();
        String javadocDirRelative = PathUtils.toRelative( project.getBasedir(), getOutputDirectory() );
        for ( MavenProject p : aggregatedProjects )
        {
            if ( !dependencyArtifactIds.contains( p.getArtifact().getId() ) || ( p.getUrl() == null ) )
            {
                continue;
            }

            File location = new File( p.getBasedir(), javadocDirRelative );

            if ( !location.exists() )
            {
                if ( getLog().isDebugEnabled() )
                {
                    getLog().debug( "Javadoc directory not found: " + location );
                }

                String javadocGoal = getFullJavadocGoal();
                getLog().info(
                    "The goal '" + javadocGoal + "' has not been previously called for the module: '" + p.getId()
                        + "'. Trying to invoke it..." );

                File invokerDir = new File( project.getBuild().getDirectory(), "invoker" );
                invokerDir.mkdirs();
                File invokerLogFile = FileUtils.createTempFile( "maven-javadoc-plugin", ".txt", invokerDir );
                try
                {
                    JavadocUtil.invokeMaven( getLog(), new File( localRepository.getBasedir() ), p.getFile(),
                                             Collections.singletonList( javadocGoal ), null, invokerLogFile,
                                             session.getRequest().getGlobalSettingsFile() );
                }
                catch ( MavenInvocationException e )
                {
                    logError( "MavenInvocationException: " + e.getMessage(), e );

                    String invokerLogContent = JavadocUtil.readFile( invokerLogFile, null /* platform encoding */ );

                    // TODO: Why are we only interested in cases where the JVM won't start?
                    // [MJAVADOC-275][jdcasey] I changed the logic here to only throw an error WHEN
                    //   the JVM won't start (opposite of what it was).
                    if ( invokerLogContent != null && invokerLogContent.contains( JavadocUtil.ERROR_INIT_VM ) )
                    {
                        throw new MavenReportException( e.getMessage(), e );
                    }
                }
                finally
                {
                    // just create the directory to prevent repeated invocations..
                    if ( !location.exists() )
                    {
                        getLog().warn( "Creating fake javadoc directory to prevent repeated invocations: " + location );
                        location.mkdirs();
                    }
                }
            }

            if ( location.exists() )
            {
                String url = getJavadocLink( p );

                OfflineLink ol = new OfflineLink();
                ol.setUrl( url );
                ol.setLocation( location.getAbsolutePath() );

                if ( getLog().isDebugEnabled() )
                {
                    getLog().debug( "Added Javadoc offline link: " + url + " for the module: " + p.getId() );
                }

                modulesLinks.add( ol );
            }
        }

        return modulesLinks;
    }

    /**
     * Using Maven, a Javadoc link is given by <code>${project.url}/apidocs</code>.
     *
     * @return the detected Javadoc links using the Maven conventions for all dependencies defined in the current
     *         project or an empty list.
     * @see #detectLinks
     * @see #isValidJavadocLink
     * @since 2.6
     */
    private List<String> getDependenciesLinks()
    {
        if ( !detectLinks )
        {
            return Collections.emptyList();
        }

        getLog().debug( "Trying to add links for dependencies..." );

        List<String> dependenciesLinks = new ArrayList<>();

        final Set<Artifact> dependencies = project.getDependencyArtifacts();
        for ( Artifact artifact : dependencies )
        {
            if ( artifact.getFile() == null || !artifact.getFile().exists() )
            {
                continue;
            }

            Optional<DependencyLink> depLink =
                this.dependencyLinks.stream().filter( d -> matches( d, artifact ) ).findAny();
            
            final String url;
            final boolean detected;
            if ( depLink.isPresent() )
            {
                url = depLink.get().getUrl();
                detected = false;
            }
            else
            {
                try
                {
                    MavenProject artifactProject =
                        mavenProjectBuilder.build( artifact, getProjectBuildingRequest( project ) ).getProject();

                    url = getJavadocLink( artifactProject );
                    detected = true;
                }
                catch ( ProjectBuildingException e )
                {
                    logError( "ProjectBuildingException for " + artifact.toString() + ": " + e.getMessage(), e );
                    continue;
                }
            }
            
            if ( url != null && isValidJavadocLink( url, detected ) )
            {
                getLog().debug( "Added Javadoc link: " + url + " for " + artifact.getId() );

                dependenciesLinks.add( url );
            }
        }

        return dependenciesLinks;
    }

    private boolean matches( DependencyLink d, Artifact artifact )
    {
        if ( d.getGroupId() != null && !d.getGroupId().equals( artifact.getGroupId() ) )
        {
            return false;
        }
        if ( d.getArtifactId() != null && !d.getArtifactId().equals( artifact.getArtifactId() ) )
        {
            return false;
        }
        if ( d.getClassifier() != null && !d.getClassifier().equals( artifact.getClassifier() ) )
        {
            return false;
        }
        return true;
    }

    /**
     * @return if {@link #detectJavaApiLink}, the Java API link based on the {@link #javaApiLinks} properties and the
     *         value of the <code>source</code> parameter in the
     *         <code>org.apache.maven.plugins:maven-compiler-plugin</code>
     *         defined in <code>${project.build.plugins}</code> or in <code>${project.build.pluginManagement}</code>,
     *         or the {@link #javadocRuntimeVersion}, or <code>null</code> if not defined.
     * @see #detectJavaApiLink
     * @see #javaApiLinks
     * @see <a href="http://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#source">source parameter</a>
     * @since 2.6
     */
    protected final OfflineLink getDefaultJavadocApiLink()
    {
        if ( !detectJavaApiLink )
        {
            return null;
        }

        final JavaVersion javaApiversion;
        if ( release != null )
        {
            javaApiversion = JavaVersion.parse( release );
        }
        else if ( source != null && !source.isEmpty() )
        {
            javaApiversion = JavaVersion.parse( source );
        }
        else
        {
            final String pluginId = "org.apache.maven.plugins:maven-compiler-plugin";
            String sourceConfigured = getPluginParameter( project, pluginId, "source" );
            if ( sourceConfigured != null )
            {
                javaApiversion = JavaVersion.parse( sourceConfigured );
            }
            else
            {
                getLog().debug( "No maven-compiler-plugin defined in ${build.plugins} or in "
                                    + "${project.build.pluginManagement} for the " + project.getId()
                                    + ". Added Javadoc API link according the javadoc executable version i.e.: "
                                    + javadocRuntimeVersion );

                javaApiversion = javadocRuntimeVersion;
            }
        }

        final String javaApiKey;
        if ( javaApiversion.asMajor().isAtLeast( "9" ) )
        {
            javaApiKey = "api_" + javaApiversion.asMajor();
        }
        else
        {
            javaApiKey = "api_1." + javaApiversion.asMajor().toString().charAt( 0 );
        }

        final String javaApiLink;
        if ( javaApiLinks != null && javaApiLinks.containsKey( javaApiKey ) )
        {
            javaApiLink = javaApiLinks.getProperty( javaApiKey );
        }
        else if ( javaApiversion.isAtLeast( "16" ) )
        {
            javaApiLink = null; // JDK-8216497
        }
        else if ( javaApiversion.isAtLeast( "11" ) )
        {
            javaApiLink =
                String.format( "https://docs.oracle.com/en/java/javase/%s/docs/api/", javaApiversion.getValue( 1 ) );
        }
        else if ( javaApiversion.asMajor().isAtLeast( "6" ) )
        {
            javaApiLink =
                String.format( "https://docs.oracle.com/javase/%s/docs/api/", javaApiversion.asMajor().getValue( 1 ) );
        }
        else if ( javaApiversion.isAtLeast( "1.5" ) )
        {
            javaApiLink = "https://docs.oracle.com/javase/1.5.0/docs/api/";
        }
        else
        {
            javaApiLink = null;
        }

        if ( getLog().isDebugEnabled() )
        {
            if ( javaApiLink != null )
            {
                getLog().debug( "Found Java API link: " + javaApiLink );
            }
            else
            {
                getLog().debug( "No Java API link found." );
            }
        }

        if ( javaApiLink == null )
        {
            return null;
        }

        final Path javaApiListFile;
        final String resourceName;
        if ( javaApiversion.isAtLeast( "10" ) )
        {
            javaApiListFile = getJavadocOptionsFile().getParentFile().toPath().resolve( "element-list" );
            resourceName = "java-api-element-list-" + javaApiversion.toString().substring( 0, 2 );
        }
        else if ( javaApiversion.asMajor().isAtLeast( "9" ) )
        {
            javaApiListFile = getJavadocOptionsFile().getParentFile().toPath().resolve( "package-list" );
            resourceName = "java-api-package-list-9";
        }
        else
        {
            javaApiListFile = getJavadocOptionsFile().getParentFile().toPath().resolve( "package-list" );
            resourceName = "java-api-package-list-1." + javaApiversion.asMajor().toString().charAt( 0 );
        }

        OfflineLink link = new OfflineLink();
        link.setLocation( javaApiListFile.getParent().toAbsolutePath().toString() );
        link.setUrl( javaApiLink );

        InputStream in = this.getClass().getResourceAsStream( resourceName );
        if ( in != null )
        {
            try ( InputStream closableIS = in )
            {
                // TODO only copy when changed
                Files.copy( closableIS, javaApiListFile, StandardCopyOption.REPLACE_EXISTING );
            }
            catch ( IOException ioe )
            {
                logError( "Can't get " + resourceName + ": " + ioe.getMessage(), ioe );
                return null;
            }
        }

        return link;
    }

    /**
     * Follows all of the given links, and returns their last redirect locations. Ordering is kept.
     * This is necessary because javadoc tool doesn't follow links, see JDK-8190312 (MJAVADOC-427, MJAVADOC-487)
     *
     * @param links Links to follow.
     * @return Last redirect location of all the links.
     */
    private Set<String> followLinks( Set<String> links )
    {
        Set<String> redirectLinks = new LinkedHashSet<>( links.size() );
        for ( String link : links )
        {
            try
            {
                redirectLinks.add( JavadocUtil.getRedirectUrl( new URI( link ).toURL(), settings ).toString() );
            }
            catch ( Exception e )
            {
                // only print in debug, it should have been logged already in warn/error because link isn't valid
                getLog().debug( "Could not follow " + link + ". Reason: " + e.getMessage() );

                // Even when link produces error it should be kept in the set because the error might be caused by
                // incomplete redirect configuration on the server side.
                // This partially restores the previous behaviour before fix for MJAVADOC-427
                redirectLinks.add( link );
            }
        }
        return redirectLinks;
    }

    /**
     * @param link not null
     * @param detecting <code>true</code> if the link is generated by
     * <code>detectLinks</code>, or <code>false</code> otherwise
     * @return <code>true</code> if the link has a <code>/package-list</code>, <code>false</code> otherwise.
     * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javadoc.html#package-list">
     *      package-list spec</a>
     * @since 2.6
     */
    protected boolean isValidJavadocLink( String link, boolean detecting )
    {
        try
        {
            final URI packageListUri;
            final URI elementListUri;

            if ( link.trim().toLowerCase( Locale.ENGLISH ).startsWith( "http:" ) || link.trim().toLowerCase(
                Locale.ENGLISH ).startsWith( "https:" ) || link.trim().toLowerCase( Locale.ENGLISH ).startsWith(
                "ftp:" ) || link.trim().toLowerCase( Locale.ENGLISH ).startsWith( "file:" ) )
            {
                packageListUri = new URI( link + '/' + PACKAGE_LIST );
                elementListUri = new URI( link + '/' + ELEMENT_LIST );
            }
            else
            {
                // links can be relative paths or files
                File dir = new File( link );
                if ( !dir.isAbsolute() )
                {
                    dir = new File( getOutputDirectory(), link );
                }
                if ( !dir.isDirectory() )
                {
                    if ( detecting )
                    {
                        getLog().warn( "The given File link: " + dir + " is not a dir." );
                    }
                    else
                    {
                        getLog().error( "The given File link: " + dir + " is not a dir." );
                    }
                }
                packageListUri = new File( dir, PACKAGE_LIST ).toURI();
                elementListUri = new File( dir, ELEMENT_LIST ).toURI();
            }


            try
            {
                if ( JavadocUtil.isValidElementList( elementListUri.toURL(), settings, validateLinks ) )
                {
                    return true;
                }
            }
            catch ( IOException e )
            {
            }

            if ( JavadocUtil.isValidPackageList( packageListUri.toURL(), settings, validateLinks ) )
            {
                return true;
            }

            if ( getLog().isErrorEnabled() )
            {
                if ( detecting )
                {
                    getLog().warn( "Invalid links: "
                                    + link + " with /" + PACKAGE_LIST + " or / " + ELEMENT_LIST + ". Ignored it." );
                }
                else
                {
                    getLog().error( "Invalid links: "
                                    + link + " with /" + PACKAGE_LIST + " or / " + ELEMENT_LIST + ". Ignored it." );
                }
            }

            return false;
        }
        catch ( URISyntaxException e )
        {
            if ( getLog().isErrorEnabled() )
            {
                if ( detecting )
                {
                    getLog().warn( "Malformed link: " + e.getInput() + ". Ignored it." );
                }
                else
                {
                    getLog().error( "Malformed link: " + e.getInput() + ". Ignored it." );
                }
            }
            return false;
        }
        catch ( IOException e )
        {
            if ( getLog().isErrorEnabled() )
            {
                if ( detecting )
                {
                    getLog().warn( "Error fetching link: " + link + ". Ignored it." );
                }
                else
                {
                    getLog().error( "Error fetching link: " + link + ". Ignored it." );
                }
            }
            return false;
        }
    }

    /**
     * Write a debug javadoc script in case of command line error or in debug mode.
     *
     * @param cmdLine                the current command line as string, not null.
     * @param javadocOutputDirectory the output dir, not null.
     * @see #executeJavadocCommandLine(Commandline, File)
     * @since 2.6
     */
    private void writeDebugJavadocScript( String cmdLine, File javadocOutputDirectory )
    {
        File commandLineFile = new File( javadocOutputDirectory, DEBUG_JAVADOC_SCRIPT_NAME );
        commandLineFile.getParentFile().mkdirs();

        try
        {
            FileUtils.fileWrite( commandLineFile.getAbsolutePath(), null /* platform encoding */, cmdLine );

            if ( !SystemUtils.IS_OS_WINDOWS )
            {
                Runtime.getRuntime().exec( new String[]{ "chmod", "a+x", commandLineFile.getAbsolutePath() } );
            }
        }
        catch ( IOException e )
        {
            logError( "Unable to write '" + commandLineFile.getName() + "' debug script file", e );
        }
    }

    /**
     * Check if the Javadoc JVM is correctly started or not.
     *
     * @param output the command line output, not null.
     * @return <code>true</code> if Javadoc output command line contains Javadoc word, <code>false</code> otherwise.
     * @see #executeJavadocCommandLine(Commandline, File)
     * @since 2.6.1
     */
    private boolean isJavadocVMInitError( String output )
    {
        /*
         * see main.usage and main.Building_tree keys from
         * com.sun.tools.javadoc.resources.javadoc bundle in tools.jar
         */
        return !( output.contains( "Javadoc" ) || output.contains( "javadoc" ) );
    }

    // ----------------------------------------------------------------------
    // Static methods
    // ----------------------------------------------------------------------

    /**
     * @param p not null
     * @return the javadoc link based on the project url i.e. <code>${project.url}/${destDir}</code> where
     *         <code>destDir</code> is configued in the Javadoc plugin configuration (<code>apidocs</code> by default).
     * @since 2.6
     */
    private static String getJavadocLink( MavenProject p )
    {
        if ( p.getUrl() == null )
        {
            return null;
        }

        String url = cleanUrl( p.getUrl() );
        String destDir = "apidocs"; // see JavadocReport#destDir

        final String pluginId = "org.apache.maven.plugins:maven-javadoc-plugin";
        String destDirConfigured = getPluginParameter( p, pluginId, "destDir" );
        if ( destDirConfigured != null )
        {
            destDir = destDirConfigured;
        }

        return url + "/" + destDir;
    }

    /**
     * @param url could be null.
     * @return the url cleaned or empty if url was null.
     * @since 2.6
     */
    private static String cleanUrl( String url )
    {
        if ( url == null )
        {
            return "";
        }

        url = url.trim();
        while ( url.endsWith( "/" ) )
        {
            url = url.substring( 0, url.lastIndexOf( "/" ) );
        }

        return url;
    }

    /**
     * @param p        not null
     * @param pluginId not null key of the plugin defined in {@link org.apache.maven.model.Build#getPluginsAsMap()}
     *                 or in {@link org.apache.maven.model.PluginManagement#getPluginsAsMap()}
     * @return the Maven plugin defined in <code>${project.build.plugins}</code> or in
     *         <code>${project.build.pluginManagement}</code>, or <code>null</code> if not defined.
     * @since 2.6
     */
    private static Plugin getPlugin( MavenProject p, String pluginId )
    {
        if ( ( p.getBuild() == null ) || ( p.getBuild().getPluginsAsMap() == null ) )
        {
            return null;
        }

        Plugin plugin = p.getBuild().getPluginsAsMap().get( pluginId );

        if ( ( plugin == null ) && ( p.getBuild().getPluginManagement() != null ) && (
            p.getBuild().getPluginManagement().getPluginsAsMap() != null ) )
        {
            plugin = p.getBuild().getPluginManagement().getPluginsAsMap().get( pluginId );
        }

        return plugin;
    }

    /**
     * @param p        not null
     * @param pluginId not null
     * @param param    not null
     * @return the simple parameter as String defined in the plugin configuration by <code>param</code> key
     *         or <code>null</code> if not found.
     * @since 2.6
     */
    private static String getPluginParameter( MavenProject p, String pluginId, String param )
    {
//        p.getGoalConfiguration( pluginGroupId, pluginArtifactId, executionId, goalId );
        Plugin plugin = getPlugin( p, pluginId );
        if ( plugin != null )
        {
            Xpp3Dom xpp3Dom = (Xpp3Dom) plugin.getConfiguration();
            if ( xpp3Dom != null && xpp3Dom.getChild( param ) != null
                && StringUtils.isNotEmpty( xpp3Dom.getChild( param ).getValue() ) )
            {
                return xpp3Dom.getChild( param ).getValue();
            }
        }

        return null;
    }

    /**
     * Construct the output file for the generated javadoc-options XML file, after creating the
     * javadocOptionsDir if necessary. This method does NOT write to the file in question.
     *
     * @return The options {@link File} file.
     * @since 2.7
     */
    protected final File getJavadocOptionsFile()
    {
        if ( javadocOptionsDir != null && !javadocOptionsDir.exists() )
        {
            javadocOptionsDir.mkdirs();
        }

        return new File( javadocOptionsDir, "javadoc-options-" + getAttachmentClassifier() + ".xml" );
    }

    /**
     * Generate a javadoc-options XML file, for either bundling with a javadoc-resources artifact OR
     * supplying to a distro module in a includeDependencySources configuration, so the javadoc options
     * from this execution can be reconstructed and merged in the distro build.
     *
     * @return {@link JavadocOptions}
     * @throws IOException {@link IOException}
     * @since 2.7
     */
    protected final JavadocOptions buildJavadocOptions()
        throws IOException
    {
        JavadocOptions options = new JavadocOptions();

        options.setBootclasspathArtifacts( toList( bootclasspathArtifacts ) );
        options.setDocfilesSubdirsUsed( docfilessubdirs );
        options.setDocletArtifacts( toList( docletArtifact, docletArtifacts ) );
        options.setExcludedDocfilesSubdirs( excludedocfilessubdir );
        options.setExcludePackageNames( toList( excludePackageNames ) );
        options.setGroups( toList( groups ) );
        options.setLinks( links );
        options.setOfflineLinks( toList( offlineLinks ) );
        options.setResourcesArtifacts( toList( resourcesArtifacts ) );
        options.setTagletArtifacts( toList( tagletArtifact, tagletArtifacts ) );
        options.setTaglets( toList( taglets ) );
        options.setTags( toList( tags ) );

        if ( getProject() != null && getJavadocDirectory() != null )
        {
            options.setJavadocResourcesDirectory(
                toRelative( getProject().getBasedir(), getJavadocDirectory().getAbsolutePath() ) );
        }

        File optionsFile = getJavadocOptionsFile();

        try ( Writer writer = WriterFactory.newXmlWriter( optionsFile ) )
        {
            new JavadocOptionsXpp3Writer().write( writer, options );
        }

        return options;
    }

    /**
     * Override this if you need to provide a bundle attachment classifier, as in the case of test
     * javadocs.
     * @return The attachment classifier.
     */
    protected String getAttachmentClassifier()
    {
        return JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER;
    }

    /**
     * Logs an error with throwable content only if in debug.
     *
     * @param message The message which should be announced.
     * @param t The throwable part of the message.
     */
    protected void logError( String message, Throwable t )
    {
        if ( getLog().isDebugEnabled() )
        {
            getLog().error( message, t );
        }
        else
        {
            getLog().error( message );
        }
    }

    /**
     * @param prefix The prefix of the exception.
     * @param e The exception.
     * @throws MojoExecutionException {@link MojoExecutionException} issue while generating report
     */
    protected void failOnError( String prefix, Exception e )
        throws MojoExecutionException
    {
        if ( failOnError )
        {
            if ( e instanceof RuntimeException )
            {
                throw (RuntimeException) e;
            }
            throw new MojoExecutionException( prefix + ": " + e.getMessage(), e );
        }

        getLog().error( prefix + ": " + e.getMessage(), e );
    }


    /**
     *
     * @return List of projects to be part of aggregated javadoc
     */
    private List<MavenProject> getAggregatedProjects()
    {
        if ( this.reactorProjects == null )
        {
           return Collections.emptyList();
        }
        Map<Path, MavenProject> reactorProjectsMap = new HashMap<>();
        for ( MavenProject reactorProject : this.reactorProjects )
        {
            if ( !isSkippedJavadoc( reactorProject )
                    &&  !isSkippedModule( reactorProject ) )
            {
                reactorProjectsMap.put( reactorProject.getBasedir().toPath(), reactorProject );
            }
        }

        return new ArrayList<>( modulesForAggregatedProject( project, reactorProjectsMap ) );
    }

    /**
     *
     * @return <code>true</code> if the module need to be skipped from aggregate generation
     */
    protected boolean isSkippedModule( MavenProject mavenProject )
    {
        if ( StringUtils.isEmpty( this.skippedModules ) )
        {
            return false;
        }
        List<String> modulesToSkip = Arrays.asList( StringUtils.split( this.skippedModules, ',' ) );
        return modulesToSkip.contains( mavenProject.getArtifactId() );
    }

    /**
     *
     * @return <code>true</code> if the pom configuration skip javadoc generation for the project
     */
    protected boolean isSkippedJavadoc( MavenProject mavenProject )
    {
        String property = mavenProject.getProperties().getProperty( "maven.javadoc.skip" );
        if ( property != null )
        {
            boolean skip = BooleanUtils.toBoolean( property );
            getLog().debug( "isSkippedJavadoc " + mavenProject + " " + skip );
            return skip;
        }
        final String pluginId = "org.apache.maven.plugins:maven-javadoc-plugin";
        property = getPluginParameter( mavenProject, pluginId, "skip" );
        if ( property != null )
        {
            boolean skip = BooleanUtils.toBoolean( property );
            getLog().debug( "isSkippedJavadoc " + mavenProject + " " + skip );
            return skip;
        }
        if ( mavenProject.getParent() != null )
        {
            return isSkippedJavadoc( mavenProject.getParent() );
        }
        getLog().debug( "isSkippedJavadoc " + mavenProject + " " + false );
        return false;
    }

}
