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.MavenExecutionRequest;
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.DirectoryScanResult;
import org.apache.maven.shared.utils.io.DirectoryScanner;
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" );

    private static final String INPUT_FILES_LST_FILENAME = "inputFiles.lst";

    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 Enable preview language features of the java compiler
     * @since 3.10.1
     */
    @Parameter( property = "maven.compiler.enablePreview", defaultValue = "false" )
    private boolean enablePreview;

    /**
     * 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;

    /**
     * Keyword to be appended to the <code>-implicit:</code> command-line switch.
     *
     * @since 3.10.2
     */
    @Parameter( property = "maven.compiler.implicit" )
    private String implicit;

    /**
     *
     */
    @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;

    @Parameter( defaultValue = "false", property = "maven.compiler.showCompilationChanges" )
    private boolean showCompilationChanges = false;
    /**
     * 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() );

        compilerConfiguration.setImplicitOption( implicit );

        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.setEnablePreview( enablePreview );

        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 );

                DirectoryScanResult dsr = computeInputFileTreeChanges( incrementalBuildHelper, sources );

                boolean idk = compiler.getCompilerOutputStyle()
                        .equals( CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES ) && !canUpdateTarget;
                boolean dependencyChanged = isDependencyChanged();
                boolean sourceChanged = isSourceChanged( compilerConfiguration, compiler );
                boolean inputFileTreeChanged = hasInputFileTreeChanged( dsr );
                // CHECKSTYLE_OFF: LineLength
                if ( idk
                    || dependencyChanged
                    || sourceChanged
                    || inputFileTreeChanged )
                    // CHECKSTYLE_ON: LineLength
                {
                    String cause = idk ? "idk" : ( dependencyChanged ? "dependency"
                            : ( sourceChanged ? "source" : "input tree" ) );
                    getLog().info( "Changes detected - recompiling the module! :" + cause );
                    if ( showCompilationChanges )
                    {
                        for ( String fileAdded : dsr.getFilesAdded() )
                        {
                            getLog().info( "\t+ " + fileAdded );
                        }
                        for ( String fileRemoved : dsr.getFilesRemoved() )
                        {
                            getLog().info( "\t- " + fileRemoved );
                        }
                    }

                    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() );
        
        compilerConfiguration.setIncludes( getIncludes() );

        compilerConfiguration.setExcludes( getExcludes() );

        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() )
                            {
                                File parentFile = file.getParentFile();
                                
                                if ( !parentFile.exists() )
                                {
                                    Files.createDirectories( parentFile.toPath() );
                                }
                                
                                byte[] bytes = generatePackage( compilerConfiguration, rel );
                                Files.write( file.toPath(), bytes );
                            }
                        }
                    }
                }
            }
        }
    }

    private byte[] generatePackage( CompilerConfiguration compilerConfiguration, String javaFile )
    {
        int version = getOpcode( compilerConfiguration );
        String internalPackageName = javaFile.substring( 0, javaFile.length() - ".java".length() );
        if ( File.separatorChar != '/' )
        {
            internalPackageName = internalPackageName.replace( File.separatorChar, '/' );
        }
        ClassWriter cw = new ClassWriter( 0 );
        cw.visit( version,
                Opcodes.ACC_SYNTHETIC | Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE,
                internalPackageName, null, "java/lang/Object", null );
        cw.visitSource( "package-info.java", 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;
    }

    protected abstract Set<String> getIncludes();

    protected abstract Set<String> getExcludes();

    /**
     * @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() || showCompilationChanges )
        {
            for ( File f : staleSources )
            {
                if ( showCompilationChanges )
                {
                    getLog().info( "Stale source detected: " + f.getAbsolutePath() );
                }
                else
                {
                    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()
    {
        return session.getRequest().getDegreeOfConcurrency();
    }

    protected Date getBuildStartTime()
    {
        MavenExecutionRequest request = session.getRequest();
        Date buildStartTime = request == null ? new Date() : request.getStartTime();
        return buildStartTime == null ? new Date() : 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 ) )
                {
                    if ( showCompilationChanges )
                    {
                        getLog().info( "New dependency detected: " + artifactPath.getAbsolutePath() );
                    }
                    else
                    {
                        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" );
    }

    private DirectoryScanResult computeInputFileTreeChanges( IncrementalBuildHelper ibh, Set<File> inputFiles )
            throws MojoExecutionException
    {
        File mojoConfigBase = ibh.getMojoStatusDirectory();
        File mojoConfigFile = new File( mojoConfigBase, INPUT_FILES_LST_FILENAME );

        String[] oldInputFiles = new String[0];

        if ( mojoConfigFile.exists() )
        {
            try
            {
                oldInputFiles = FileUtils.fileReadArray( mojoConfigFile );
            }
            catch ( IOException e )
            {
                throw new MojoExecutionException( "Error reading old mojo status " + mojoConfigFile, e );
            }
        }

        String[] inputFileNames = inputFiles.stream().map( File::getAbsolutePath ).toArray( String[]::new );

        DirectoryScanResult dsr = DirectoryScanner.diffFiles( oldInputFiles, inputFileNames );

        try
        {
            FileUtils.fileWriteArray( mojoConfigFile, inputFileNames );
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Error while storing the mojo status", e );
        }

        return dsr;
    }

    private boolean hasInputFileTreeChanged( DirectoryScanResult dsr )
    {
        return ( dsr.getFilesAdded().length > 0 || dsr.getFilesRemoved().length > 0 );
    }

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

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

    final String getImplicit()
    {
        return implicit;
    }
}
