package org.apache.maven.plugin.compiler;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.RepositorySystem;
import org.apache.maven.shared.incremental.IncrementalBuildHelper;
import org.apache.maven.shared.incremental.IncrementalBuildHelperRequest;
import org.apache.maven.shared.utils.ReaderFactory;
import org.apache.maven.shared.utils.StringUtils;
import org.apache.maven.shared.utils.io.FileUtils;
import org.apache.maven.shared.utils.logging.MessageBuilder;
import org.apache.maven.shared.utils.logging.MessageUtils;
import org.apache.maven.toolchain.Toolchain;
import org.apache.maven.toolchain.ToolchainManager;
import org.codehaus.plexus.compiler.Compiler;
import org.codehaus.plexus.compiler.CompilerConfiguration;
import org.codehaus.plexus.compiler.CompilerError;
import org.codehaus.plexus.compiler.CompilerException;
import org.codehaus.plexus.compiler.CompilerMessage;
import org.codehaus.plexus.compiler.CompilerNotImplementedException;
import org.codehaus.plexus.compiler.CompilerOutputStyle;
import org.codehaus.plexus.compiler.CompilerResult;
import org.codehaus.plexus.compiler.manager.CompilerManager;
import org.codehaus.plexus.compiler.manager.NoSuchCompilerException;
import org.codehaus.plexus.compiler.util.scan.InclusionScanException;
import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner;
import org.codehaus.plexus.compiler.util.scan.mapping.SingleTargetSourceMapping;
import org.codehaus.plexus.compiler.util.scan.mapping.SourceMapping;
import org.codehaus.plexus.compiler.util.scan.mapping.SuffixMapping;
import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor;
import org.codehaus.plexus.languages.java.version.JavaVersion;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;

/**
 * TODO: At least one step could be optimized, currently the plugin will do two
 * scans of all the source code if the compiler has to have the entire set of
 * sources. This is currently the case for at least the C# compiler and most
 * likely all the other .NET compilers too.
 *
 * @author others
 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
 * @since 2.0
 */
public abstract class AbstractCompilerMojo
    extends AbstractMojo
{
    protected static final String PS = System.getProperty( "path.separator" );

    static final String DEFAULT_SOURCE = "1.7";
    
    static final String DEFAULT_TARGET = "1.7";
    
    // Used to compare with older targets
    static final String MODULE_INFO_TARGET = "1.9";
    
    // ----------------------------------------------------------------------
    // Configurables
    // ----------------------------------------------------------------------

    /**
     * Indicates whether the build will continue even if there are compilation errors.
     *
     * @since 2.0.2
     */
    @Parameter( property = "maven.compiler.failOnError", defaultValue = "true" )
    private boolean failOnError = true;
    
    /**
     * Indicates whether the build will continue even if there are compilation warnings.
     *
     * @since 3.6
     */
    @Parameter( property = "maven.compiler.failOnWarning", defaultValue = "false" )
    private boolean failOnWarning;  

    /**
     * Set to <code>true</code> to include debugging information in the compiled class files.
     */
    @Parameter( property = "maven.compiler.debug", defaultValue = "true" )
    private boolean debug = true;

    /**
     * Set to <code>true</code> to generate metadata for reflection on method parameters.
     * @since 3.6.2
     */
    @Parameter( property = "maven.compiler.parameters", defaultValue = "false" )
    private boolean parameters;

    /**
     * Set to <code>true</code> to show messages about what the compiler is doing.
     */
    @Parameter( property = "maven.compiler.verbose", defaultValue = "false" )
    private boolean verbose;

    /**
     * Sets whether to show source locations where deprecated APIs are used.
     */
    @Parameter( property = "maven.compiler.showDeprecation", defaultValue = "false" )
    private boolean showDeprecation;

    /**
     * Set to <code>true</code> to optimize the compiled code using the compiler's optimization methods.
     * @deprecated This property is a no-op in {@code javac}.
     */
    @Deprecated
    @Parameter( property = "maven.compiler.optimize", defaultValue = "false" )
    private boolean optimize;

    /**
     * Set to <code>true</code> to show compilation warnings.
     */
    @Parameter( property = "maven.compiler.showWarnings", defaultValue = "false" )
    private boolean showWarnings;

    /**
     * <p>The -source argument for the Java compiler.</p>
     * 
     * <b>NOTE: </b>Since 3.8.0 the default value has changed from 1.5 to 1.6.
     * Since 3.9.0 the default value has changed from 1.6 to 1.7
     */
    @Parameter( property = "maven.compiler.source", defaultValue = DEFAULT_SOURCE )
    protected String source;

    /**
     * <p>The -target argument for the Java compiler.</p>
     * 
     * <b>NOTE: </b>Since 3.8.0 the default value has changed from 1.5 to 1.6.
     * Since 3.9.0 the default value has changed from 1.6 to 1.7
     */
    @Parameter( property = "maven.compiler.target", defaultValue = DEFAULT_TARGET )
    protected String target;

    /**
     * The -release argument for the Java compiler, supported since Java9
     * 
     * @since 3.6
     */
    @Parameter( property = "maven.compiler.release" )
    protected String release;
    
    /**
     * The -encoding argument for the Java compiler.
     *
     * @since 2.1
     */
    @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
    private String encoding;

    /**
     * Sets the granularity in milliseconds of the last modification
     * date for testing whether a source needs recompilation.
     */
    @Parameter( property = "lastModGranularityMs", defaultValue = "0" )
    private int staleMillis;

    /**
     * The compiler id of the compiler to use. See this
     * <a href="non-javac-compilers.html">guide</a> for more information.
     */
    @Parameter( property = "maven.compiler.compilerId", defaultValue = "javac" )
    private String compilerId;

    /**
     * Version of the compiler to use, ex. "1.3", "1.5", if {@link #fork} is set to <code>true</code>.
     */
    @Parameter( property = "maven.compiler.compilerVersion" )
    private String compilerVersion;

    /**
     * Allows running the compiler in a separate process.
     * If <code>false</code> it uses the built in compiler, while if <code>true</code> it will use an executable.
     */
    @Parameter( property = "maven.compiler.fork", defaultValue = "false" )
    private boolean fork;

    /**
     * Initial size, in megabytes, of the memory allocation pool, ex. "64", "64m"
     * if {@link #fork} is set to <code>true</code>.
     *
     * @since 2.0.1
     */
    @Parameter( property = "maven.compiler.meminitial" )
    private String meminitial;

    /**
     * Sets the maximum size, in megabytes, of the memory allocation pool, ex. "128", "128m"
     * if {@link #fork} is set to <code>true</code>.
     *
     * @since 2.0.1
     */
    @Parameter( property = "maven.compiler.maxmem" )
    private String maxmem;

    /**
     * Sets the executable of the compiler to use when {@link #fork} is <code>true</code>.
     */
    @Parameter( property = "maven.compiler.executable" )
    private String executable;

    /**
     * <p>
     * Sets whether annotation processing is performed or not. Only applies to JDK 1.6+
     * If not set, both compilation and annotation processing are performed at the same time.
     * </p>
     * <p>Allowed values are:</p>
     * <ul>
     * <li><code>none</code> - no annotation processing is performed.</li>
     * <li><code>only</code> - only annotation processing is done, no compilation.</li>
     * </ul>
     *
     * @since 2.2
     */
    @Parameter
    private String proc;

    /**
     * <p>
     * Names of annotation processors to run. Only applies to JDK 1.6+
     * If not set, the default annotation processors discovery process applies.
     * </p>
     *
     * @since 2.2
     */
    @Parameter
    private String[] annotationProcessors;

    /**
     * <p>
     * Classpath elements to supply as annotation processor path. If specified, the compiler will detect annotation
     * processors only in those classpath elements. If omitted, the default classpath is used to detect annotation
     * processors. The detection itself depends on the configuration of {@code annotationProcessors}.
     * </p>
     * <p>
     * Each classpath element is specified using their Maven coordinates (groupId, artifactId, version, classifier,
     * type). Transitive dependencies are added automatically. Example:
     * </p>
     *
     * <pre>
     * &lt;configuration&gt;
     *   &lt;annotationProcessorPaths&gt;
     *     &lt;path&gt;
     *       &lt;groupId&gt;org.sample&lt;/groupId&gt;
     *       &lt;artifactId&gt;sample-annotation-processor&lt;/artifactId&gt;
     *       &lt;version&gt;1.2.3&lt;/version&gt;
     *     &lt;/path&gt;
     *     &lt;!-- ... more ... --&gt;
     *   &lt;/annotationProcessorPaths&gt;
     * &lt;/configuration&gt;
     * </pre>
     *
     * @since 3.5
     */
    @Parameter
    private List<DependencyCoordinate> annotationProcessorPaths;

    /**
     * <p>
     * Sets the arguments to be passed to the compiler (prepending a dash).
     * </p>
     * <p>
     * This is because the list of valid arguments passed to a Java compiler varies based on the compiler version.
     * </p>
     * <p>
     * Note that {@code -J} options are only passed through if {@link #fork} is set to {@code true}.
     * </p>
     * <p>
     * To pass <code>-Xmaxerrs 1000 -Xlint -Xlint:-path -Averbose=true</code> you should include the following:
     * </p>
     *
     * <pre>
     * &lt;compilerArguments&gt;
     *   &lt;Xmaxerrs&gt;1000&lt;/Xmaxerrs&gt;
     *   &lt;Xlint/&gt;
     *   &lt;Xlint:-path/&gt;
     *   &lt;Averbose&gt;true&lt;/Averbose&gt;
     * &lt;/compilerArguments&gt;
     * </pre>
     *
     * @since 2.0.1
     * @deprecated use {@link #compilerArgs} instead.
     */
    @Parameter
    @Deprecated
    protected Map<String, String> compilerArguments;

    /**
     * <p>
     * Sets the arguments to be passed to the compiler.
     * </p>
     * <p>
     * Note that {@code -J} options are only passed through if {@link #fork} is set to {@code true}.
     * </p>
     * Example:
     * <pre>
     * &lt;compilerArgs&gt;
     *   &lt;arg&gt;-Xmaxerrs&lt;/arg&gt;
     *   &lt;arg&gt;1000&lt;/arg&gt;
     *   &lt;arg&gt;-Xlint&lt;/arg&gt;
     *   &lt;arg&gt;-J-Duser.language=en_us&lt;/arg&gt;
     * &lt;/compilerArgs&gt;
     * </pre>
     *
     * @since 3.1
     */
    @Parameter
    protected List<String> compilerArgs;

    /**
     * <p>
     * Sets the unformatted single argument string to be passed to the compiler. To pass multiple arguments such as
     * <code>-Xmaxerrs 1000</code> (which are actually two arguments) you have to use {@link #compilerArguments}.
     * </p>
     * <p>
     * This is because the list of valid arguments passed to a Java compiler varies based on the compiler version.
     * </p>
     * <p>
     * Note that {@code -J} options are only passed through if {@link #fork} is set to {@code true}.
     * </p>
     */
    @Parameter
    protected String compilerArgument;

    /**
     * Sets the name of the output file when compiling a set of
     * sources to a single file.
     * <p/>
     * expression="${project.build.finalName}"
     */
    @Parameter
    private String outputFileName;

    /**
     * Keyword list to be appended to the <code>-g</code> command-line switch. Legal values are none or a
     * comma-separated list of the following keywords: <code>lines</code>, <code>vars</code>, and <code>source</code>.
     * If debug level is not specified, by default, nothing will be appended to <code>-g</code>.
     * If debug is not turned on, this attribute will be ignored.
     *
     * @since 2.1
     */
    @Parameter( property = "maven.compiler.debuglevel" )
    private String debuglevel;

    /**
     *
     */
    @Component
    private ToolchainManager toolchainManager;

    /**
     * <p>
     * Specify the requirements for this jdk toolchain for using a different {@code javac} than the one of the JRE used
     * by Maven. This overrules the toolchain selected by the
     * <a href="https://maven.apache.org/plugins/maven-toolchains-plugin/">maven-toolchain-plugin</a>.
     * </p>
     * (see <a href="https://maven.apache.org/guides/mini/guide-using-toolchains.html"> Guide to Toolchains</a> for more
     * info)
     * 
     * <pre>
     * &lt;configuration&gt;
     *   &lt;jdkToolchain&gt;
     *     &lt;version&gt;11&lt;/version&gt;
     *   &lt;/jdkToolchain&gt;
     *   ...
     * &lt;/configuration&gt;
     *
     * &lt;configuration&gt;
     *   &lt;jdkToolchain&gt;
     *     &lt;version&gt;1.8&lt;/version&gt;
     *     &lt;vendor&gt;zulu&lt;/vendor&gt;
     *   &lt;/jdkToolchain&gt;
     *   ...
     * &lt;/configuration&gt;
     * </pre>
     * <strong>note:</strong> requires at least Maven 3.3.1
     * 
     * @since 3.6
     */
    @Parameter
    private Map<String, String> jdkToolchain;

    // ----------------------------------------------------------------------
    // Read-only parameters
    // ----------------------------------------------------------------------

    /**
     * The directory to run the compiler from if fork is true.
     */
    @Parameter( defaultValue = "${basedir}", required = true, readonly = true )
    private File basedir;

    /**
     * The target directory of the compiler if fork is true.
     */
    @Parameter( defaultValue = "${project.build.directory}", required = true, readonly = true )
    private File buildDirectory;

    /**
     * Plexus compiler manager.
     */
    @Component
    private CompilerManager compilerManager;

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

    /**
     * The current project instance. This is used for propagating generated-sources paths as compile/testCompile source
     * roots.
     */
    @Parameter( defaultValue = "${project}", readonly = true, required = true )
    private MavenProject project;

    /**
     * Strategy to re use javacc class created:
     * <ul>
     * <li><code>reuseCreated</code> (default): will reuse already created but in case of multi-threaded builds, each
     * thread will have its own instance</li>
     * <li><code>reuseSame</code>: the same Javacc class will be used for each compilation even for multi-threaded build
     * </li>
     * <li><code>alwaysNew</code>: a new Javacc class will be created for each compilation</li>
     * </ul>
     * Note this parameter value depends on the os/jdk you are using, but the default value should work on most of env.
     *
     * @since 2.5
     */
    @Parameter( defaultValue = "${reuseCreated}", property = "maven.compiler.compilerReuseStrategy" )
    private String compilerReuseStrategy = "reuseCreated";

    /**
     * @since 2.5
     */
    @Parameter( defaultValue = "false", property = "maven.compiler.skipMultiThreadWarning" )
    private boolean skipMultiThreadWarning;

    /**
     * compiler can now use javax.tools if available in your current jdk, you can disable this feature
     * using -Dmaven.compiler.forceJavacCompilerUse=true or in the plugin configuration
     *
     * @since 3.0
     */
    @Parameter( defaultValue = "false", property = "maven.compiler.forceJavacCompilerUse" )
    private boolean forceJavacCompilerUse;

    /**
     * @since 3.0 needed for storing the status for the incremental build support.
     */
    @Parameter( defaultValue = "${mojoExecution}", readonly = true, required = true )
    private MojoExecution mojoExecution;

    /**
     * File extensions to check timestamp for incremental build.
     * Default contains only <code>class</code> and <code>jar</code>.
     *
     * @since 3.1
     */
    @Parameter
    private List<String> fileExtensions;

    /**
     * <p>to enable/disable incremental compilation feature.</p>
     * <p>This leads to two different modes depending on the underlying compiler. The default javac compiler does the
     * following:</p>
     * <ul>
     * <li>true <strong>(default)</strong> in this mode the compiler plugin determines whether any JAR files the
     * current module depends on have changed in the current build run; or any source file was added, removed or
     * changed since the last compilation. If this is the case, the compiler plugin recompiles all sources.</li>
     * <li>false <strong>(not recommended)</strong> this only compiles source files which are newer than their
     * corresponding class files, namely which have changed since the last compilation. This does not
     * recompile other classes which use the changed class, potentially leaving them with references to methods that no
     * longer exist, leading to errors at runtime.</li>
     * </ul>
     *
     * @since 3.1
     */
    @Parameter( defaultValue = "true", property = "maven.compiler.useIncrementalCompilation" )
    private boolean useIncrementalCompilation = true;

    /**
     * Package info source files that only contain javadoc and no annotation on the package
     * can lead to no class file being generated by the compiler.  This causes a file miss
     * on the next compilations and forces an unnecessary recompilation. The default value
     * of <code>true</code> causes an empty class file to be generated.  This behavior can
     * be changed by setting this parameter to <code>false</code>.
     *
     * @since 3.10
     */
    @Parameter( defaultValue = "true", property = "maven.compiler.createMissingPackageInfoClass" )
    private boolean createMissingPackageInfoClass = true;

    /**
     * Resolves the artifacts needed.
     */
    @Component
    private RepositorySystem repositorySystem;

    /**
     * Artifact handler manager.
     */
    @Component
    private ArtifactHandlerManager artifactHandlerManager;

    /**
     * Throws an exception on artifact resolution errors.
     */
    @Component
    private ResolutionErrorHandler resolutionErrorHandler;

    protected abstract SourceInclusionScanner getSourceInclusionScanner( int staleMillis );

    protected abstract SourceInclusionScanner getSourceInclusionScanner( String inputFileEnding );

    protected abstract List<String> getClasspathElements();

    protected abstract List<String> getModulepathElements();

    protected abstract Map<String, JavaModuleDescriptor> getPathElements();

    protected abstract List<String> getCompileSourceRoots();
    
    protected abstract void preparePaths( Set<File> sourceFiles );

    protected abstract File getOutputDirectory();

    protected abstract String getSource();

    protected abstract String getTarget();

    protected abstract String getRelease();

    protected abstract String getCompilerArgument();

    protected abstract Map<String, String> getCompilerArguments();

    protected abstract File getGeneratedSourcesDirectory();

    protected abstract String getDebugFileName();

    protected final MavenProject getProject()
    {
        return project;
    }

    private boolean targetOrReleaseSet;

    @Override
    public void execute()
        throws MojoExecutionException, CompilationFailureException
    {
        // ----------------------------------------------------------------------
        // Look up the compiler. This is done before other code than can
        // cause the mojo to return before the lookup is done possibly resulting
        // in misconfigured POMs still building.
        // ----------------------------------------------------------------------

        Compiler compiler;

        getLog().debug( "Using compiler '" + compilerId + "'." );

        try
        {
            compiler = compilerManager.getCompiler( compilerId );
        }
        catch ( NoSuchCompilerException e )
        {
            throw new MojoExecutionException( "No such compiler '" + e.getCompilerId() + "'." );
        }

        //-----------toolchains start here ----------------------------------
        //use the compilerId as identifier for toolchains as well.
        Toolchain tc = getToolchain();
        if ( tc != null )
        {
            getLog().info( "Toolchain in maven-compiler-plugin: " + tc );
            if ( executable != null )
            {
                getLog().warn( "Toolchains are ignored, 'executable' parameter is set to " + executable );
            }
            else
            {
                fork = true;
                //TODO somehow shaky dependency between compilerId and tool executable.
                executable = tc.findTool( compilerId );
            }
        }
        // ----------------------------------------------------------------------
        //
        // ----------------------------------------------------------------------

        List<String> compileSourceRoots = removeEmptyCompileSourceRoots( getCompileSourceRoots() );

        if ( compileSourceRoots.isEmpty() )
        {
            getLog().info( "No sources to compile" );

            return;
        }

        // Verify that target or release is set
        if ( !targetOrReleaseSet )
        {
            MessageBuilder mb = MessageUtils.buffer().a( "No explicit value set for target or release! " )
                            .a( "To ensure the same result even after upgrading this plugin, please add " ).newline()
                            .newline();

            writePlugin( mb );

            getLog().warn( mb.toString() );
        }

        // ----------------------------------------------------------------------
        // Create the compiler configuration
        // ----------------------------------------------------------------------

        CompilerConfiguration compilerConfiguration = new CompilerConfiguration();

        compilerConfiguration.setOutputLocation( getOutputDirectory().getAbsolutePath() );

        compilerConfiguration.setOptimize( optimize );

        compilerConfiguration.setDebug( debug );

        compilerConfiguration.setDebugFileName( getDebugFileName() );

        if ( debug && StringUtils.isNotEmpty( debuglevel ) )
        {
            String[] split = StringUtils.split( debuglevel, "," );
            for ( String aSplit : split )
            {
                if ( !( aSplit.equalsIgnoreCase( "none" ) || aSplit.equalsIgnoreCase( "lines" )
                    || aSplit.equalsIgnoreCase( "vars" ) || aSplit.equalsIgnoreCase( "source" ) ) )
                {
                    throw new IllegalArgumentException( "The specified debug level: '" + aSplit + "' is unsupported. "
                        + "Legal values are 'none', 'lines', 'vars', and 'source'." );
                }
            }
            compilerConfiguration.setDebugLevel( debuglevel );
        }

        compilerConfiguration.setParameters( parameters );

        compilerConfiguration.setVerbose( verbose );

        compilerConfiguration.setShowWarnings( showWarnings );

        compilerConfiguration.setFailOnWarning( failOnWarning );

        compilerConfiguration.setShowDeprecation( showDeprecation );

        compilerConfiguration.setSourceVersion( getSource() );

        compilerConfiguration.setTargetVersion( getTarget() );
        
        compilerConfiguration.setReleaseVersion( getRelease() );

        compilerConfiguration.setProc( proc );

        File generatedSourcesDirectory = getGeneratedSourcesDirectory();
        compilerConfiguration.setGeneratedSourcesDirectory( generatedSourcesDirectory != null
                        ? generatedSourcesDirectory.getAbsoluteFile() : null );

        if ( generatedSourcesDirectory != null )
        {
            if ( !generatedSourcesDirectory.exists() )
            {
                generatedSourcesDirectory.mkdirs();
            }

            String generatedSourcesPath = generatedSourcesDirectory.getAbsolutePath();

            compileSourceRoots.add( generatedSourcesPath );

            if ( isTestCompile() )
            {
                getLog().debug( "Adding " + generatedSourcesPath + " to test-compile source roots:\n  "
                                    + StringUtils.join( project.getTestCompileSourceRoots()
                                                               .iterator(), "\n  " ) );

                project.addTestCompileSourceRoot( generatedSourcesPath );

                getLog().debug( "New test-compile source roots:\n  "
                                    + StringUtils.join( project.getTestCompileSourceRoots()
                                                               .iterator(), "\n  " ) );
            }
            else
            {
                getLog().debug( "Adding " + generatedSourcesPath + " to compile source roots:\n  "
                                    + StringUtils.join( project.getCompileSourceRoots()
                                                               .iterator(), "\n  " ) );

                project.addCompileSourceRoot( generatedSourcesPath );

                getLog().debug( "New compile source roots:\n  " + StringUtils.join( project.getCompileSourceRoots()
                                                                                           .iterator(), "\n  " ) );
            }
        }

        compilerConfiguration.setSourceLocations( compileSourceRoots );

        compilerConfiguration.setAnnotationProcessors( annotationProcessors );

        compilerConfiguration.setProcessorPathEntries( resolveProcessorPathEntries() );

        compilerConfiguration.setSourceEncoding( encoding );

        compilerConfiguration.setFork( fork );

        if ( fork )
        {
            if ( !StringUtils.isEmpty( meminitial ) )
            {
                String value = getMemoryValue( meminitial );

                if ( value != null )
                {
                    compilerConfiguration.setMeminitial( value );
                }
                else
                {
                    getLog().info( "Invalid value for meminitial '" + meminitial + "'. Ignoring this option." );
                }
            }

            if ( !StringUtils.isEmpty( maxmem ) )
            {
                String value = getMemoryValue( maxmem );

                if ( value != null )
                {
                    compilerConfiguration.setMaxmem( value );
                }
                else
                {
                    getLog().info( "Invalid value for maxmem '" + maxmem + "'. Ignoring this option." );
                }
            }
        }

        compilerConfiguration.setExecutable( executable );

        compilerConfiguration.setWorkingDirectory( basedir );

        compilerConfiguration.setCompilerVersion( compilerVersion );

        compilerConfiguration.setBuildDirectory( buildDirectory );

        compilerConfiguration.setOutputFileName( outputFileName );

        if ( CompilerConfiguration.CompilerReuseStrategy.AlwaysNew.getStrategy().equals( this.compilerReuseStrategy ) )
        {
            compilerConfiguration.setCompilerReuseStrategy( CompilerConfiguration.CompilerReuseStrategy.AlwaysNew );
        }
        else if ( CompilerConfiguration.CompilerReuseStrategy.ReuseSame.getStrategy().equals(
            this.compilerReuseStrategy ) )
        {
            if ( getRequestThreadCount() > 1 )
            {
                if ( !skipMultiThreadWarning )
                {
                    getLog().warn( "You are in a multi-thread build and compilerReuseStrategy is set to reuseSame."
                                       + " This can cause issues in some environments (os/jdk)!"
                                       + " Consider using reuseCreated strategy."
                                       + System.getProperty( "line.separator" )
                                       + "If your env is fine with reuseSame, you can skip this warning with the "
                                       + "configuration field skipMultiThreadWarning "
                                       + "or -Dmaven.compiler.skipMultiThreadWarning=true" );
                }
            }
            compilerConfiguration.setCompilerReuseStrategy( CompilerConfiguration.CompilerReuseStrategy.ReuseSame );
        }
        else
        {

            compilerConfiguration.setCompilerReuseStrategy( CompilerConfiguration.CompilerReuseStrategy.ReuseCreated );
        }

        getLog().debug( "CompilerReuseStrategy: " + compilerConfiguration.getCompilerReuseStrategy().getStrategy() );

        compilerConfiguration.setForceJavacCompilerUse( forceJavacCompilerUse );

        boolean canUpdateTarget;

        IncrementalBuildHelper incrementalBuildHelper = new IncrementalBuildHelper( mojoExecution, session );

        final Set<File> sources;

        IncrementalBuildHelperRequest incrementalBuildHelperRequest = null;

        if ( useIncrementalCompilation )
        {
            getLog().debug( "useIncrementalCompilation enabled" );
            try
            {
                canUpdateTarget = compiler.canUpdateTarget( compilerConfiguration );

                sources = getCompileSources( compiler, compilerConfiguration );
                
                preparePaths( sources );

                incrementalBuildHelperRequest = new IncrementalBuildHelperRequest().inputFiles( sources );

                // CHECKSTYLE_OFF: LineLength
                if ( ( compiler.getCompilerOutputStyle().equals( CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES ) && !canUpdateTarget )
                    || isDependencyChanged()
                    || isSourceChanged( compilerConfiguration, compiler )
                    || incrementalBuildHelper.inputFileTreeChanged( incrementalBuildHelperRequest ) )
                    // CHECKSTYLE_ON: LineLength
                {
                    getLog().info( "Changes detected - recompiling the module!" );

                    compilerConfiguration.setSourceFiles( sources );
                }
                else
                {
                    getLog().info( "Nothing to compile - all classes are up to date" );

                    return;
                }
            }
            catch ( CompilerException e )
            {
                throw new MojoExecutionException( "Error while computing stale sources.", e );
            }
        }
        else
        {
            getLog().debug( "useIncrementalCompilation disabled" );
            
            Set<File> staleSources;
            try
            {
                staleSources =
                    computeStaleSources( compilerConfiguration, compiler, getSourceInclusionScanner( staleMillis ) );

                canUpdateTarget = compiler.canUpdateTarget( compilerConfiguration );

                if ( compiler.getCompilerOutputStyle().equals( CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES )
                    && !canUpdateTarget )
                {
                    getLog().info( "RESCANNING!" );
                    // TODO: This second scan for source files is sub-optimal
                    String inputFileEnding = compiler.getInputFileEnding( compilerConfiguration );

                    staleSources = computeStaleSources( compilerConfiguration, compiler,
                                                             getSourceInclusionScanner( inputFileEnding ) );
                }
                
            }
            catch ( CompilerException e )
            {
                throw new MojoExecutionException( "Error while computing stale sources.", e );
            }

            if ( staleSources.isEmpty() )
            {
                getLog().info( "Nothing to compile - all classes are up to date" );

                return;
            }

            compilerConfiguration.setSourceFiles( staleSources );
            
            try
            {
                // MCOMPILER-366: if sources contain the module-descriptor it must be used to define the modulepath
                sources = getCompileSources( compiler, compilerConfiguration );

                if ( getLog().isDebugEnabled() )
                {
                    getLog().debug( "#sources: " + sources.size() );
                    for ( File file : sources )
                    {
                        getLog().debug( file.getPath() );
                    }
                }

                preparePaths( sources );
            }
            catch ( CompilerException e )
            {
                throw new MojoExecutionException( "Error while computing stale sources.", e );
            }
        }
       
        // Dividing pathElements of classPath and modulePath is based on sourceFiles
        compilerConfiguration.setClasspathEntries( getClasspathElements() );

        compilerConfiguration.setModulepathEntries( getModulepathElements() );
        
        Map<String, String> effectiveCompilerArguments = getCompilerArguments();

        String effectiveCompilerArgument = getCompilerArgument();

        if ( ( effectiveCompilerArguments != null ) || ( effectiveCompilerArgument != null )
                        || ( compilerArgs != null ) )
        {
            if ( effectiveCompilerArguments != null )
            {
                for ( Map.Entry<String, String> me : effectiveCompilerArguments.entrySet() )
                {
                    String key = me.getKey();
                    String value = me.getValue();
                    if ( !key.startsWith( "-" ) )
                    {
                        key = "-" + key;
                    }

                    if ( key.startsWith( "-A" ) && StringUtils.isNotEmpty( value ) )
                    {
                        compilerConfiguration.addCompilerCustomArgument( key + "=" + value, null );
                    }
                    else
                    {
                        compilerConfiguration.addCompilerCustomArgument( key, value );
                    }
                }
            }
            if ( !StringUtils.isEmpty( effectiveCompilerArgument ) )
            {
                compilerConfiguration.addCompilerCustomArgument( effectiveCompilerArgument, null );
            }
            if ( compilerArgs != null )
            {
                for ( String arg : compilerArgs )
                {
                    compilerConfiguration.addCompilerCustomArgument( arg, null );
                }
            }
        }
        
        // ----------------------------------------------------------------------
        // Dump configuration
        // ----------------------------------------------------------------------
        if ( getLog().isDebugEnabled() )
        {
            getLog().debug( "Classpath:" );

            for ( String s : getClasspathElements() )
            {
                getLog().debug( " " + s );
            }

            if ( !getModulepathElements().isEmpty() )
            {
                getLog().debug( "Modulepath:" );
                for ( String s : getModulepathElements() )
                {
                    getLog().debug( " " + s );
                }
            }

            getLog().debug( "Source roots:" );

            for ( String root : getCompileSourceRoots() )
            {
                getLog().debug( " " + root );
            }

            try
            {
                if ( fork )
                {
                    if ( compilerConfiguration.getExecutable() != null )
                    {
                        getLog().debug( "Excutable: " );
                        getLog().debug( " " + compilerConfiguration.getExecutable() );
                    }
                }

                String[] cl = compiler.createCommandLine( compilerConfiguration );
                if ( cl != null && cl.length > 0 )
                {
                    StringBuilder sb = new StringBuilder();
                    sb.append( cl[0] );
                    for ( int i = 1; i < cl.length; i++ )
                    {
                        sb.append( " " );
                        sb.append( cl[i] );
                    }
                    getLog().debug( "Command line options:" );
                    getLog().debug( sb );
                }
            }
            catch ( CompilerException ce )
            {
                getLog().debug( ce );
            }
        }
        

        List<String> jpmsLines = new ArrayList<>();
        
        // See http://openjdk.java.net/jeps/261
        final List<String> runtimeArgs = Arrays.asList( "--upgrade-module-path", 
                                                  "--add-exports",
                                                  "--add-reads", 
                                                  "--add-modules", 
                                                  "--limit-modules" );
        
        // Custom arguments are all added as keys to an ordered Map
        Iterator<Map.Entry<String, String>> entryIter =
            compilerConfiguration.getCustomCompilerArgumentsEntries().iterator();
        while ( entryIter.hasNext() )
        {
            Map.Entry<String, String> entry = entryIter.next();
            
            if ( runtimeArgs.contains( entry.getKey() ) )
            {
                jpmsLines.add( entry.getKey() );
                
                String value = entry.getValue();
                if ( value == null )
                {
                    entry = entryIter.next();
                    value = entry.getKey();
                }
                jpmsLines.add( value );
            }
            else if ( "--patch-module".equals( entry.getKey() ) )
            {
                String value = entry.getValue();
                if ( value == null )
                {
                    entry = entryIter.next();
                    value = entry.getKey();
                }
                
                String[] values = value.split( "=" );

                StringBuilder patchModule = new StringBuilder( values[0] );
                patchModule.append( '=' );

                Set<String> patchModules = new LinkedHashSet<>();
                Set<Path> sourceRoots = new HashSet<>( getCompileSourceRoots().size() );
                for ( String sourceRoot : getCompileSourceRoots() )
                {
                    sourceRoots.add( Paths.get( sourceRoot ) );
                }

                String[] files = values[1].split( PS );

                for ( String file : files )
                {
                    Path filePath = Paths.get( file );
                    if ( getOutputDirectory().toPath().equals( filePath ) )
                    {
                        patchModules.add( "_" ); // this jar
                    }
                    else if ( getOutputDirectory().toPath().startsWith( filePath ) )
                    {
                        // multirelease, can be ignored
                        continue;
                    }
                    else if ( sourceRoots.contains( filePath ) )
                    {
                        patchModules.add( "_" ); // this jar
                    }
                    else
                    {
                        JavaModuleDescriptor descriptor = getPathElements().get( file );
                        
                        if ( descriptor == null )
                        {
                            if ( Files.isDirectory( filePath ) )
                            {
                                patchModules.add( file );
                            }
                            else
                            {
                                getLog().warn( "Can't locate " + file );
                            }
                        }
                        else if ( !values[0].equals( descriptor.name() ) )
                        {
                            patchModules.add( descriptor.name() );
                        }
                    }
                }

                StringBuilder sb = new StringBuilder();
                
                if ( !patchModules.isEmpty() )
                {
                    for ( String mod : patchModules )
                    {
                        if ( sb.length() > 0 )
                        {
                            sb.append( ", " );
                        }
                        // use 'invalid' separator to ensure values are transformed
                        sb.append( mod );
                    }

                    jpmsLines.add( "--patch-module" );
                    jpmsLines.add( patchModule + sb.toString() );
                }

            }
        }
        
        if ( !jpmsLines.isEmpty() ) 
        {
            Path jpmsArgs = Paths.get( getOutputDirectory().getAbsolutePath(), "META-INF/jpms.args" );
            try
            {
                Files.createDirectories( jpmsArgs.getParent() );
                
                Files.write( jpmsArgs, jpmsLines, Charset.defaultCharset() );
            }
            catch ( IOException e )
            {
                getLog().warn( e.getMessage() );
            }
        }


        // ----------------------------------------------------------------------
        // Compile!
        // ----------------------------------------------------------------------

        if ( StringUtils.isEmpty( compilerConfiguration.getSourceEncoding() ) )
        {
            getLog().warn( "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
                               + ", i.e. build is platform dependent!" );
        }

        CompilerResult compilerResult;


        if ( useIncrementalCompilation )
        {
            incrementalBuildHelperRequest.outputDirectory( getOutputDirectory() );

            incrementalBuildHelper.beforeRebuildExecution( incrementalBuildHelperRequest );

            getLog().debug( "incrementalBuildHelper#beforeRebuildExecution" );
        }

        try
        {
            try
            {
                compilerResult = compiler.performCompile( compilerConfiguration );
            }
            catch ( CompilerNotImplementedException cnie )
            {
                List<CompilerError> messages = compiler.compile( compilerConfiguration );
                compilerResult = convertToCompilerResult( messages );
            }
        }
        catch ( Exception e )
        {
            // TODO: don't catch Exception
            throw new MojoExecutionException( "Fatal error compiling", e );
        }

        if ( createMissingPackageInfoClass && compilerResult.isSuccess()
                && compiler.getCompilerOutputStyle() == CompilerOutputStyle.ONE_OUTPUT_FILE_PER_INPUT_FILE )
        {
            try
            {
                SourceMapping sourceMapping = getSourceMapping( compilerConfiguration, compiler );
                createMissingPackageInfoClasses( compilerConfiguration, sourceMapping, sources );
            }
            catch ( Exception e )
            {
                getLog().warn( "Error creating missing package info classes", e );

            }
        }

        if ( useIncrementalCompilation )
        {
            if ( incrementalBuildHelperRequest.getOutputDirectory().exists() )
            {
                getLog().debug( "incrementalBuildHelper#afterRebuildExecution" );
                // now scan the same directory again and create a diff
                incrementalBuildHelper.afterRebuildExecution( incrementalBuildHelperRequest );
            }
            else
            {
                getLog().debug(
                    "skip incrementalBuildHelper#afterRebuildExecution as the output directory doesn't exist" );
            }
        }

        List<CompilerMessage> warnings = new ArrayList<>();
        List<CompilerMessage> errors = new ArrayList<>();
        List<CompilerMessage> others = new ArrayList<>();
        for ( CompilerMessage message : compilerResult.getCompilerMessages() )
        {
            if ( message.getKind() == CompilerMessage.Kind.ERROR )
            {
                errors.add( message );
            }
            else if ( message.getKind() == CompilerMessage.Kind.WARNING
                || message.getKind() == CompilerMessage.Kind.MANDATORY_WARNING )
            {
                warnings.add( message );
            }
            else
            {
                others.add( message );
            }
        }

        if ( failOnError && !compilerResult.isSuccess() )
        {
            for ( CompilerMessage message : others )
            {
                assert message.getKind() != CompilerMessage.Kind.ERROR
                    && message.getKind() != CompilerMessage.Kind.WARNING
                    && message.getKind() != CompilerMessage.Kind.MANDATORY_WARNING;
                getLog().info( message.toString() );
            }
            if ( !warnings.isEmpty() )
            {
                getLog().info( "-------------------------------------------------------------" );
                getLog().warn( "COMPILATION WARNING : " );
                getLog().info( "-------------------------------------------------------------" );
                for ( CompilerMessage warning : warnings )
                {
                    getLog().warn( warning.toString() );
                }
                getLog().info( warnings.size() + ( ( warnings.size() > 1 ) ? " warnings " : " warning" ) );
                getLog().info( "-------------------------------------------------------------" );
            }

            if ( !errors.isEmpty() )
            {
                getLog().info( "-------------------------------------------------------------" );
                getLog().error( "COMPILATION ERROR : " );
                getLog().info( "-------------------------------------------------------------" );
                for ( CompilerMessage error : errors )
                {
                    getLog().error( error.toString() );
                }
                getLog().info( errors.size() + ( ( errors.size() > 1 ) ? " errors " : " error" ) );
                getLog().info( "-------------------------------------------------------------" );
            }

            if ( !errors.isEmpty() )
            {
                throw new CompilationFailureException( errors );
            }
            else
            {
                throw new CompilationFailureException( warnings );
            }
        }
        else
        {
            for ( CompilerMessage message : compilerResult.getCompilerMessages() )
            {
                switch ( message.getKind() )
                {
                    case NOTE:
                    case OTHER:
                        getLog().info( message.toString() );
                        break;

                    case ERROR:
                        getLog().error( message.toString() );
                        break;

                    case MANDATORY_WARNING:
                    case WARNING:
                    default:
                        getLog().warn( message.toString() );
                        break;
                }
            }
        }
    }

    private void createMissingPackageInfoClasses( CompilerConfiguration compilerConfiguration,
                                                  SourceMapping sourceMapping,
                                                  Set<File> sources )
            throws InclusionScanException, IOException
    {
        for ( File source : sources )
        {
            String path = source.toString();
            if ( path.endsWith( File.separator + "package-info.java" ) )
            {
                for ( String root : getCompileSourceRoots() )
                {
                    root = root + File.separator;
                    if ( path.startsWith( root ) )
                    {
                        String rel = path.substring( root.length() );
                        Set<File> files = sourceMapping.getTargetFiles( getOutputDirectory(), rel );
                        for ( File file : files )
                        {
                            if ( !file.exists() )
                            {
                                byte[] bytes = generatePackage( compilerConfiguration, rel );
                                Files.write( file.toPath(), bytes );
                            }
                        }
                    }
                }
            }
        }
    }

    private byte[] generatePackage( CompilerConfiguration compilerConfiguration, String javaFile )
    {
        int version = getOpcode( compilerConfiguration );
        ClassWriter cw = new ClassWriter( 0 );
        cw.visitSource( "package-info.java", null );
        cw.visit( version,
                Opcodes.ACC_SYNTHETIC | Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE,
                javaFile.substring( 0, javaFile.length() - ".java".length() ),
                null, "java/lang/Object", null );
        return cw.toByteArray();
    }

    private int getOpcode( CompilerConfiguration compilerConfiguration )
    {
        String version = compilerConfiguration.getReleaseVersion();
        if ( version == null )
        {
            version = compilerConfiguration.getTargetVersion();
            if ( version == null )
            {
                version = "1.5";
            }
        }
        if ( version.startsWith( "1." ) )
        {
            version = version.substring( 2 );
        }
        int iVersion = Integer.parseInt( version );
        if ( iVersion < 2 )
        {
            throw new IllegalArgumentException( "Unsupported java version '" + version + "'" );
        }
        return iVersion - 2 + Opcodes.V1_2;
    }

    protected boolean isTestCompile()
    {
        return false;
    }

    protected CompilerResult convertToCompilerResult( List<CompilerError> compilerErrors )
    {
        if ( compilerErrors == null )
        {
            return new CompilerResult();
        }
        List<CompilerMessage> messages = new ArrayList<>( compilerErrors.size() );
        boolean success = true;
        for ( CompilerError compilerError : compilerErrors )
        {
            messages.add(
                new CompilerMessage( compilerError.getFile(), compilerError.getKind(), compilerError.getStartLine(),
                                     compilerError.getStartColumn(), compilerError.getEndLine(),
                                     compilerError.getEndColumn(), compilerError.getMessage() ) );
            if ( compilerError.isError() )
            {
                success = false;
            }
        }

        return new CompilerResult( success, messages );
    }

    /**
     * @return all source files for the compiler
     */
    private Set<File> getCompileSources( Compiler compiler, CompilerConfiguration compilerConfiguration )
        throws MojoExecutionException, CompilerException
    {
        String inputFileEnding = compiler.getInputFileEnding( compilerConfiguration );
        if ( StringUtils.isEmpty( inputFileEnding ) )
        {
            // see MCOMPILER-199 GroovyEclipseCompiler doesn't set inputFileEnding
            // so we can presume it's all files from the source directory
            inputFileEnding = ".*";
        }
        SourceInclusionScanner scanner = getSourceInclusionScanner( inputFileEnding );

        SourceMapping mapping = getSourceMapping( compilerConfiguration, compiler );

        scanner.addSourceMapping( mapping );

        Set<File> compileSources = new HashSet<>();

        for ( String sourceRoot : getCompileSourceRoots() )
        {
            File rootFile = new File( sourceRoot );

            if ( !rootFile.isDirectory()
                || rootFile.getAbsoluteFile().equals( compilerConfiguration.getGeneratedSourcesDirectory() ) )
            {
                continue;
            }

            try
            {
                compileSources.addAll( scanner.getIncludedSources( rootFile, null ) );
            }
            catch ( InclusionScanException e )
            {
                throw new MojoExecutionException(
                    "Error scanning source root: \'" + sourceRoot + "\' for stale files to recompile.", e );
            }
        }

        return compileSources;
    }

    /**
     * @param compilerConfiguration
     * @param compiler
     * @return <code>true</code> if at least a single source file is newer than it's class file
     */
    private boolean isSourceChanged( CompilerConfiguration compilerConfiguration, Compiler compiler )
        throws CompilerException, MojoExecutionException
    {
        Set<File> staleSources =
            computeStaleSources( compilerConfiguration, compiler, getSourceInclusionScanner( staleMillis ) );

        if ( getLog().isDebugEnabled() )
        {
            for ( File f : staleSources )
            {
                getLog().debug( "Stale source detected: " + f.getAbsolutePath() );
            }
        }
        return !staleSources.isEmpty();
    }


    /**
     * try to get thread count if a Maven 3 build, using reflection as the plugin must not be maven3 api dependent
     *
     * @return number of thread for this build or 1 if not multi-thread build
     */
    protected int getRequestThreadCount()
    {
        try
        {
            Method getRequestMethod = session.getClass().getMethod( "getRequest" );
            Object mavenExecutionRequest = getRequestMethod.invoke( this.session );
            Method getThreadCountMethod = mavenExecutionRequest.getClass().getMethod( "getThreadCount" );
            String threadCount = (String) getThreadCountMethod.invoke( mavenExecutionRequest );
            return Integer.parseInt( threadCount );
        }
        catch ( Exception e )
        {
            getLog().debug( "unable to get threadCount for the current build: " + e.getMessage() );
        }
        return 1;
    }

    protected Date getBuildStartTime()
    {
        Date buildStartTime = null;
        try
        {
            Method getRequestMethod = session.getClass().getMethod( "getRequest" );
            Object mavenExecutionRequest = getRequestMethod.invoke( session );
            Method getStartTimeMethod = mavenExecutionRequest.getClass().getMethod( "getStartTime" );
            buildStartTime = (Date) getStartTimeMethod.invoke( mavenExecutionRequest );
        }
        catch ( Exception e )
        {
            getLog().debug( "unable to get start time for the current build: " + e.getMessage() );
        }

        if ( buildStartTime == null )
        {
            return new Date();
        }

        return buildStartTime;
    }


    private String getMemoryValue( String setting )
    {
        String value = null;

        // Allow '128' or '128m'
        if ( isDigits( setting ) )
        {
            value = setting + "m";
        }
        else if ( ( isDigits( setting.substring( 0, setting.length() - 1 ) ) )
            && ( setting.toLowerCase().endsWith( "m" ) ) )
        {
            value = setting;
        }
        return value;
    }

    //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.isEmpty() )
                {
                    tc = tcs.get( 0 );
                }
            }
            catch ( NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
                | InvocationTargetException e )
            {
                // ignore
            }
        }
        
        if ( tc == null )
        {
            tc = toolchainManager.getToolchainFromBuildContext( "jdk", session );
        }
        
        return tc;
    }

    private boolean isDigits( String string )
    {
        for ( int i = 0; i < string.length(); i++ )
        {
            if ( !Character.isDigit( string.charAt( i ) ) )
            {
                return false;
            }
        }
        return true;
    }

    private Set<File> computeStaleSources( CompilerConfiguration compilerConfiguration, Compiler compiler,
                                           SourceInclusionScanner scanner )
        throws MojoExecutionException, CompilerException
    {
        SourceMapping mapping = getSourceMapping( compilerConfiguration, compiler );

        File outputDirectory;
        CompilerOutputStyle outputStyle = compiler.getCompilerOutputStyle();
        if ( outputStyle == CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES )
        {
            outputDirectory = buildDirectory;
        }
        else
        {
            outputDirectory = getOutputDirectory();
        }

        scanner.addSourceMapping( mapping );

        Set<File> staleSources = new HashSet<>();

        for ( String sourceRoot : getCompileSourceRoots() )
        {
            File rootFile = new File( sourceRoot );

            if ( !rootFile.isDirectory() )
            {
                continue;
            }

            try
            {
                staleSources.addAll( scanner.getIncludedSources( rootFile, outputDirectory ) );
            }
            catch ( InclusionScanException e )
            {
                throw new MojoExecutionException(
                    "Error scanning source root: \'" + sourceRoot + "\' for stale files to recompile.", e );
            }
        }

        return staleSources;
    }

    private SourceMapping getSourceMapping( CompilerConfiguration compilerConfiguration, Compiler compiler )
        throws CompilerException, MojoExecutionException
    {
        CompilerOutputStyle outputStyle = compiler.getCompilerOutputStyle();

        SourceMapping mapping;
        if ( outputStyle == CompilerOutputStyle.ONE_OUTPUT_FILE_PER_INPUT_FILE )
        {
            mapping = new SuffixMapping( compiler.getInputFileEnding( compilerConfiguration ),
                                         compiler.getOutputFileEnding( compilerConfiguration ) );
        }
        else if ( outputStyle == CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES )
        {
            mapping = new SingleTargetSourceMapping( compiler.getInputFileEnding( compilerConfiguration ),
                                                     compiler.getOutputFile( compilerConfiguration ) );

        }
        else
        {
            throw new MojoExecutionException( "Unknown compiler output style: '" + outputStyle + "'." );
        }
        return mapping;
    }

    /**
     * @todo also in ant plugin. This should be resolved at some point so that it does not need to
     * be calculated continuously - or should the plugins accept empty source roots as is?
     */
    private static List<String> removeEmptyCompileSourceRoots( List<String> compileSourceRootsList )
    {
        List<String> newCompileSourceRootsList = new ArrayList<>();
        if ( compileSourceRootsList != null )
        {
            // copy as I may be modifying it
            for ( String srcDir : compileSourceRootsList )
            {
                if ( !newCompileSourceRootsList.contains( srcDir ) && new File( srcDir ).exists() )
                {
                    newCompileSourceRootsList.add( srcDir );
                }
            }
        }
        return newCompileSourceRootsList;
    }

    /**
     * We just compare the timestamps of all local dependency files (inter-module dependency classpath) and the own
     * generated classes and if we got a file which is &gt;= the build-started timestamp, then we caught a file which
     * got changed during this build.
     *
     * @return <code>true</code> if at least one single dependency has changed.
     */
    protected boolean isDependencyChanged()
    {
        if ( session == null )
        {
            // we just cannot determine it, so don't do anything beside logging
            getLog().info( "Cannot determine build start date, skipping incremental build detection." );
            return false;
        }

        if ( fileExtensions == null || fileExtensions.isEmpty() )
        {
            fileExtensions = Collections.unmodifiableList( Arrays.asList( "class", "jar" ) );
        }

        Date buildStartTime = getBuildStartTime();

        List<String> pathElements = new ArrayList<>();
        pathElements.addAll( getClasspathElements() );
        pathElements.addAll( getModulepathElements() );
        
        for ( String pathElement : pathElements )
        {
            File artifactPath = new File( pathElement );
            if ( artifactPath.isDirectory() || artifactPath.isFile() )
            {
                if ( hasNewFile( artifactPath, buildStartTime ) )
                {
                    getLog().debug( "New dependency detected: " + artifactPath.getAbsolutePath() );
                    return true;
                }
            }
        }

        // obviously there was no new file detected.
        return false;
    }

    /**
     * @param classPathEntry entry to check
     * @param buildStartTime time build start
     * @return if any changes occurred
     */
    private boolean hasNewFile( File classPathEntry, Date buildStartTime )
    {
        if ( !classPathEntry.exists() )
        {
            return false;
        }

        if ( classPathEntry.isFile() )
        {
            return classPathEntry.lastModified() >= buildStartTime.getTime()
                    && fileExtensions.contains( FileUtils.getExtension( classPathEntry.getName() ) );
        }

        File[] children = classPathEntry.listFiles();

        for ( File child : children )
        {
            if ( hasNewFile( child, buildStartTime ) )
            {
                return true;
            }
        }

        return false;
    }

    private List<String> resolveProcessorPathEntries()
        throws MojoExecutionException
    {
        if ( annotationProcessorPaths == null || annotationProcessorPaths.isEmpty() )
        {
            return null;
        }

        try
        {
            Set<String> elements = new LinkedHashSet<>();
            for ( DependencyCoordinate coord : annotationProcessorPaths )
            {
                ArtifactHandler handler = artifactHandlerManager.getArtifactHandler( coord.getType() );

                Artifact artifact = new DefaultArtifact(
                     coord.getGroupId(),
                     coord.getArtifactId(),
                     VersionRange.createFromVersionSpec( coord.getVersion() ),
                     Artifact.SCOPE_RUNTIME,
                     coord.getType(),
                     coord.getClassifier(),
                     handler,
                     false );

                ArtifactResolutionRequest request = new ArtifactResolutionRequest()
                                .setArtifact( artifact )
                                .setResolveRoot( true )
                                .setResolveTransitively( true )
                                .setLocalRepository( session.getLocalRepository() )
                                .setRemoteRepositories( project.getRemoteArtifactRepositories() );

                ArtifactResolutionResult resolutionResult = repositorySystem.resolve( request );

                resolutionErrorHandler.throwErrors( request, resolutionResult );

                for ( Artifact resolved : resolutionResult.getArtifacts() )
                {
                    elements.add( resolved.getFile().getAbsolutePath() );
                }
            }
            return new ArrayList<>( elements );
        }
        catch ( Exception e )
        {
            throw new MojoExecutionException( "Resolution of annotationProcessorPath dependencies failed: "
                + e.getLocalizedMessage(), e );
        }
    }

    private void writePlugin( MessageBuilder mb )
    {
        mb.a( "    <plugin>" ).newline();
        mb.a( "      <groupId>org.apache.maven.plugins</groupId>" ).newline();
        mb.a( "      <artifactId>maven-compiler-plugin</artifactId>" ).newline();
        
        String version = getMavenCompilerPluginVersion();
        if ( version != null )
        {
            mb.a( "      <version>" ).a( version ).a( "</version>" ).newline();
        }
        writeConfig( mb );
        
        mb.a( "    </plugin>" ).newline();
    }

    private void writeConfig( MessageBuilder mb )
    {
        mb.a( "      <configuration>" ).newline();

        if ( release != null )
        {
            mb.a( "        <release>" ).a( release ).a( "</release>" ).newline();
        }
        else if ( JavaVersion.JAVA_VERSION.isAtLeast( "9" ) )
        {
            String rls = target.replaceAll( ".\\.", "" );
            // when using Java9+, motivate to use release instead of source/target
            mb.a( "        <release>" ).a( rls ).a( "</release>" ).newline();
        }
        else
        {
            mb.a( "        <source>" ).a( source ).a( "</source>" ).newline();
            mb.a( "        <target>" ).a( target ).a( "</target>" ).newline();
        }
        mb.a( "      </configuration>" ).newline();
    }

    private String getMavenCompilerPluginVersion()
    {
        Properties pomProperties = new Properties();

        try ( InputStream is = AbstractCompilerMojo.class
            .getResourceAsStream( "/META-INF/maven/org.apache.maven.plugins/maven-compiler-plugin/pom.properties" ) )
        {
            if ( is != null )
            {
                pomProperties.load( is );
            }
        }
        catch ( IOException e )
        {
            // noop
        }

        return pomProperties.getProperty( "version" );
    }

    public void setTarget( String target )
    {
        this.target = target;
        targetOrReleaseSet = true;
    }

    public void setRelease( String release )
    {
        this.release = release;
        targetOrReleaseSet = true;
    }
}
