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.ClassUtils;
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.plugin.MojoFailureException;
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.LocationManager;
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.StringUtils;
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.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
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.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.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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>
 * @version $Id: AbstractJavadocMojo.java 1801354 2017-07-09 08:49:46Z rfscholte $
 * @see <a href="http://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 default Javadoc API urls according the
     * <a href="http://www.oracle.com/technetwork/java/javase/documentation/api-jsp-136079.html">Sun API
     * Specifications</a>:
     * <pre>
     * &lt;javaApiLinks&gt;
     *   &lt;property&gt;
     *     &lt;name&gt;api_1.3&lt;/name&gt;
     *     &lt;value&gt;http://docs.oracle.com/javase/1.3/docs/api/&lt;/value&gt;
     *   &lt;/property&gt;
     *   &lt;property&gt;
     *     &lt;name&gt;api_1.4&lt;/name&gt;
     *     &lt;value&gt;http://docs.oracle.com/javase/1.4.2/docs/api/&lt;/value&gt;
     *   &lt;/property&gt;
     *   &lt;property&gt;
     *     &lt;name&gt;api_1.5&lt;/name&gt;
     *     &lt;value&gt;http://docs.oracle.com/javase/1.5.0/docs/api/&lt;/value&gt;
     *   &lt;/property&gt;
     *   &lt;property&gt;
     *     &lt;name&gt;api_1.6&lt;/name&gt;
     *     &lt;value&gt;http://docs.oracle.com/javase/6/docs/api/&lt;/value&gt;
     *   &lt;/property&gt;
     *   &lt;property&gt;
     *     &lt;name&gt;api_1.7&lt;/name&gt;
     *     &lt;value&gt;http://docs.oracle.com/javase/7/docs/api/&lt;/value&gt;
     *   &lt;/property&gt;
     *   &lt;property&gt;
     *     &lt;name&gt;api_1.8&lt;/name&gt;
     *     &lt;value&gt;http://docs.oracle.com/javase/8/docs/api/&lt;/value&gt;
     *   &lt;/property&gt;
     * &lt;/javaApiLinks&gt;
     * </pre>
     *
     * @since 2.6
     */
    public static final Properties DEFAULT_JAVA_API_LINKS = new Properties();

    /**
     * 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="http://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="http://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="http://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="http://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="http://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;

    // ----------------------------------------------------------------------
    // 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. This value should include quotes as necessary for
     * parameters that include spaces. 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="http://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="http://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/plugin/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="http://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
     * @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>http://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/plugin/javadoc/AbstractJavadocMojo.html#DEFAULT_JAVA_API_LINKS">Javadoc</a>
     * for the default values.
     * <br/>
     *
     * @see #links
     * @see #javaApiLinks
     * @see #DEFAULT_JAVA_API_LINKS
     * @since 2.6
     */
    @Parameter( property = "detectJavaApiLink", defaultValue = "true" )
    private boolean detectJavaApiLink;

    /**
     * Use this parameter <b>only</b> if the <a href="http://java.sun.com/reference/api/index.html">Sun Javadoc API</a>
     * urls have been changed or to use custom urls for Javadoc API url.
     * <br/>
     * See
     * <a href="./apidocs/org/apache/maven/plugin/javadoc/AbstractJavadocMojo.html#DEFAULT_JAVA_API_LINKS">Javadoc</a>
     * for the default values.
     * <br/>
     *
     * @see #DEFAULT_JAVA_API_LINKS
     * @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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#bootclasspath">bootclasspath</a>.
     * <br/>
     *
     * @since 2.5
     */
    @Parameter( property = "bootclasspath" )
    private String bootclasspath;

    /**
     * Specifies the artifacts where the boot classes reside.
     * <br/>
     * See <a
     * href="http://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/plugin/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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#breakiterator">breakiterator</a>.
     * <br/>
     * Since <a href="http://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="http://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="http://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/plugin/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="http://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/plugin/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="http://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="http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#exclude">exclude</a>.
     * <br/>
     * Since <a href="http://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="http://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="http://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="http://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="http://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="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4714350">4714350</a>).
     * <br/>
     * See <a href="http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#public">public</a>
     * (shows only public classes and members)</li>
     * <li><a href="http://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="http://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="http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#source">source</a>.
     * <br/>
     * Since <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.html#summary">Java
     * 1.4</a>.
     */
    @Parameter( property = "source" )
    private String source;

    /**
     * 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="http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#subpackages">subpackages</a>.
     * <br/>
     * Since <a href="http://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="http://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="http://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/>
     * eg. <code>&lt;![CDATA[Copyright 2005, &lt;a href="http://www.mycompany.com">MyCompany, Inc.&lt;a>]]&gt;</code>
     * <br/>
     * See <a href="http://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="http://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="http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#docfilessubdirs">
     * docfilessubdirs</a>.
     * <br/>
     * Since <a href="http://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="http://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="http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#excludedocfilessubdir">
     * excludedocfilessubdir</a>.
     * <br/>
     * Since <a href="http://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="http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#group">group</a>.
     * <br/>
     * See <a href="./apidocs/org/apache/maven/plugin/javadoc/options/Group.html">Javadoc</a>.
     * <br/>
     */
    @Parameter( property = "groups" )
    private Group[] groups;

    /**
     * Specifies the header text to be placed at the top of each output file.
     * <br/>
     * See <a href="http://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="http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#keywords">keywords</a>.
     * <br/>
     * Since
     * <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/whatsnew-1.4.2.html#commandlineoptions">
     * Java 1.4.2</a>.
     * <br/>
     * Since
     * <a href="http://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;http://docs.oracle.com/javase/1.4.2/docs/api&lt;/link&gt;
     * &lt;links&gt;
     * </pre>
     * will be used because <code>http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#link">link</a>.
     *
     * @see #detectLinks
     * @see #detectJavaApiLink
     */
    @Parameter( property = "links" )
    protected ArrayList<String> links;

    /**
     * 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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#linksource">linksource</a>.
     * <br/>
     * Since <a href="http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#nocomment">nocomment</a>.
     * <br/>
     * Since <a href="http://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="http://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="http://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="http://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="http://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="http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#noqualifier">noqualifier</a>.
     * <br/>
     * Since <a href="http://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="http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#notimestamp">notimestamp</a>.
     * <br/>
     * Since
     * <a href="http://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="http://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="http://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;http://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/plugin/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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#d">d</a> option
     */
    @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="http://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="http://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="http://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="http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#stylesheetfile">
     * stylesheetfile</a>.
     */
    @Parameter( property = "stylesheetfile" )
   private String stylesheetfile;

    /**
     * Specifies the class file that starts the taglet used in generating the documentation for that tag.
     * <br/>
     * See <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#taglet">taglet</a>.
     * <br/>
     * Since
     * <a href="http://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="http://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/plugin/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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#taglet">taglet</a>.
     * <br/>
     * See
     * <a href="http://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/plugin/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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#tagletpath">tagletpath</a>.
     * <br/>
     * Since
     * <a href="http://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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#taglet">taglet</a>.
     * <br/>
     * See
     * <a href="http://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/plugin/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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#tag">tag</a>.
     * <br/>
     * Since
     * <a href="http://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/plugin/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="http://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="http://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="http://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
     */
    @Parameter( defaultValue = "false" )
    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.
     */
    @Parameter
    private List<String> sourceFileIncludes;

    /**
     * exclude filters on the source files.
     * These are ignored if you specify subpackages or subpackage excludes.
     */
    @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>
     * Specify the requirements for this jdk toolchain.
     * This overrules the toolchain selected by the maven-toolchain-plugin.
     * </p>
     * <strong>note:</strong> requires at least Maven 3.3.1
     * 
     * @since 3.0.0
     */
    @Parameter
    private Map<String, String> jdkToolchain;

    // ----------------------------------------------------------------------
    // static
    // ----------------------------------------------------------------------

    static
    {
        DEFAULT_JAVA_API_LINKS.put( "api_1.5", "https://docs.oracle.com/javase/1.5.0/docs/api/" );
        DEFAULT_JAVA_API_LINKS.put( "api_1.6", "https://docs.oracle.com/javase/6/docs/api/" );
        DEFAULT_JAVA_API_LINKS.put( "api_1.7", "https://docs.oracle.com/javase/7/docs/api/" );
        DEFAULT_JAVA_API_LINKS.put( "api_1.8", "https://docs.oracle.com/javase/8/docs/api/" );
        DEFAULT_JAVA_API_LINKS.put( "api_9",   "https://docs.oracle.com/javase/9/docs/api/" );
        DEFAULT_JAVA_API_LINKS.put( "api_10",  "https://docs.oracle.com/javase/10/docs/api/" );
        DEFAULT_JAVA_API_LINKS.put( "api_11",  "https://docs.oracle.com/en/java/javase/11/docs/api" );
    }

    // ----------------------------------------------------------------------
    // 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() ) );
    }

    /**
     * @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, MojoFailureException
    {
        verifyRemovedParameter( "aggregator" );
        verifyRemovedParameter( "proxyHost" );
        verifyRemovedParameter( "proxyPort" );
        verifyReplacedParameter( "additionalparam", "additionalOptions" );

        doExecute();
    }

    abstract void doExecute() throws MojoExecutionException, MojoFailureException;

    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 );
        }

        Map<String, Collection<String>> sourcePaths = getSourcePaths();
        
        Collection<String> collectedSourcePaths = collect( sourcePaths.values() );
        
        List<String> files = getFiles( collectedSourcePaths );
        if ( !canGenerateReport( files ) )
        {
            return;
        }

        List<String> packageNames = getPackageNames( collectedSourcePaths, files );
        List<String> filesWithUnnamedPackages = getFilesWithUnnamedPackages( collectedSourcePaths, files );

        // ----------------------------------------------------------------------
        // 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 ) );

        // ----------------------------------------------------------------------
        // 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 );
            }
        }

        List<String> arguments = new ArrayList<>();

        // ----------------------------------------------------------------------
        // Wrap Javadoc options
        // ----------------------------------------------------------------------

        addJavadocOptions( javadocOutputDirectory, arguments, sourcePaths );

        // ----------------------------------------------------------------------
        // Wrap Standard doclet Options
        // ----------------------------------------------------------------------

        if ( StringUtils.isEmpty( doclet ) || useStandardDocletOptions )
        {
            addStandardDocletOptions( javadocOutputDirectory, arguments );
        }

        // ----------------------------------------------------------------------
        // Write options file and include it in the command line
        // ----------------------------------------------------------------------

        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
            // ----------------------------------------------------------------------

            if ( !filesWithUnnamedPackages.isEmpty() )
            {
                addCommandLineArgFile( cmd, javadocOutputDirectory, filesWithUnnamedPackages );
            }
        }
        else
        {
            // ----------------------------------------------------------------------
            // Write argfile file and include it in the command line
            // ----------------------------------------------------------------------

            if ( !files.isEmpty() )
            {
                addCommandLineArgFile( cmd, javadocOutputDirectory, files );
            }
        }

        // ----------------------------------------------------------------------
        // 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" );
        }
    }

    protected final Collection<String> collect( Collection<Collection<String>> sourcePaths )
    {
        Collection<String> collectedSourcePaths = new LinkedHashSet<>();
        for ( Collection<String> sp : sourcePaths )
        {
            collectedSourcePaths.addAll( sp );
        }
        return collectedSourcePaths;
    }

    /**
     * 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}
     */
    protected List<String> getFiles( Collection<String> sourcePaths )
        throws MavenReportException
    {
        List<String> files = new ArrayList<>();
        if ( StringUtils.isEmpty( subpackages ) )
        {
            Collection<String> excludedPackages = getExcludedPackages();
            
            for ( String sourcePath : sourcePaths )
            {
                File sourceDirectory = new File( sourcePath );
                files.addAll( JavadocUtil.getFilesFromSource( sourceDirectory, sourceFileIncludes, sourceFileExcludes,
                                                              excludedPackages ) );
            }
        }

        return files;
    }

    /**
     * Method to get the source paths. If no source path is specified in the parameter, the compile source roots
     * of the project will be used.
     *
     * @return a Collection of the project absolute source paths as <code>String</code>
     * @throws MavenReportException {@link MavenReportException}
     * @see JavadocUtil#pruneDirs(MavenProject, Collection)
     */
    protected Map<String, Collection<String>> getSourcePaths()
        throws MavenReportException
    {
        Map<String, Collection<String>> mappedSourcePaths = new LinkedHashMap<>();

        if ( StringUtils.isEmpty( sourcepath ) )
        {
            
            Set<String> 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<String> l = JavadocUtil.pruneDirs( project, Collections.singletonList(
                        getJavadocDirectory().getAbsolutePath() ) );
                    sourcePaths.addAll( l );
                }
            }
            mappedSourcePaths.put( ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ),
                                   sourcePaths );
            
            if ( includeDependencySources )
            {
                mappedSourcePaths.putAll( getDependencySourcePaths() );
            }

            if ( isAggregator() )
            {
                for ( MavenProject subProject : getAggregatedProjects() )
                {
                    if ( subProject != project )
                    {
                        Collection<String> 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<String> l = JavadocUtil.pruneDirs( subProject, Collections.singletonList(
                                        javadocDir.getAbsolutePath() ) );
                                additionalSourcePaths.addAll( l );
                            }
                        }
                        mappedSourcePaths.put( ArtifactUtils.versionlessKey( subProject.getGroupId(),
                                                                             subProject.getArtifactId() ),
                                               additionalSourcePaths );
                    }
                }
            }
        }
        else
        {
            Collection<String> sourcePaths = new ArrayList<>( Arrays.asList( JavadocUtil.splitPath( sourcepath ) ) );
            sourcePaths = JavadocUtil.pruneDirs( project, sourcePaths );
            if ( getJavadocDirectory() != null )
            {
                Collection<String> l = JavadocUtil.pruneDirs( project, Collections.singletonList(
                    getJavadocDirectory().getAbsolutePath() ) );
                sourcePaths.addAll( l );
            }
            mappedSourcePaths.put( ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ),
                                   sourcePaths );
        }

        return mappedSourcePaths;
    }

    private Collection<MavenProject> getAggregatedProjects()
    {
        Map<Path, MavenProject> reactorProjectsMap = new HashMap<>();
        for ( MavenProject reactorProject : this.reactorProjects )
        {
            reactorProjectsMap.put( reactorProject.getBasedir().toPath(), reactorProject );
        }
        
        return modulesForAggregatedProject( project, reactorProjectsMap );
    }

    /**
     * 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 
     * @throws MavenReportException if any
     */
    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 );
        }

        List<Path> modulePaths = new LinkedList<Path>();
        for ( String module :  aggregatedProject.getModules() )
        {
            modulePaths.add( new File( aggregatedProject.getBasedir(), module ).toPath() );
        }

        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 Map<String, Collection<String>> 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();

        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 ) );
            }

            config.withFilter( new AndFilter( andFilters ) );
        }

        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()
    {
        return configureDependencySourceResolution(
                        new SourceResolverConfig( project, session.getProjectBuildingRequest(),
                                                  sourceDependencyCacheDir ).withReactorProjects( reactorProjects ) );
    }

    /**
     * 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( List<String> files )
    {
        boolean canGenerate = true;

        if ( files.isEmpty() && StringUtils.isEmpty( subpackages ) )
        {
            canGenerate = false;
        }

        return canGenerate;
    }

    // ----------------------------------------------------------------------
    // 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<String> sourceFolders )
        throws MavenReportException
    {
        List<String> excludedNames = null;
        
        Collection<Path> sourcePaths = new ArrayList<>( sourceFolders.size() );
        for ( String folder : sourceFolders )
        {
            sourcePaths.add( Paths.get( folder ) );
        }

        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<String> 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 List<File> getPathElements()
        throws MavenReportException
    {
        List<File> classpathElements = new ArrayList<>();
        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 )
                {
                    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 = session.getProjectBuildingRequest();
                        buildingRequest =
                            buildingRequest.setRemoteRepositories( subProject.getRemoteArtifactRepositories() );
                        
                        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( session.getProjectBuildingRequest(), 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()
    {
        int currentYear = Calendar.getInstance().get( Calendar.YEAR );
        String year = String.valueOf( currentYear );

        String inceptionYear = project.getInceptionYear();

        String theBottom = StringUtils.replace( this.bottom, "{currentYear}", year );

        if ( inceptionYear != null )
        {
            if ( inceptionYear.equals( year ) )
            {
                theBottom = StringUtils.replace( theBottom, "{inceptionYear}&#x2013;", "" );
            }
            else
            {
                theBottom = StringUtils.replace( theBottom, "{inceptionYear}", inceptionYear );
            }
        }
        else
        {
            theBottom = StringUtils.replace( theBottom, "{inceptionYear}&#x2013;", "" );
        }

        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 String getStylesheetFile( final File javadocOutputDirectory )
    {
        if ( StringUtils.isEmpty( stylesheetfile ) )
        {
            if ( "java".equalsIgnoreCase( stylesheet ) )
            {
                // use the default Javadoc tool stylesheet
                return null;
            }

            // maven, see #copyDefaultStylesheet(File)
            return new File( javadocOutputDirectory, DEFAULT_CSS_NAME ).getAbsolutePath();
        }

        if ( new File( stylesheetfile ).exists() )
        {
            return new File( stylesheetfile ).getAbsolutePath();
        }

        return getResource( new File( javadocOutputDirectory, DEFAULT_CSS_NAME ), stylesheetfile );
    }

    /**
     * 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 String getHelpFile( final File javadocOutputDirectory )
    {
        if ( StringUtils.isEmpty( helpfile ) )
        {
            return null;
        }

        if ( new File( helpfile ).exists() )
        {
            return new File( helpfile ).getAbsolutePath();
        }

        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( getArtifactsAbsolutePath( taglet.getTagletArtifact() ) );

                pathParts = JavadocUtil.pruneFiles( pathParts );
            }
            else if ( StringUtils.isNotEmpty( taglet.getTagletpath() ) )
            {
                pathParts.add( taglet.getTagletpath() );

                pathParts = JavadocUtil.pruneDirs( project, pathParts );
            }
        }

        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( session.getProjectBuildingRequest(), 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
     */
    private Artifact createAndResolveArtifact( JavadocPathArtifact javadocArtifact )
        throws ArtifactResolverException
    {
        DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate();
        coordinate.setGroupId( javadocArtifact.getGroupId() );
        coordinate.setArtifactId( javadocArtifact.getArtifactId() );
        coordinate.setVersion( javadocArtifact.getVersion() );

        DefaultProjectBuildingRequest buildingRequest =
            new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
        buildingRequest.setRemoteRepositories( project.getRemoteArtifactRepositories() );
        
        return artifactResolver.resolveArtifact( buildingRequest, 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.getActiveProxy() == null )
        {
            return;
        }

        Proxy activeProxy = settings.getActiveProxy();
        String protocol = StringUtils.isNotEmpty( activeProxy.getProtocol() ) ? activeProxy.getProtocol() + "." : "";

        if ( StringUtils.isNotEmpty( activeProxy.getHost() ) )
        {
            cmd.createArg().setValue( "-J-D" + protocol + "proxySet=true" );
            cmd.createArg().setValue( "-J-D" + protocol + "proxyHost=" + activeProxy.getHost() );

            if ( activeProxy.getPort() > 0 )
            {
                cmd.createArg().setValue( "-J-D" + protocol + "proxyPort=" + activeProxy.getPort() );
            }

            if ( StringUtils.isNotEmpty( activeProxy.getNonProxyHosts() ) )
            {
                cmd.createArg().setValue(
                    "-J-D" + protocol + "nonProxyHosts=\"" + activeProxy.getNonProxyHosts() + "\"" );
            }

            if ( StringUtils.isNotEmpty( activeProxy.getUsername() ) )
            {
                cmd.createArg().setValue( "-J-Dhttp.proxyUser=\"" + activeProxy.getUsername() + "\"" );

                if ( StringUtils.isNotEmpty( activeProxy.getPassword() ) )
                {
                    cmd.createArg().setValue( "-J-Dhttp.proxyPassword=\"" + activeProxy.getPassword() + "\"" );
                }
            }
        }
    }

    /**
     * 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();
        }

        // ----------------------------------------------------------------------
        // Try to find javadocExe from System.getProperty( "java.home" )
        // By default, System.getProperty( "java.home" ) = JRE_HOME and JRE_HOME
        // should be in the JDK_HOME
        // ----------------------------------------------------------------------
        // For IBM's JDK 1.2
        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
        {
            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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#package-list">package-list spec</a>
     */
    private void addLinkofflineArguments( List<String> arguments )
        throws MavenReportException
    {
        Set<OfflineLink> offlineLinksList = collectOfflineLinks();

        offlineLinksList.addAll( getModulesLinks() );

        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 );
            }
        }
    }

    /**
     * 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
     * @see #detectLinks
     * @see #getDependenciesLinks()
     * @see <a href="http://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="http://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
     * @param files       not null
     * @return the list of package names for files in the sourcePaths
     */
    private List<String> getPackageNames( Collection<String> sourcePaths, List<String> files )
    {
        return getPackageNamesOrFilesWithUnnamedPackages( sourcePaths, files, true );
    }

    /**
     * @param sourcePaths could be null
     * @param files       not null
     * @return a list files with unnamed package names for files in the sourcePaths
     */
    private List<String> getFilesWithUnnamedPackages( Collection<String> sourcePaths, List<String> files )
    {
        return getPackageNamesOrFilesWithUnnamedPackages( sourcePaths, files, false );
    }

    /**
     * @param sourcePaths     not null, containing absolute and relative paths
     * @param files           not null, containing list of quoted files
     * @param onlyPackageName boolean for only package name
     * @return a list of package names or files with unnamed package names, depending the value of the unnamed flag
     * @see #getFiles
     * @see #getSourcePaths()
     */
    private List<String> getPackageNamesOrFilesWithUnnamedPackages( Collection<String> sourcePaths, List<String> files,
                                                                    boolean onlyPackageName )
    {
        List<String> returnList = new ArrayList<>();

        if ( !StringUtils.isEmpty( sourcepath ) )
        {
            return returnList;
        }

        for ( String currentFile : files )
        {
            currentFile = currentFile.replace( '\\', '/' );

            for ( String currentSourcePath : sourcePaths )
            {
                currentSourcePath = currentSourcePath.replace( '\\', '/' );

                if ( !currentSourcePath.endsWith( "/" ) )
                {
                    currentSourcePath += "/";
                }

                if ( currentFile.contains( currentSourcePath ) )
                {
                    String packagename = currentFile.substring( currentSourcePath.length() + 1 );

                    /*
                     * Remove the miscellaneous files
                     * http://docs.oracle.com/javase/1.4.2/docs/tooldocs/solaris/javadoc.html#unprocessed
                     */
                    if ( packagename.contains( "doc-files" ) )
                    {
                        continue;
                    }

                    if ( onlyPackageName && packagename.lastIndexOf( "/" ) != -1 )
                    {
                        packagename = packagename.substring( 0, packagename.lastIndexOf( "/" ) );
                        packagename = packagename.replace( '/', '.' );

                        if ( !returnList.contains( packagename ) )
                        {
                            returnList.add( packagename );
                        }
                    }
                    if ( !onlyPackageName && packagename.lastIndexOf( "/" ) == -1 )
                    {
                        returnList.add( currentFile );
                    }
                }
            }
        }

        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="http://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 ) );

        /* default to platform encoding */
        String outputFileEncoding = null;
        if ( JAVA_VERSION.isAtLeast( "9" ) )
        {
            outputFileEncoding = StandardCharsets.UTF_8.name();
        }
        try
        {
            FileUtils.fileWrite( optionsFile.getAbsolutePath(), outputFileEncoding, options.toString() );
        }
        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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#argumentfiles">
     *      Reference Guide, Command line argument files
     *      </a>
     * @see <a href="http://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 );
        }

        try
        {
            FileUtils.fileWrite( argfileFile.getAbsolutePath(), null /* platform encoding */,
                                 StringUtils.join( files.iterator(), SystemUtils.LINE_SEPARATOR ) );
        }
        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="http://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, List<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 ) && 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." );
        }

        // default java api links
        if ( javaApiLinks == null || javaApiLinks.size() == 0 )
        {
            javaApiLinks = DEFAULT_JAVA_API_LINKS;
        }
    }

    /**
     * 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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#javadocoptions">http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#javadocoptions</a>
     */
    private void addJavadocOptions( File javadocOutputDirectory,
                                    List<String> arguments,
                                    Map<String, Collection<String>> allSourcePaths )
        throws MavenReportException
    {
        Collection<String> sourcePaths = collect( allSourcePaths.values() );
        
        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 );
        }
        
        Collection<String> reactorKeys = new HashSet<>( session.getProjects().size() );
        for ( MavenProject reactorProject : session.getProjects() )
        {
            reactorKeys.add( ArtifactUtils.versionlessKey( reactorProject.getGroupId(),
                                                           reactorProject.getArtifactId() ) );
        }
        
        final LocationManager locationManager = new LocationManager();
        
        Collection<String> additionalModules = new ArrayList<>();
        
        Path moduleSourceDir = null;
        if ( allSourcePaths.size() > 1 )
        {
            for ( Map.Entry<String, Collection<String>> projectSourcepaths : allSourcePaths.entrySet() )
            {
                if ( reactorKeys.contains( projectSourcepaths.getKey() ) )
                {
                    File moduleDescriptor = findMainDescriptor( projectSourcepaths.getValue() );
                    if ( moduleDescriptor != null )
                    {
                        moduleSourceDir = javadocOutputDirectory.toPath().resolve( "src" );
                        try
                        {
                            moduleSourceDir = Files.createDirectories( moduleSourceDir );
                            ResolvePathsRequest<File> request =
                                ResolvePathsRequest.withFiles( Collections.<File>emptyList() )
                                                   .setMainModuleDescriptor( moduleDescriptor );
                            
                            String moduleName =
                                locationManager.resolvePaths( request ).getMainModuleDescriptor().name();
                            
                            additionalModules.add( moduleName );
                            
                            addArgIfNotEmpty( arguments, "--patch-module", moduleName + '='
                                + JavadocUtil.quotedPathArgument( getSourcePath( projectSourcepaths.getValue() ) ) );
                            
                            Files.createDirectories( moduleSourceDir.resolve( moduleName ) );
                        }
                        catch ( IOException e )
                        {
                            throw new MavenReportException( e.getMessage(), e );
                        }
                    }
                    else
                    {
                        // todo
                        getLog().error( "no module descriptor for " + projectSourcepaths.getKey() );
                    }
                }
                else
                {
                    // todo
                    getLog().error( "no reactor project: " + projectSourcepaths.getKey() );

                }
            }
        }

        List<String> roots = getProjectSourceRoots( getProject() );
        
        File mainDescriptor = findMainDescriptor( roots );

        if ( javadocRuntimeVersion.isAtLeast( "9" ) && ( isAggregator() || mainDescriptor != null ) && !isTest() )
        {
            ResolvePathsRequest<File> request =
                ResolvePathsRequest.withFiles( getPathElements() ).setAdditionalModules( additionalModules );
            
            if ( mainDescriptor != null )
            {
                request.setMainModuleDescriptor( mainDescriptor );
            }
            
            try
            {
                ResolvePathsResult<File> result = locationManager.resolvePaths( request );
                
                Set<File> modulePathElements = new HashSet<>( result.getModulepathElements().keySet() )  ;
                if ( allSourcePaths.size() > 1 )
                {
                    // Probably required due to bug in javadoc (Java 9+)   
                    modulePathElements.addAll( getProjectBuildOutputDirs( getProject() ) );
                }

                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
                    {
                        classPathElements.add( file );
                    }
                }
                
                String classpath = StringUtils.join( classPathElements.iterator(), File.pathSeparator );
                addArgIfNotEmpty( arguments, "--class-path", JavadocUtil.quotedPathArgument( classpath ) );
                
                String modulepath =
                    StringUtils.join( modulePathElements.iterator(), File.pathSeparator );
                addArgIfNotEmpty( arguments, "--module-path", JavadocUtil.quotedPathArgument( modulepath ) );
            }
            catch ( IOException e )
            {
                throw new MavenReportException( e.getMessage(), e );
            }
        }
        else
        {
            String classpath = StringUtils.join( getPathElements().iterator(), File.pathSeparator );
            addArgIfNotEmpty( arguments, "-classpath", JavadocUtil.quotedPathArgument( classpath ) );
        }
        
        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 );
        }

        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, "--module-source-path",
                              JavadocUtil.quotedPathArgument( moduleSourceDir.toString() ) );
        }
        else
        {
            addArgIfNotEmpty( arguments, "-sourcepath",
                              JavadocUtil.quotedPathArgument( getSourcePath( sourcePaths ) ) );
        }


        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 )
        {
            Collections.addAll( arguments, additionalOptions );
        }
    }

    private File findMainDescriptor( Collection<String> roots )
    {
        for ( String root : roots )
        {
            File descriptorFile = new File( root, "module-info.java" ).getAbsoluteFile();
            if ( descriptorFile.exists() )
            {
                return descriptorFile;
            }
        }
        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="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#standard">
     *      http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#standard</a>
     */
    private void addStandardDocletOptions( File javadocOutputDirectory, List<String> arguments )
        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 );

        addArgIfNotEmpty( arguments, "-helpfile",
                          JavadocUtil.quotedPathArgument( getHelpFile( javadocOutputDirectory ) ) );

        addArgIf( arguments, keywords, "-keywords", SINCE_JAVADOC_1_4_2 );

        addLinkArguments( arguments );

        addLinkofflineArguments( arguments );

        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" );

        addArgIfNotEmpty( arguments, "-stylesheetfile",
                          JavadocUtil.quotedPathArgument( getStylesheetFile( javadocOutputDirectory ) ) );

        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
    {
        Set<Tag> tags = collectTags();

        if ( isEmpty( tags ) )
        {
            return;
        }

        for ( Tag tag : tags )
        {
            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();
                    if ( StringUtils.isNotEmpty( tag.getHead() ) )
                    {
                        value += ":" + tag.getHead();
                    }
                }
                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 ( getLog().isDebugEnabled() )
        {
            // no quoted arguments
            getLog().debug( CommandLineUtils.toString( cmd.getCommandline() ).replaceAll( "'", "" ) );
        }

        String cmdLine = null;
        if ( debug )
        {
            cmdLine = CommandLineUtils.toString( cmd.getCommandline() ).replaceAll( "'", "" );
            cmdLine = JavadocUtil.hideProxyPassword( cmdLine, settings );

            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( "'", "" );
                    cmdLine = JavadocUtil.hideProxyPassword( cmdLine, settings );
                }
                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 ( StringUtils.isNotEmpty( err.getOutput() ) && 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 ( StringUtils.isNotEmpty( err.getOutput() ) && failOnWarnings )
        {
            throw new MavenReportException( "Project contains Javadoc Warnings" );
        }
    }

    /**
     * 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;
        InputStream in = null;
        try
        {
            in = this.getClass().getResourceAsStream( "frame-injection-fix.txt" );
            if ( in == null )
            {
                throw new FileNotFoundException( "Missing resource 'frame-injection-fix.txt' in classpath." );
            }
            fixData = StringUtils.unifyLineSeparators( IOUtil.toString( in, "US-ASCII" ) ).trim();
            in.close();
            in = null;
        }
        finally
        {
            IOUtil.close( in );
        }

        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 String 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 FileUtils.toFile( resourceURL ).getAbsolutePath();
        }

        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 FileUtils.toFile( resourceURL ).getAbsolutePath();
        }

        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 FileUtils.toFile( resourceURL ).getAbsolutePath();
            }
        }

        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 )
            {
                JavadocPathArtifact javadocPathArtifact = new JavadocPathArtifact();
                javadocPathArtifact.setGroupId( dependency.getGroupId() );
                javadocPathArtifact.setArtifactId( dependency.getArtifactId() );
                javadocPathArtifact.setVersion( dependency.getVersion() );
                Artifact artifact = null;
                try
                {
                    artifact = createAndResolveArtifact( javadocPathArtifact );
                }
                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 outputFile.getAbsolutePath();
                }
                catch ( IOException e )
                {
                    logError( "IOException: " + e.getMessage(), e );
                }
            }
        }

        getLog().warn( "Unable to find the resource '" + inputResourceName + "'. Using default Javadoc resources." );

        return null;
    }

    /**
     * @param classPath a not null String list of files where resource will be look up.
     * @param resource  a not null ressource 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 ).toURL() );
            }
            catch ( MalformedURLException e )
            {
                getLog().error( "MalformedURLException: " + e.getMessage() );
            }
        }

        ClassLoader javadocClassLoader = new URLClassLoader( urls.toArray( new URL[urls.size()] ), null );

        return javadocClassLoader.getResource( resource );
    }

    /**
     * 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;
        InputStream resourceAsStream = null;
        try
        {
            String resource = "META-INF/maven/org.apache.maven.plugins/maven-javadoc-plugin/pom.properties";
            resourceAsStream = AbstractJavadocMojo.class.getClassLoader().getResourceAsStream( resource );

            if ( resourceAsStream != null )
            {
                Properties properties = new Properties();
                properties.load( resourceAsStream );
                resourceAsStream.close();
                resourceAsStream = null;
                if ( StringUtils.isNotEmpty( properties.getProperty( "version" ) ) )
                {
                    javadocPluginVersion = properties.getProperty( "version" );
                }
            }
        }
        catch ( IOException e )
        {
            // nop
        }
        finally
        {
            IOUtil.close( resourceAsStream );
        }

        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
    {
        if ( !detectOfflineLinks || isAggregator() || reactorProjects == null )
        {
            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 : reactorProjects )
        {
            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 );
                }
                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;
            }

            try
            {
                MavenProject artifactProject =
                    mavenProjectBuilder.build( artifact, session.getProjectBuildingRequest() ).getProject();

                if ( StringUtils.isNotEmpty( artifactProject.getUrl() ) )
                {
                    String url = getJavadocLink( artifactProject );

                    if ( isValidJavadocLink( url, true ) )
                    {
                        getLog().debug( "Added Javadoc link: " + url + " for " + artifactProject.getId() );

                        dependenciesLinks.add( url );
                    }
                }
            }
            catch ( ProjectBuildingException e )
            {
                logError( "ProjectBuildingException for " + artifact.toString() + ": " + e.getMessage(), e );
            }
        }

        return dependenciesLinks;
    }

    /**
     * @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 #DEFAULT_JAVA_API_LINKS
     * @see <a href="http://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#source">source parameter</a>
     * @since 2.6
     */
    private OfflineLink getDefaultJavadocApiLink()
    {
        if ( !detectJavaApiLink )
        {
            return null;
        }

        final String pluginId = "org.apache.maven.plugins:maven-compiler-plugin";
        JavaVersion sourceVersion = javadocRuntimeVersion;
        String sourceConfigured = getPluginParameter( project, pluginId, "source" );
        if ( sourceConfigured != null )
        {
            try
            {
                sourceVersion = JavaVersion.parse( sourceConfigured );
            }
            catch ( NumberFormatException e )
            {
                getLog().debug(
                    "NumberFormatException for the source parameter in the maven-compiler-plugin. " + "Ignored it", e );
            }
        }
        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 );
        }

        String apiVersion;
        
        Matcher apiMatcher = Pattern.compile( "(1\\.\\d|\\d\\d*)" ).matcher( sourceVersion.toString() );
        if ( apiMatcher.find() )
        {
            apiVersion = apiMatcher.group( 1 );
        }
        else
        {
            apiVersion = null;
        }

        String javaApiLink = javaApiLinks.getProperty( "api_" + apiVersion, null );

        if ( getLog().isDebugEnabled() )
        {
            if ( StringUtils.isNotEmpty( javaApiLink ) )
            {
                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 ( JavaVersion.parse( apiVersion ).isAtLeast( "10" ) )
        {
            javaApiListFile = getJavadocOptionsFile().getParentFile().toPath().resolve( "element-list" );
            resourceName = "java-api-element-list-" + apiVersion;
        }
        else
        {
            javaApiListFile = getJavadocOptionsFile().getParentFile().toPath().resolve( "package-list" );
            resourceName = "java-api-package-list-" + apiVersion;
        }

        OfflineLink link = new OfflineLink();
        link.setLocation( javaApiListFile.getParent().toAbsolutePath().toString() );
        link.setUrl( javaApiLink );

        try ( InputStream in = this.getClass().getResourceAsStream( resourceName ) )
        {
            // TODO only copy when changed
            Files.copy( in, javaApiListFile, StandardCopyOption.REPLACE_EXISTING );
        }
        catch ( IOException ioe )
        {
            logError( "Can't get java-api-package-list-" + apiVersion + ": " + 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() );
            }
        }
        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="http://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();
            }

            
            IOException elementListIOException = null;
            try 
            {
                if ( JavadocUtil.isValidElementList( elementListUri.toURL(), settings, validateLinks ) )
                {
                    return true;
                }
            }
            catch ( IOException e ) 
            {
                elementListIOException = 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}
     */
    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 );
    }
}
