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.JavaModuleDescriptor;
import org.codehaus.plexus.languages.java.jpms.LocationManager;
import org.codehaus.plexus.languages.java.jpms.ResolvePathRequest;
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.Map.Entry;
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>
 * @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. All input will be passed as-is to the
     * {@code @options} file. You must take care of quoting and escaping. Useful for a custom doclet.
     *
     * @since 3.0.0
     */
    @Parameter
    private String[] additionalOptions;

    /**
     * Set an additional Javadoc option(s) (i.e. JVM options) on the command line.
     * Example:
     * <pre>
     * &lt;additionalJOption&gt;-J-Xss128m&lt;/additionalJOption&gt;
     * </pre>
     * See <a href="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;
    
    /**
     * Provide source compatibility with specified release
     * 
     * @since JDK 9
     * @since 3.1.0
     */
    @Parameter( defaultValue = "${maven.compiler.release}" )
    private String release;

    /**
     * Specifies the source paths where the subpackages are located. The <code>sourcepath</code> can contain
     * multiple paths by separating them with a colon (<code>:</code>) or a semi-colon (<code>;</code>).
     * <br/>
     * See
     * <a href="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
     * @deprecated if these sources depend on transitive dependencies, those dependencies should be added to the pom as
     *             direct dependencies
     */
    @Parameter( defaultValue = "false" )
    @Deprecated
    private boolean includeTransitiveDependencySources;

    /**
     * List of included dependency-source patterns. Example: <code>org.apache.maven:*</code>
     *
     * @see #includeDependencySources
     * @since 2.7
     */
    @Parameter
    private List<String> dependencySourceIncludes;

    /**
     * List of excluded dependency-source patterns. Example: <code>org.apache.maven.shared:*</code>
     *
     * @see #includeDependencySources
     * @since 2.7
     */
    @Parameter
    private List<String> dependencySourceExcludes;

    /**
     * Directory into which assembled {@link JavadocOptions} instances will be written before they
     * are added to javadoc resources bundles.
     *
     * @since 2.7
     */
    @Parameter( defaultValue = "${project.build.directory}/javadoc-bundle-options", readonly = true )
    private File javadocOptionsDir;

    /**
     * Transient variable to allow lazy-resolution of javadoc bundles from dependencies, so they can
     * be used at various points in the javadoc generation process.
     *
     * @since 2.7
     */
    private transient List<JavadocBundle> dependencyJavadocBundles;

    /**
     * Capability to add additional dependencies to the javadoc classpath.
     * Example:
     * <pre>
     * &lt;additionalDependencies&gt;
     *   &lt;additionalDependency&gt;
     *     &lt;groupId&gt;geronimo-spec&lt;/groupId&gt;
     *     &lt;artifactId&gt;geronimo-spec-jta&lt;/artifactId&gt;
     *     &lt;version&gt;1.0.1B-rc4:&lt;/version&gt;
     *   &lt;/additionalDependency&gt;
     * &lt;/additionalDependencies&gt;
     * </pre>
     *
     * @since 2.8.1
     */
    @Parameter
    private List<AdditionalDependency> additionalDependencies;

    /**
     * Include filters on the source files. Default is **\/\*.java.
     * These are ignored if you specify subpackages or subpackage excludes.
     */
    @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() ) );
    }
    
    protected File getArtifactFile( MavenProject project )
    {
        if ( project.getArtifact() != null )
        {
            return project.getArtifact().getFile();
        }
        return null;
    }

    /**
     * @param p not null maven project
     * @return the list of source paths for the given project
     */
    protected List<String> getProjectSourceRoots( MavenProject p )
    {
        if ( "pom".equals( p.getPackaging().toLowerCase() ) )
        {
            return Collections.emptyList();
        }

        return ( p.getCompileSourceRoots() == null
            ? Collections.<String>emptyList()
            : new LinkedList<>( p.getCompileSourceRoots() ) );
    }

    /**
     * @param p not null maven project
     * @return the list of source paths for the execution project of the given project
     */
    protected List<String> getExecutionProjectSourceRoots( MavenProject p )
    {
        if ( "pom".equals( p.getExecutionProject().getPackaging().toLowerCase() ) )
        {
            return Collections.emptyList();
        }

        return ( p.getExecutionProject().getCompileSourceRoots() == null
            ? Collections.<String>emptyList()
            : new LinkedList<>( p.getExecutionProject().getCompileSourceRoots() ) );
    }

    /**
     * @return the current javadoc directory
     */
    protected File getJavadocDirectory()
    {
        return javadocDirectory;
    }

    /**
     * @return the doclint specific checks configuration
     */
    protected String getDoclint()
    {
        return doclint;
    }

    /**
     * @return the title to be placed near the top of the overview summary file
     */
    protected String getDoctitle()
    {
        return doctitle;
    }

    /**
     * @return the overview documentation file from the user parameter or from the <code>javadocdirectory</code>
     */
    protected File getOverview()
    {
        return overview;
    }

    /**
     * @return the title to be placed in the HTML title tag
     */
    protected String getWindowtitle()
    {
        return windowtitle;
    }

    /**
     * @return the charset attribute or the value of {@link #getDocencoding()} if <code>null</code>.
     */
    private String getCharset()
    {
        return ( StringUtils.isEmpty( charset ) ) ? getDocencoding() : charset;
    }

    /**
     * @return the docencoding attribute or <code>UTF-8</code> if <code>null</code>.
     */
    private String getDocencoding()
    {
        return ( StringUtils.isEmpty( docencoding ) ) ? ReaderFactory.UTF_8 : docencoding;
    }

    /**
     * @return the encoding attribute or the value of <code>file.encoding</code> system property if <code>null</code>.
     */
    private String getEncoding()
    {
        return ( StringUtils.isEmpty( encoding ) ) ? ReaderFactory.FILE_ENCODING : encoding;
    }

    @Override
    public void execute()
        throws MojoExecutionException, 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<Path>> sourcePaths = getSourcePaths();
        
        Collection<Path> collectedSourcePaths = collect( sourcePaths.values() );
        
        Map<Path, Collection<String>> files = getFiles( collectedSourcePaths );
        if ( !canGenerateReport( files ) )
        {
            return;
        }

        // ----------------------------------------------------------------------
        // Find the javadoc executable and version
        // ----------------------------------------------------------------------

        String jExecutable;
        try
        {
            jExecutable = getJavadocExecutable();
        }
        catch ( IOException e )
        {
            throw new MavenReportException( "Unable to find javadoc command: " + e.getMessage(), e );
        }
        setFJavadocVersion( new File( jExecutable ) );

        List<String> packageNames;
        if ( javadocRuntimeVersion.isAtLeast( "9" ) )
        {
            packageNames = getPackageNamesRespectingJavaModules( sourcePaths );
        }
        else
        {
            packageNames = getPackageNames( files );
        }

        // ----------------------------------------------------------------------
        // Javadoc output directory as File
        // ----------------------------------------------------------------------

        File javadocOutputDirectory = new File( getOutputDirectory() );
        if ( javadocOutputDirectory.exists() && !javadocOutputDirectory.isDirectory() )
        {
            throw new MavenReportException( "IOException: " + getOutputDirectory() + " is not a directory." );
        }
        if ( javadocOutputDirectory.exists() && !javadocOutputDirectory.canWrite() )
        {
            throw new MavenReportException( "IOException: " + getOutputDirectory() + " is not writable." );
        }
        javadocOutputDirectory.mkdirs();

        // ----------------------------------------------------------------------
        // Copy all resources
        // ----------------------------------------------------------------------

        copyAllResources( javadocOutputDirectory );

        // ----------------------------------------------------------------------
        // Create command line for Javadoc
        // ----------------------------------------------------------------------

        Commandline cmd = new Commandline();
        cmd.getShell().setQuotedArgumentsEnabled( false ); // for Javadoc JVM args
        cmd.setWorkingDirectory( javadocOutputDirectory.getAbsolutePath() );
        cmd.setExecutable( jExecutable );

        // ----------------------------------------------------------------------
        // Wrap Javadoc JVM args
        // ----------------------------------------------------------------------

        addMemoryArg( cmd, "-Xmx", this.maxmemory );
        addMemoryArg( cmd, "-Xms", this.minmemory );
        addProxyArg( cmd );

        if ( StringUtils.isNotEmpty( additionalJOption ) )
        {
            cmd.createArg().setValue( additionalJOption );
        }

        if ( additionalJOptions != null && additionalJOptions.length != 0 )
        {
            for ( String jo : additionalJOptions )
            {
                cmd.createArg().setValue( jo );
            }
        }

        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
            // ----------------------------------------------------------------------

            List<String> specialFiles = getSpecialFiles( files );

            if ( !specialFiles.isEmpty() )
            {
                addCommandLineArgFile( cmd, javadocOutputDirectory, specialFiles );
            }
        }
        else
        {
            // ----------------------------------------------------------------------
            // Write argfile file and include it in the command line
            // ----------------------------------------------------------------------
            
            List<String> allFiles = new ArrayList<>();
            for ( Map.Entry<Path, Collection<String>> filesEntry : files.entrySet() )
            {
                for ( String file : filesEntry.getValue() )
                {
                    allFiles.add( filesEntry.getKey().resolve( file ).toString() );
                }
            }

            if ( !files.isEmpty() )
            {
                addCommandLineArgFile( cmd, javadocOutputDirectory, allFiles );
            }
        }

        // ----------------------------------------------------------------------
        // Execute command line
        // ----------------------------------------------------------------------

        executeJavadocCommandLine( cmd, javadocOutputDirectory );

        // delete generated javadoc files only if no error and no debug mode
        // [MJAVADOC-336] Use File.delete() instead of File.deleteOnExit() to
        // prevent these files from making their way into archives.
        if ( !debug )
        {
            for ( int i = 0; i < cmd.getArguments().length; i++ )
            {
                String arg = cmd.getArguments()[i].trim();

                if ( !arg.startsWith( "@" ) )
                {
                    continue;
                }

                File argFile = new File( javadocOutputDirectory, arg.substring( 1 ) );
                if ( argFile.exists() )
                {
                    argFile.delete();
                }
            }

            File scriptFile = new File( javadocOutputDirectory, DEBUG_JAVADOC_SCRIPT_NAME );
            if ( scriptFile.exists() )
            {
                scriptFile.delete();
            }
        }
        if ( applyJavadocSecurityFix )
        {
            // finally, patch the Javadoc vulnerability in older Javadoc tools (CVE-2013-1571):
            try
            {
                final int patched = fixFrameInjectionBug( javadocOutputDirectory, getDocencoding() );
                if ( patched > 0 )
                {
                    getLog().info(
                        String.format( "Fixed Javadoc frame injection vulnerability (CVE-2013-1571) in %d files.",
                                       patched ) );
                }
            }
            catch ( IOException e )
            {
                throw new MavenReportException( "Failed to patch javadocs vulnerability: " + e.getMessage(), e );
            }
        }
        else
        {
          getLog().info( "applying javadoc security fix has been disabled" );
        }
    }

    protected final <T> Collection<T> collect( Collection<Collection<T>> sourcePaths )
    {
        Collection<T> collectedSourcePaths = new LinkedHashSet<>();
        for ( Collection<T> 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 Map<Path, Collection<String>> getFiles( Collection<Path> sourcePaths )
        throws MavenReportException
    {
        Map<Path, Collection<String>> mappedFiles = new LinkedHashMap<>( sourcePaths.size() );
        if ( StringUtils.isEmpty( subpackages ) )
        {
            Collection<String> excludedPackages = getExcludedPackages();
            
            for ( Path sourcePath : sourcePaths )
            {
                List<String> files = new ArrayList<>();
                File sourceDirectory = sourcePath.toFile();
                files.addAll( JavadocUtil.getFilesFromSource( sourceDirectory, sourceFileIncludes, sourceFileExcludes,
                                                              excludedPackages ) );
                mappedFiles.put( sourcePath, files );
            }
        }

        return mappedFiles;
    }

    /**
     * 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<Path>> getSourcePaths()
        throws MavenReportException
    {
        Map<String, Collection<Path>> mappedSourcePaths = new LinkedHashMap<>();

        if ( StringUtils.isEmpty( sourcepath ) )
        {
            
            Set<Path> sourcePaths =
                new LinkedHashSet<>( JavadocUtil.pruneDirs( project, getProjectSourceRoots( project ) ) );

            if ( project.getExecutionProject() != null )
            {
                sourcePaths.addAll( JavadocUtil.pruneDirs( project, getExecutionProjectSourceRoots( project ) ) );
            }

            /*
             * Should be after the source path (i.e. -sourcepath '.../src/main/java;.../src/main/javadoc') and
             * *not* the opposite. If not, the javadoc tool always copies doc files, even if -docfilessubdirs is
             * not setted.
             */
            if ( getJavadocDirectory() != null )
            {
                File javadocDir = getJavadocDirectory();
                if ( javadocDir.exists() && javadocDir.isDirectory() )
                {
                    Collection<Path> l = JavadocUtil.pruneDirs( project, Collections.singletonList(
                        getJavadocDirectory().getAbsolutePath() ) );
                    sourcePaths.addAll( l );
                }
            }
            mappedSourcePaths.put( ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ),
                                   sourcePaths );
            
            if ( includeDependencySources )
            {
                mappedSourcePaths.putAll( getDependencySourcePaths() );
            }

            if ( isAggregator() )
            {
                for ( MavenProject subProject : getAggregatedProjects() )
                {
                    if ( subProject != project )
                    {
                        Collection<Path> additionalSourcePaths = new ArrayList<>();

                        List<String> sourceRoots = getProjectSourceRoots( subProject );

                        if ( subProject.getExecutionProject() != null )
                        {
                            sourceRoots.addAll( getExecutionProjectSourceRoots( subProject ) );
                        }

                        ArtifactHandler artifactHandler = subProject.getArtifact().getArtifactHandler();
                        if ( "java".equals( artifactHandler.getLanguage() ) )
                        {
                            additionalSourcePaths.addAll( JavadocUtil.pruneDirs( subProject, sourceRoots ) );
                        }

                        if ( getJavadocDirectory() != null )
                        {
                            String javadocDirRelative =
                                PathUtils.toRelative( project.getBasedir(),
                                                      getJavadocDirectory().getAbsolutePath() );
                            File javadocDir = new File( subProject.getBasedir(), javadocDirRelative );
                            if ( javadocDir.exists() && javadocDir.isDirectory() )
                            {
                                Collection<Path> l = JavadocUtil.pruneDirs( subProject, Collections.singletonList(
                                        javadocDir.getAbsolutePath() ) );
                                additionalSourcePaths.addAll( l );
                            }
                        }
                        mappedSourcePaths.put( ArtifactUtils.versionlessKey( subProject.getGroupId(),
                                                                             subProject.getArtifactId() ),
                                               additionalSourcePaths );
                    }
                }
            }
        }
        else
        {
            Collection<Path> sourcePaths =
                JavadocUtil.pruneDirs( project,
                                       new ArrayList<>( Arrays.asList( JavadocUtil.splitPath( sourcepath ) ) ) );
            if ( getJavadocDirectory() != null )
            {
                Collection<Path> l = JavadocUtil.pruneDirs( project, Collections.singletonList(
                    getJavadocDirectory().getAbsolutePath() ) );
                sourcePaths.addAll( l );
            }
            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<Path>> 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( Map<Path, Collection<String>> files )
    {
        for ( Collection<String> filesValues : files.values() )
        {
            if ( !filesValues.isEmpty() )
            {
                return true;
            }
        }

        return !StringUtils.isEmpty( subpackages );
    }

    // ----------------------------------------------------------------------
    // private methods
    // ----------------------------------------------------------------------

    /**
     * Method to get the excluded source files from the javadoc and create the argument string
     * that will be included in the javadoc commandline execution.
     *
     * @param sourceFolders the collection of paths to the source files
     * @return a String that contains the exclude argument that will be used by javadoc
     * @throws MavenReportException
     */
    private String getExcludedPackages( Collection<Path> sourcePaths )
        throws MavenReportException
    {
        List<String> excludedNames = null;
        
        if ( StringUtils.isNotEmpty( sourcepath ) && StringUtils.isNotEmpty( subpackages ) )
        {
            Collection<String> excludedPackages = getExcludedPackages();
            
            excludedNames = JavadocUtil.getExcludedPackages( sourcePaths, excludedPackages );
        }

        String excludeArg = "";
        if ( StringUtils.isNotEmpty( subpackages ) && excludedNames != null )
        {
            // add the excludedpackage names
            excludeArg = StringUtils.join( excludedNames.iterator(), ":" );
        }

        return excludeArg;
    }

    /**
     * Method to format the specified source paths that will be accepted by the javadoc tool.
     *
     * @param sourcePaths the list of paths to the source files that will be included in the javadoc.
     * @return a String that contains the formatted source path argument, separated by the System pathSeparator
     *         string (colon (<code>:</code>) on Solaris or semi-colon (<code>;</code>) on Windows).
     * @see File#pathSeparator
     */
    private String getSourcePath( Collection<Path> sourcePaths )
    {
        String sourcePath = null;

        if ( StringUtils.isEmpty( subpackages ) || StringUtils.isNotEmpty( sourcepath ) )
        {
            sourcePath = StringUtils.join( sourcePaths.iterator(), File.pathSeparator );
        }

        return sourcePath;
    }

    /**
     * Method to get the packages specified in the <code>excludePackageNames</code> parameter. The packages are split
     * with ',', ':', or ';' and then formatted.
     *
     * @return an array of String objects that contain the package names
     * @throws MavenReportException
     */
    private Collection<String> getExcludedPackages()
        throws MavenReportException
    {
        Set<String> excluded = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getExcludePackageNames() ) )
                    {
                        excluded.addAll( options.getExcludePackageNames() );
                    }
                }
            }
        }

        // for the specified excludePackageNames
        if ( StringUtils.isNotEmpty( excludePackageNames ) )
        {
            List<String> packageNames = Arrays.asList( excludePackageNames.split( "[,:;]" ) );
            excluded.addAll( trimValues( packageNames ) );
        }

        return excluded;
    }

    private static List<String> trimValues( List<String> items )
    {
        List<String> result = new ArrayList<>( items.size() );
        for ( String item : items )
        {
            String trimmed = item.trim();
            if ( StringUtils.isEmpty( trimmed ) )
            {
                continue;
            }
            result.add( trimmed );
        }
        return result;
    }

    /**
     * Method that gets the classpath and modulepath elements that will be specified in the javadoc
     * <code>-classpath</code> and <code>--module-path</code> parameter. 
     * Since we have all the sources of the current reactor, it is sufficient to consider the
     * dependencies of the reactor modules, excluding the module artifacts which may not yet be available
     * when the reactor project is built for the first time.
     *
     * @return all classpath elements
     * @throws MavenReportException if any.
     */
    private 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 )
                {
                    File projectArtifactFile = getArtifactFile( subProject );
                    if ( projectArtifactFile != null )
                    {
                        classpathElements.add( projectArtifactFile );
                    }
                    else
                    {
                        classpathElements.addAll( getProjectBuildOutputDirs( subProject ) );
                    }

                    try
                    {
                        StringBuilder sb = new StringBuilder();

                        sb.append( "Compiled artifacts for " );
                        sb.append( subProject.getGroupId() ).append( ":" );
                        sb.append( subProject.getArtifactId() ).append( ":" );
                        sb.append( subProject.getVersion() ).append( '\n' );

                        ProjectBuildingRequest buildingRequest = 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( JavadocUtil.pruneFiles( getArtifactsAbsolutePath( taglet.getTagletArtifact() ) ) );
            }
            else if ( StringUtils.isNotEmpty( taglet.getTagletpath() ) )
            {
                for ( Path dir : JavadocUtil.pruneDirs( project, Collections.singletonList( taglet.getTagletpath() ) ) )
                {
                    pathParts.add( dir.toString()  );
                }
            }
        }

        StringBuilder path = new StringBuilder();
        path.append( StringUtils.join( pathParts.iterator(), File.pathSeparator ) );

        if ( StringUtils.isNotEmpty( tagletpath ) )
        {
            path.append( JavadocUtil.unifyPathSeparator( tagletpath ) );
        }

        return path.toString();
    }

    private Set<String> collectLinks()
        throws MavenReportException
    {
        Set<String> links = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getLinks() ) )
                    {
                        links.addAll( options.getLinks() );
                    }
                }
            }
        }

        if ( isNotEmpty( this.links ) )
        {
            links.addAll( this.links );
        }

        links.addAll( getDependenciesLinks() );

        return followLinks( links );
    }

    private Set<Group> collectGroups()
        throws MavenReportException
    {
        Set<Group> groups = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getGroups() ) )
                    {
                        groups.addAll( options.getGroups() );
                    }
                }
            }
        }

        if ( this.groups != null && this.groups.length > 0 )
        {
            groups.addAll( Arrays.asList( this.groups ) );
        }

        return groups;
    }

    private Set<ResourcesArtifact> collectResourcesArtifacts()
        throws MavenReportException
    {
        Set<ResourcesArtifact> result = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getResourcesArtifacts() ) )
                    {
                        result.addAll( options.getResourcesArtifacts() );
                    }
                }
            }
        }

        if ( this.resourcesArtifacts != null && this.resourcesArtifacts.length > 0 )
        {
            result.addAll( Arrays.asList( this.resourcesArtifacts ) );
        }

        return result;
    }

    private Set<BootclasspathArtifact> collectBootClasspathArtifacts()
        throws MavenReportException
    {
        Set<BootclasspathArtifact> result = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getBootclasspathArtifacts() ) )
                    {
                        result.addAll( options.getBootclasspathArtifacts() );
                    }
                }
            }
        }

        if ( this.bootclasspathArtifacts != null && this.bootclasspathArtifacts.length > 0 )
        {
            result.addAll( Arrays.asList( this.bootclasspathArtifacts ) );
        }

        return result;
    }

    private Set<OfflineLink> collectOfflineLinks()
        throws MavenReportException
    {
        Set<OfflineLink> result = new LinkedHashSet<>();

        OfflineLink javaApiLink = getDefaultJavadocApiLink();
        if ( javaApiLink != null )
        {
            result.add( javaApiLink );
        }

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getOfflineLinks() ) )
                    {
                        result.addAll( options.getOfflineLinks() );
                    }
                }
            }
        }

        if ( this.offlineLinks != null && this.offlineLinks.length > 0 )
        {
            result.addAll( Arrays.asList( this.offlineLinks ) );
        }

        return result;
    }

    private Set<Tag> collectTags()
        throws MavenReportException
    {
        Set<Tag> tags = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getTags() ) )
                    {
                        tags.addAll( options.getTags() );
                    }
                }
            }
        }

        if ( this.tags != null && this.tags.length > 0 )
        {
            tags.addAll( Arrays.asList( this.tags ) );
        }

        return tags;
    }

    private Set<TagletArtifact> collectTagletArtifacts()
        throws MavenReportException
    {
        Set<TagletArtifact> tArtifacts = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getTagletArtifacts() ) )
                    {
                        tArtifacts.addAll( options.getTagletArtifacts() );
                    }
                }
            }
        }

        if ( tagletArtifact != null )
        {
            tArtifacts.add( tagletArtifact );
        }

        if ( tagletArtifacts != null && tagletArtifacts.length > 0 )
        {
            tArtifacts.addAll( Arrays.asList( tagletArtifacts ) );
        }

        return tArtifacts;
    }

    private Set<DocletArtifact> collectDocletArtifacts()
        throws MavenReportException
    {
        Set<DocletArtifact> dArtifacts = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getDocletArtifacts() ) )
                    {
                        dArtifacts.addAll( options.getDocletArtifacts() );
                    }
                }
            }
        }

        if ( docletArtifact != null )
        {
            dArtifacts.add( docletArtifact );
        }

        if ( docletArtifacts != null && docletArtifacts.length > 0 )
        {
            dArtifacts.addAll( Arrays.asList( docletArtifacts ) );
        }

        return dArtifacts;
    }

    private Set<Taglet> collectTaglets()
        throws MavenReportException
    {
        Set<Taglet> result = new LinkedHashSet<>();

        if ( includeDependencySources )
        {
            try
            {
                resolveDependencyBundles();
            }
            catch ( IOException e )
            {
                throw new MavenReportException(
                    "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
            }

            if ( isNotEmpty( dependencyJavadocBundles ) )
            {
                for ( JavadocBundle bundle : dependencyJavadocBundles )
                {
                    JavadocOptions options = bundle.getOptions();
                    if ( options != null && isNotEmpty( options.getTaglets() ) )
                    {
                        result.addAll( options.getTaglets() );
                    }
                }
            }
        }

        if ( taglets != null && taglets.length > 0 )
        {
            result.addAll( Arrays.asList( taglets ) );
        }

        return result;
    }

    /**
     * Return the Javadoc artifact path and its transitive dependencies path from the local repository
     *
     * @param javadocArtifact not null
     * @return a list of locale artifacts absolute path
     * @throws MavenReportException if any
     */
    private List<String> getArtifactsAbsolutePath( JavadocPathArtifact javadocArtifact )
        throws MavenReportException
    {
        if ( ( StringUtils.isEmpty( javadocArtifact.getGroupId() ) ) && ( StringUtils.isEmpty(
            javadocArtifact.getArtifactId() ) ) && ( StringUtils.isEmpty( javadocArtifact.getVersion() ) ) )
        {
            return Collections.emptyList();
        }

        List<String> path = new ArrayList<>();

        try
        {
            Artifact artifact = createAndResolveArtifact( javadocArtifact );
            path.add( artifact.getFile().getAbsolutePath() );

            DefaultDependableCoordinate coordinate = new DefaultDependableCoordinate();
            coordinate.setGroupId( javadocArtifact.getGroupId() );
            coordinate.setArtifactId( javadocArtifact.getArtifactId() );
            coordinate.setVersion( javadocArtifact.getVersion() );
            
            Iterable<ArtifactResult> deps =
                dependencyResolver.resolveDependencies( 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( Map<Path, Collection<String>> sourcePaths )
    {
        List<String> returnList = new ArrayList<>();
        
        if ( !StringUtils.isEmpty( sourcepath ) )
        {
            return returnList;
        }
        
        for ( Entry<Path, Collection<String>> currentPathEntry : sourcePaths.entrySet() )
        {
            for ( String currentFile : currentPathEntry.getValue() )
            {
                /*
                 * Remove the miscellaneous files
                 * http://docs.oracle.com/javase/1.4.2/docs/tooldocs/solaris/javadoc.html#unprocessed
                 */
                if ( currentFile.contains( "doc-files" ) )
                {
                    continue;
                }
        
                int lastIndexOfSeparator = currentFile.lastIndexOf( "/" );
                if ( lastIndexOfSeparator != -1 )
                {
                    String packagename = currentFile.substring( 0, lastIndexOfSeparator ).replace( '/', '.' );
        
                    if ( !returnList.contains( packagename ) )
                    {
                        returnList.add( packagename );
                    }
                }
            }
        }
        
        return returnList;
    }

    /**
     * @param allSourcePaths     not null, containing absolute and relative paths
     * @return a list of exported package names for files in allSourcePaths
     * @throws MavenReportException if any
     * @see #getFiles
     * @see #getSourcePaths()
     */
    private List<String> getPackageNamesRespectingJavaModules( Map<String, Collection<Path>> allSourcePaths )
            throws MavenReportException
    {
        List<String> returnList = new ArrayList<>();

        if ( !StringUtils.isEmpty( sourcepath ) )
        {
            return returnList;
        }
        LocationManager locationManager = new LocationManager();

        for ( Collection<Path> artifactSourcePaths: allSourcePaths.values() )
        {
            Set<String> exportedPackages = new HashSet<>();
            boolean exportAllPackages;
            File mainDescriptor = findMainDescriptor( artifactSourcePaths );
            if ( mainDescriptor != null && !isTest() )
            {
                ResolvePathsRequest<File> request =
                        ResolvePathsRequest.withFiles( Collections.<File>emptyList() ).
                                setMainModuleDescriptor( mainDescriptor );
    
                try
                {
                    Set<JavaModuleDescriptor.JavaExports> exports = locationManager.resolvePaths( request ).
                            getMainModuleDescriptor().exports();
                    if ( exports.isEmpty() )
                    {
                        continue;
                    }
                    for ( JavaModuleDescriptor.JavaExports export : exports )
                    {
                        exportedPackages.add( export.source() );
                    }
                }
                catch ( IOException e )
                {
                    throw new MavenReportException( e.getMessage(), e );
                }
                exportAllPackages = false;
            }
            else
            {
                exportAllPackages = true;
            }
            
            for ( Map.Entry<Path, Collection<String>> currentPathEntry : getFiles( artifactSourcePaths ).entrySet() )
            {
                for ( String currentFile : currentPathEntry.getValue() )
                {
                    /*
                     * Remove the miscellaneous files
                     * http://docs.oracle.com/javase/1.4.2/docs/tooldocs/solaris/javadoc.html#unprocessed
                     */
                    if ( currentFile.contains( "doc-files" ) )
                    {
                        continue;
                    }

                    int lastIndexOfSeparator = currentFile.lastIndexOf( File.separatorChar );
                    if ( lastIndexOfSeparator != -1 )
                    {
                        String packagename =
                            currentFile.substring( 0, lastIndexOfSeparator ).replace( File.separatorChar, '.' );

                        if ( exportAllPackages || exportedPackages.contains( packagename ) )
                        {
                            returnList.add( packagename );
                        }
                    }
                }
            }
        }

        return returnList;
    }

    /**
     * @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( Map<Path, Collection<String>> sourcePaths )
    {
        List<String> returnList = new ArrayList<>();
        
        if ( !StringUtils.isEmpty( sourcepath ) )
        {
            return returnList;
        }
        
        for ( Entry<Path, Collection<String>> currentPathEntry : sourcePaths.entrySet() )
        {
            Path currentSourcePath = currentPathEntry.getKey();
        
            for ( String currentFile : currentPathEntry.getValue() )
            {
                /*
                 * Remove the miscellaneous files
                 * http://docs.oracle.com/javase/1.4.2/docs/tooldocs/solaris/javadoc.html#unprocessed
                 */
                if ( currentFile.contains( "doc-files" ) )
                {
                    continue;
                }
        
                if ( currentFile.indexOf( File.separatorChar ) == -1 )
                {
                    returnList.add( currentSourcePath.resolve( currentFile ).toAbsolutePath().toString() );
                }
            }
        }
        
        return returnList;
    }
    
    /**
     * Either return only the module descriptor or all sourcefiles per sourcepath
     * @param sourcePaths could be null
     * @param files       not null
     * @return a list of files
     */
    private List<String> getSpecialFiles( Map<Path, Collection<String>> sourcePaths )
    {
        if ( !StringUtils.isEmpty( sourcepath ) )
        {
            return new ArrayList<>();
        }
        
        boolean containsModuleDescriptor = false;
        for ( Collection<String> sourcepathFiles : sourcePaths.values() )
        {
            containsModuleDescriptor = sourcepathFiles.contains( "module-info.java" );
            if ( containsModuleDescriptor )
            {
                break;
            }
        }
        
        if ( containsModuleDescriptor )
        {
            return getModuleSourcePathFiles( sourcePaths );
        }
        else
        {
            return getFilesWithUnnamedPackages( sourcePaths );
        }
    }

    private List<String> getModuleSourcePathFiles( Map<Path, Collection<String>> sourcePaths )
    {
        List<String> returnList = new ArrayList<>();
        
        for ( Entry<Path, Collection<String>> currentPathEntry : sourcePaths.entrySet() )
        {
            Path currentSourcePath = currentPathEntry.getKey();
            if ( currentPathEntry.getValue().contains( "module-info.java" ) )
            {
                returnList.add( currentSourcePath.resolve( "module-info.java" ).toAbsolutePath().toString() );
            }
            else
            {
                for ( String currentFile : currentPathEntry.getValue() )
                {
                    /*
                     * Remove the miscellaneous files
                     * http://docs.oracle.com/javase/1.4.2/docs/tooldocs/solaris/javadoc.html#unprocessed
                     */
                    if ( currentFile.contains( "doc-files" ) )
                    {
                        continue;
                    }
            
                    returnList.add( currentSourcePath.resolve( currentFile ).toAbsolutePath().toString() );
                }
            }
        }
        return returnList;
    }

    /**
     * Generate an <code>options</code> file for all options and arguments and add the <code>@options</code> in the
     * command line.
     *
     * @param cmd                    not null
     * @param arguments              not null
     * @param javadocOutputDirectory not null
     * @throws MavenReportException if any
     * @see <a href="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 );
        }

        List<String> quotedFiles = new ArrayList<>( files.size() );
        for ( String file : files )
        {
            quotedFiles.add( JavadocUtil.quotedPathArgument( file ) );
        }
        
        try
        {
            FileUtils.fileWrite( argfileFile.getAbsolutePath(), null /* platform encoding */,
                                 StringUtils.join( quotedFiles.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<Path>> allSourcePaths )
        throws MavenReportException
    {
        Collection<Path> 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 );
        }
        
        Map<String, MavenProject> reactorKeys = new HashMap<>( session.getProjects().size() );
        for ( MavenProject reactorProject : session.getProjects() )
        {
            reactorKeys.put( ArtifactUtils.versionlessKey( reactorProject.getGroupId(),
                                                           reactorProject.getArtifactId() ), reactorProject );
        }
        
        final LocationManager locationManager = new LocationManager();
        
        Collection<String> additionalModules = new ArrayList<>();
        
        boolean containsModuleDescriptor = false;
        for ( Collection<Path> sourcepaths : allSourcePaths.values() )
        {
            if ( findMainDescriptor( sourcepaths ) != null )
            {
                containsModuleDescriptor = true;
            }
        }
        
        
        Path moduleSourceDir = null;
        if ( containsModuleDescriptor && allSourcePaths.size() > 1 )
        {
            for ( Map.Entry<String, Collection<Path>> projectSourcepaths : allSourcePaths.entrySet() )
            {
                MavenProject aggregatorProject = reactorKeys.get( projectSourcepaths.getKey() );
                if ( aggregatorProject != null )
                {
                    String moduleName = null;
                    
                    // Prefer jar over outputDirectory, since it may may contain an automatic module name
                    File artifactFile = getArtifactFile( aggregatorProject );
                    if ( artifactFile != null ) 
                    {
                        ResolvePathRequest<File> request = ResolvePathRequest.ofFile( artifactFile );
                        try
                        {
                            moduleName = locationManager.resolvePath( request ).getModuleDescriptor().name();
                        }
                        catch ( RuntimeException e )
                        {
                            // most likely an invalid module name based on filename
                            if ( !"java.lang.module.FindException".equals( e.getClass().getName() ) )
                            {
                                throw e;
                            }
                        }
                        catch ( IOException e )
                        {
                            throw new MavenReportException( e.getMessage(), e );
                        }
                    }
                    else
                    {
                        File moduleDescriptor = findMainDescriptor( projectSourcepaths.getValue() );
                        
                        if ( moduleDescriptor != null )
                        {
                            ResolvePathsRequest<File> request =
                                            ResolvePathsRequest.ofFiles( Collections.<File>emptyList() )
                                                               .setMainModuleDescriptor( moduleDescriptor );

                            try
                            {
                                moduleName =
                                    locationManager.resolvePaths( request ).getMainModuleDescriptor().name();
                            }
                            catch ( IOException e )
                            {
                                throw new MavenReportException( e.getMessage(), e );
                            }
                        }
                    }
                    if ( moduleName != null )
                    {
                        moduleSourceDir = javadocOutputDirectory.toPath().resolve( "src" );
                        try
                        {
                            moduleSourceDir = Files.createDirectories( moduleSourceDir );
                            
                            additionalModules.add( moduleName );
                            
                            addArgIfNotEmpty( arguments, "--patch-module", moduleName + '='
                                + JavadocUtil.quotedPathArgument( getSourcePath( projectSourcepaths.getValue() ) ) );
                            
                            Path modulePath = moduleSourceDir.resolve( moduleName );
                            if ( !Files.isDirectory( modulePath ) )
                            {
                                Files.createDirectory( modulePath );
                            }
                        }
                        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() );

                }
            }
        }

        Collection<Path> roots = new ArrayList<>();
        for ( String path : getProjectSourceRoots( getProject() ) )
        {
            roots.add( Paths.get( path ) );
        }
        
        File mainDescriptor = findMainDescriptor( roots );

        if ( javadocRuntimeVersion.isAtLeast( "9" ) && ( isAggregator() || mainDescriptor != null ) && !isTest() )
        {
            ResolvePathsRequest<File> request =
                ResolvePathsRequest.ofFiles( 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 );
        }

        if ( release != null )
        {
            arguments.add( "--release" );
            arguments.add( release );
        }
        else
        {
            addArgIfNotEmpty( arguments, "-source", JavadocUtil.quotedArgument( source ), SINCE_JAVADOC_1_4 );
        }

        if ( ( StringUtils.isEmpty( sourcepath ) ) && ( StringUtils.isNotEmpty( subpackages ) ) )
        {
            sourcepath = StringUtils.join( sourcePaths.iterator(), File.pathSeparator );
        }
        
        if ( moduleSourceDir != null )
        {
            addArgIfNotEmpty( arguments, "--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<Path> roots )
    {
        for ( Path root : roots )
        {
            File descriptorFile = root.resolve( "module-info.java" ).toAbsolutePath().toFile();
            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 );
    }
}
