package org.apache.maven.cli;

/*
 * 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 com.google.inject.AbstractModule;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.UnrecognizedOptionException;
import org.apache.maven.BuildAbort;
import org.apache.maven.InternalErrorException;
import org.apache.maven.Maven;
import org.apache.maven.building.FileSource;
import org.apache.maven.building.Problem;
import org.apache.maven.building.Source;
import org.apache.maven.cli.configuration.ConfigurationProcessor;
import org.apache.maven.cli.configuration.SettingsXmlConfigurationProcessor;
import org.apache.maven.cli.event.DefaultEventSpyContext;
import org.apache.maven.cli.event.ExecutionEventLogger;
import org.apache.maven.cli.internal.BootstrapCoreExtensionManager;
import org.apache.maven.cli.internal.extension.model.CoreExtension;
import org.apache.maven.cli.internal.extension.model.io.xpp3.CoreExtensionsXpp3Reader;
import org.apache.maven.cli.logging.Slf4jConfiguration;
import org.apache.maven.cli.logging.Slf4jConfigurationFactory;
import org.apache.maven.cli.logging.Slf4jLoggerManager;
import org.apache.maven.cli.logging.Slf4jStdoutLogger;
import org.apache.maven.cli.transfer.ConsoleMavenTransferListener;
import org.apache.maven.cli.transfer.QuietMavenTransferListener;
import org.apache.maven.cli.transfer.Slf4jMavenTransferListener;
import org.apache.maven.eventspy.internal.EventSpyDispatcher;
import org.apache.maven.exception.DefaultExceptionHandler;
import org.apache.maven.exception.ExceptionHandler;
import org.apache.maven.exception.ExceptionSummary;
import org.apache.maven.execution.DefaultMavenExecutionRequest;
import org.apache.maven.execution.ExecutionListener;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionRequestPopulationException;
import org.apache.maven.execution.MavenExecutionRequestPopulator;
import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule;
import org.apache.maven.extension.internal.CoreExports;
import org.apache.maven.extension.internal.CoreExtensionEntry;
import org.apache.maven.lifecycle.LifecycleExecutionException;
import org.apache.maven.logwrapper.LogLevelRecorder;
import org.apache.maven.logwrapper.MavenSlf4jWrapperFactory;
import org.apache.maven.model.building.ModelProcessor;
import org.apache.maven.project.MavenProject;
import org.apache.maven.properties.internal.EnvironmentUtils;
import org.apache.maven.properties.internal.SystemProperties;
import org.apache.maven.session.scope.internal.SessionScopeModule;
import org.apache.maven.shared.utils.logging.MessageBuilder;
import org.apache.maven.shared.utils.logging.MessageUtils;
import org.apache.maven.toolchain.building.DefaultToolchainsBuildingRequest;
import org.apache.maven.toolchain.building.ToolchainsBuilder;
import org.apache.maven.toolchain.building.ToolchainsBuildingResult;
import org.codehaus.plexus.ContainerConfiguration;
import org.codehaus.plexus.DefaultContainerConfiguration;
import org.codehaus.plexus.DefaultPlexusContainer;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.logging.LoggerManager;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.eclipse.aether.transfer.TransferListener;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;

import java.io.BufferedInputStream;
import java.io.Console;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.Comparator.comparing;
import static org.apache.maven.cli.ResolveFile.resolveFile;
import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;

// TODO push all common bits back to plexus cli and prepare for transition to Guice. We don't need 50 ways to make CLIs

/**
 * @author Jason van Zyl
 */
public class MavenCli
{
    public static final String LOCAL_REPO_PROPERTY = "maven.repo.local";

    public static final String MULTIMODULE_PROJECT_DIRECTORY = "maven.multiModuleProjectDirectory";

    public static final String USER_HOME = System.getProperty( "user.home" );

    public static final File USER_MAVEN_CONFIGURATION_HOME = new File( USER_HOME, ".m2" );

    public static final File DEFAULT_USER_TOOLCHAINS_FILE = new File( USER_MAVEN_CONFIGURATION_HOME, "toolchains.xml" );

    public static final File DEFAULT_GLOBAL_TOOLCHAINS_FILE =
        new File( System.getProperty( "maven.conf" ), "toolchains.xml" );

    private static final String EXT_CLASS_PATH = "maven.ext.class.path";

    private static final String EXTENSIONS_FILENAME = ".mvn/extensions.xml";

    private static final String MVN_MAVEN_CONFIG = ".mvn/maven.config";

    public static final String STYLE_COLOR_PROPERTY = "style.color";

    private ClassWorld classWorld;

    private LoggerManager plexusLoggerManager;

    private ILoggerFactory slf4jLoggerFactory;

    private Logger slf4jLogger;

    private EventSpyDispatcher eventSpyDispatcher;

    private ModelProcessor modelProcessor;

    private Maven maven;

    private MavenExecutionRequestPopulator executionRequestPopulator;

    private ToolchainsBuilder toolchainsBuilder;

    private DefaultSecDispatcher dispatcher;

    private Map<String, ConfigurationProcessor> configurationProcessors;

    public MavenCli()
    {
        this( null );
    }

    // This supports painless invocation by the Verifier during embedded execution of the core ITs
    public MavenCli( ClassWorld classWorld )
    {
        this.classWorld = classWorld;
    }

    public static void main( String[] args )
    {
        int result = main( args, null );

        System.exit( result );
    }

    public static int main( String[] args, ClassWorld classWorld )
    {
        MavenCli cli = new MavenCli();

        MessageUtils.systemInstall();
        MessageUtils.registerShutdownHook();
        int result = cli.doMain( new CliRequest( args, classWorld ) );
        MessageUtils.systemUninstall();

        return result;
    }

    // TODO need to externalize CliRequest
    public static int doMain( String[] args, ClassWorld classWorld )
    {
        MavenCli cli = new MavenCli();
        return cli.doMain( new CliRequest( args, classWorld ) );
    }

    /**
     * This supports painless invocation by the Verifier during embedded execution of the core ITs.
     * See <a href="http://maven.apache.org/shared/maven-verifier/xref/org/apache/maven/it/Embedded3xLauncher.html">
     * <code>Embedded3xLauncher</code> in <code>maven-verifier</code></a>
     */
    public int doMain( String[] args, String workingDirectory, PrintStream stdout, PrintStream stderr )
    {
        PrintStream oldout = System.out;
        PrintStream olderr = System.err;

        final Set<String> realms;
        if ( classWorld != null )
        {
            realms = new HashSet<>();
            for ( ClassRealm realm : classWorld.getRealms() )
            {
                realms.add( realm.getId() );
            }
        }
        else
        {
            realms = Collections.emptySet();
        }

        try
        {
            if ( stdout != null )
            {
                System.setOut( stdout );
            }
            if ( stderr != null )
            {
                System.setErr( stderr );
            }

            CliRequest cliRequest = new CliRequest( args, classWorld );
            cliRequest.workingDirectory = workingDirectory;

            return doMain( cliRequest );
        }
        finally
        {
            if ( classWorld != null )
            {
                for ( ClassRealm realm : new ArrayList<>( classWorld.getRealms() ) )
                {
                    String realmId = realm.getId();
                    if ( !realms.contains( realmId ) )
                    {
                        try
                        {
                            classWorld.disposeRealm( realmId );
                        }
                        catch ( NoSuchRealmException ignored )
                        {
                            // can't happen
                        }
                    }
                }
            }
            System.setOut( oldout );
            System.setErr( olderr );
        }
    }

    // TODO need to externalize CliRequest
    public int doMain( CliRequest cliRequest )
    {
        PlexusContainer localContainer = null;
        try
        {
            initialize( cliRequest );
            cli( cliRequest );
            properties( cliRequest );
            logging( cliRequest );
            version( cliRequest );
            localContainer = container( cliRequest );
            commands( cliRequest );
            configure( cliRequest );
            toolchains( cliRequest );
            populateRequest( cliRequest );
            encryption( cliRequest );
            repository( cliRequest );
            return execute( cliRequest );
        }
        catch ( ExitException e )
        {
            return e.exitCode;
        }
        catch ( UnrecognizedOptionException e )
        {
            // pure user error, suppress stack trace
            return 1;
        }
        catch ( BuildAbort e )
        {
            CLIReportingUtils.showError( slf4jLogger, "ABORTED", e, cliRequest.showErrors );

            return 2;
        }
        catch ( Exception e )
        {
            CLIReportingUtils.showError( slf4jLogger, "Error executing Maven.", e, cliRequest.showErrors );

            return 1;
        }
        finally
        {
            if ( localContainer != null )
            {
                localContainer.dispose();
            }
        }
    }

    void initialize( CliRequest cliRequest )
        throws ExitException
    {
        if ( cliRequest.workingDirectory == null )
        {
            cliRequest.workingDirectory = System.getProperty( "user.dir" );
        }

        if ( cliRequest.multiModuleProjectDirectory == null )
        {
            String basedirProperty = System.getProperty( MULTIMODULE_PROJECT_DIRECTORY );
            if ( basedirProperty == null )
            {
                System.err.format(
                    "-D%s system property is not set.", MULTIMODULE_PROJECT_DIRECTORY );
                throw new ExitException( 1 );
            }
            File basedir = new File( basedirProperty );
            try
            {
                cliRequest.multiModuleProjectDirectory = basedir.getCanonicalFile();
            }
            catch ( IOException e )
            {
                cliRequest.multiModuleProjectDirectory = basedir.getAbsoluteFile();
            }
        }

        //
        // Make sure the Maven home directory is an absolute path to save us from confusion with say drive-relative
        // Windows paths.
        //
        String mavenHome = System.getProperty( "maven.home" );

        if ( mavenHome != null )
        {
            System.setProperty( "maven.home", new File( mavenHome ).getAbsolutePath() );
        }
    }

    void cli( CliRequest cliRequest )
        throws Exception
    {
        //
        // Parsing errors can happen during the processing of the arguments and we prefer not having to check if
        // the logger is null and construct this so we can use an SLF4J logger everywhere.
        //
        slf4jLogger = new Slf4jStdoutLogger();

        CLIManager cliManager = new CLIManager();

        List<String> args = new ArrayList<>();
        CommandLine mavenConfig = null;
        try
        {
            File configFile = new File( cliRequest.multiModuleProjectDirectory, MVN_MAVEN_CONFIG );

            if ( configFile.isFile() )
            {
                for ( String arg : new String( Files.readAllBytes( configFile.toPath() ) ).split( "\\s+" ) )
                {
                    if ( !arg.isEmpty() )
                    {
                        args.add( arg );
                    }
                }

                mavenConfig = cliManager.parse( args.toArray( new String[0] ) );
                List<?> unrecongized = mavenConfig.getArgList();
                if ( !unrecongized.isEmpty() )
                {
                    throw new ParseException( "Unrecognized maven.config entries: " + unrecongized );
                }
            }
        }
        catch ( ParseException e )
        {
            System.err.println( "Unable to parse maven.config: " + e.getMessage() );
            cliManager.displayHelp( System.out );
            throw e;
        }

        try
        {
            if ( mavenConfig == null )
            {
                cliRequest.commandLine = cliManager.parse( cliRequest.args );
            }
            else
            {
                cliRequest.commandLine = cliMerge( cliManager.parse( cliRequest.args ), mavenConfig );
            }
        }
        catch ( ParseException e )
        {
            System.err.println( "Unable to parse command line options: " + e.getMessage() );
            cliManager.displayHelp( System.out );
            throw e;
        }

        if ( cliRequest.commandLine.hasOption( CLIManager.HELP ) )
        {
            cliManager.displayHelp( System.out );
            throw new ExitException( 0 );
        }

        if ( cliRequest.commandLine.hasOption( CLIManager.VERSION ) )
        {
            System.out.println( CLIReportingUtils.showVersion() );
            throw new ExitException( 0 );
        }
    }

    private CommandLine cliMerge( CommandLine mavenArgs, CommandLine mavenConfig )
    {
        CommandLine.Builder commandLineBuilder = new CommandLine.Builder();

        // the args are easy, cli first then config file
        for ( String arg : mavenArgs.getArgs() )
        {
            commandLineBuilder.addArg( arg );
        }
        for ( String arg : mavenConfig.getArgs() )
        {
            commandLineBuilder.addArg( arg );
        }

        // now add all options, except for -D with cli first then config file
        List<Option> setPropertyOptions = new ArrayList<>();
        for ( Option opt : mavenArgs.getOptions() )
        {
            if ( String.valueOf( CLIManager.SET_SYSTEM_PROPERTY ).equals( opt.getOpt() ) )
            {
                setPropertyOptions.add( opt );
            }
            else
            {
                commandLineBuilder.addOption( opt );
            }
        }
        for ( Option opt : mavenConfig.getOptions() )
        {
            commandLineBuilder.addOption( opt );
        }
        // finally add the CLI system properties
        for ( Option opt : setPropertyOptions )
        {
            commandLineBuilder.addOption( opt );
        }
        return commandLineBuilder.build();
    }

    /**
     * configure logging
     */
    void logging( CliRequest cliRequest )
    {
        // LOG LEVEL
        cliRequest.debug = cliRequest.commandLine.hasOption( CLIManager.DEBUG );
        cliRequest.quiet = !cliRequest.debug && cliRequest.commandLine.hasOption( CLIManager.QUIET );
        cliRequest.showErrors = cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.ERRORS );

        slf4jLoggerFactory = LoggerFactory.getILoggerFactory();
        Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration( slf4jLoggerFactory );

        if ( cliRequest.debug )
        {
            cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_DEBUG );
            slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.DEBUG );
        }
        else if ( cliRequest.quiet )
        {
            cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_ERROR );
            slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.ERROR );
        }
        // else fall back to default log level specified in conf
        // see https://issues.apache.org/jira/browse/MNG-2570

        // LOG COLOR
        String styleColor = cliRequest.getUserProperties().getProperty( STYLE_COLOR_PROPERTY, "auto" );
        if ( "always".equals( styleColor ) )
        {
            MessageUtils.setColorEnabled( true );
        }
        else if ( "never".equals( styleColor ) )
        {
            MessageUtils.setColorEnabled( false );
        }
        else if ( !"auto".equals( styleColor ) )
        {
            throw new IllegalArgumentException( "Invalid color configuration option [" + styleColor
                + "]. Supported values are (auto|always|never)." );
        }
        else if ( cliRequest.commandLine.hasOption( CLIManager.BATCH_MODE )
            || cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
        {
            MessageUtils.setColorEnabled( false );
        }

        // LOG STREAMS
        if ( cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
        {
            File logFile = new File( cliRequest.commandLine.getOptionValue( CLIManager.LOG_FILE ) );
            logFile = resolveFile( logFile, cliRequest.workingDirectory );

            // redirect stdout and stderr to file
            try
            {
                PrintStream ps = new PrintStream( new FileOutputStream( logFile ) );
                System.setOut( ps );
                System.setErr( ps );
            }
            catch ( FileNotFoundException e )
            {
                //
                // Ignore
                //
            }
        }

        slf4jConfiguration.activate();

        plexusLoggerManager = new Slf4jLoggerManager();
        slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );

        if ( cliRequest.commandLine.hasOption( CLIManager.FAIL_ON_SEVERITY ) )
        {
            String logLevelThreshold = cliRequest.commandLine.getOptionValue( CLIManager.FAIL_ON_SEVERITY );

            if ( slf4jLoggerFactory instanceof MavenSlf4jWrapperFactory )
            {
                LogLevelRecorder logLevelRecorder = new LogLevelRecorder( logLevelThreshold );
                ( (MavenSlf4jWrapperFactory) slf4jLoggerFactory ).setLogLevelRecorder( logLevelRecorder );
                slf4jLogger.info( "Enabled to break the build on log level {}.", logLevelThreshold );
            }
            else
            {
                slf4jLogger.warn( "Expected LoggerFactory to be of type '{}', but found '{}' instead. "
                        + "The --fail-on-severity flag will not take effect.",
                        MavenSlf4jWrapperFactory.class.getName(), slf4jLoggerFactory.getClass().getName() );
            }
        }
    }

    private void version( CliRequest cliRequest )
    {
        if ( cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.SHOW_VERSION ) )
        {
            System.out.println( CLIReportingUtils.showVersion() );
        }
    }

    private void commands( CliRequest cliRequest )
    {
        if ( cliRequest.showErrors )
        {
            slf4jLogger.info( "Error stacktraces are turned on." );
        }

        if ( MavenExecutionRequest.CHECKSUM_POLICY_WARN.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
        {
            slf4jLogger.info( "Disabling strict checksum verification on all artifact downloads." );
        }
        else if ( MavenExecutionRequest.CHECKSUM_POLICY_FAIL.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
        {
            slf4jLogger.info( "Enabling strict checksum verification on all artifact downloads." );
        }

        if ( slf4jLogger.isDebugEnabled() )
        {
            slf4jLogger.debug( "Message scheme: {}", ( MessageUtils.isColorEnabled() ? "color" : "plain" ) );
            if ( MessageUtils.isColorEnabled() )
            {
                MessageBuilder buff = MessageUtils.buffer();
                buff.a( "Message styles: " );
                buff.a( MessageUtils.level().debug( "debug" ) ).a( ' ' );
                buff.a( MessageUtils.level().info( "info" ) ).a( ' ' );
                buff.a( MessageUtils.level().warning( "warning" ) ).a( ' ' );
                buff.a( MessageUtils.level().error( "error" ) ).a( ' ' );

                buff.success( "success" ).a( ' ' );
                buff.failure( "failure" ).a( ' ' );
                buff.strong( "strong" ).a( ' ' );
                buff.mojo( "mojo" ).a( ' ' );
                buff.project( "project" );
                slf4jLogger.debug( buff.toString() );
            }
        }
    }

    //Needed to make this method package visible to make writing a unit test possible
    //Maybe it's better to move some of those methods to separate class (SoC).
    void properties( CliRequest cliRequest )
    {
        populateProperties( cliRequest.commandLine, cliRequest.systemProperties, cliRequest.userProperties );
    }

    PlexusContainer container( CliRequest cliRequest )
        throws Exception
    {
        if ( cliRequest.classWorld == null )
        {
            cliRequest.classWorld = new ClassWorld( "plexus.core", Thread.currentThread().getContextClassLoader() );
        }

        ClassRealm coreRealm = cliRequest.classWorld.getClassRealm( "plexus.core" );
        if ( coreRealm == null )
        {
            coreRealm = cliRequest.classWorld.getRealms().iterator().next();
        }

        List<File> extClassPath = parseExtClasspath( cliRequest );

        CoreExtensionEntry coreEntry = CoreExtensionEntry.discoverFrom( coreRealm );
        List<CoreExtensionEntry> extensions =
            loadCoreExtensions( cliRequest, coreRealm, coreEntry.getExportedArtifacts() );

        ClassRealm containerRealm = setupContainerRealm( cliRequest.classWorld, coreRealm, extClassPath, extensions );

        ContainerConfiguration cc = new DefaultContainerConfiguration().setClassWorld( cliRequest.classWorld )
            .setRealm( containerRealm ).setClassPathScanning( PlexusConstants.SCANNING_INDEX ).setAutoWiring( true )
            .setJSR250Lifecycle( true ).setName( "maven" );

        Set<String> exportedArtifacts = new HashSet<>( coreEntry.getExportedArtifacts() );
        Set<String> exportedPackages = new HashSet<>( coreEntry.getExportedPackages() );
        for ( CoreExtensionEntry extension : extensions )
        {
            exportedArtifacts.addAll( extension.getExportedArtifacts() );
            exportedPackages.addAll( extension.getExportedPackages() );
        }

        final CoreExports exports = new CoreExports( containerRealm, exportedArtifacts, exportedPackages );

        DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule()
        {
            @Override
            protected void configure()
            {
                bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
                bind( CoreExports.class ).toInstance( exports );
            }
        } );

        // NOTE: To avoid inconsistencies, we'll use the TCCL exclusively for lookups
        container.setLookupRealm( null );
        Thread.currentThread().setContextClassLoader( container.getContainerRealm() );

        container.setLoggerManager( plexusLoggerManager );

        for ( CoreExtensionEntry extension : extensions )
        {
            container.discoverComponents( extension.getClassRealm(), new SessionScopeModule( container ),
                                          new MojoExecutionScopeModule( container ) );
        }

        customizeContainer( container );

        container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );

        eventSpyDispatcher = container.lookup( EventSpyDispatcher.class );

        DefaultEventSpyContext eventSpyContext = new DefaultEventSpyContext();
        Map<String, Object> data = eventSpyContext.getData();
        data.put( "plexus", container );
        data.put( "workingDirectory", cliRequest.workingDirectory );
        data.put( "systemProperties", cliRequest.systemProperties );
        data.put( "userProperties", cliRequest.userProperties );
        data.put( "versionProperties", CLIReportingUtils.getBuildProperties() );
        eventSpyDispatcher.init( eventSpyContext );

        // refresh logger in case container got customized by spy
        slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );

        maven = container.lookup( Maven.class );

        executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );

        modelProcessor = createModelProcessor( container );

        configurationProcessors = container.lookupMap( ConfigurationProcessor.class );

        toolchainsBuilder = container.lookup( ToolchainsBuilder.class );

        dispatcher = (DefaultSecDispatcher) container.lookup( SecDispatcher.class, "maven" );

        return container;
    }

    private List<CoreExtensionEntry> loadCoreExtensions( CliRequest cliRequest, ClassRealm containerRealm,
                                                         Set<String> providedArtifacts )
    {
        if ( cliRequest.multiModuleProjectDirectory == null )
        {
            return Collections.emptyList();
        }

        File extensionsFile = new File( cliRequest.multiModuleProjectDirectory, EXTENSIONS_FILENAME );
        if ( !extensionsFile.isFile() )
        {
            return Collections.emptyList();
        }

        try
        {
            List<CoreExtension> extensions = readCoreExtensionsDescriptor( extensionsFile );
            if ( extensions.isEmpty() )
            {
                return Collections.emptyList();
            }

            ContainerConfiguration cc = new DefaultContainerConfiguration() //
                .setClassWorld( cliRequest.classWorld ) //
                .setRealm( containerRealm ) //
                .setClassPathScanning( PlexusConstants.SCANNING_INDEX ) //
                .setAutoWiring( true ) //
                .setJSR250Lifecycle( true ) //
                .setName( "maven" );

            DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule()
            {
                @Override
                protected void configure()
                {
                    bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
                }
            } );

            try
            {
                container.setLookupRealm( null );

                container.setLoggerManager( plexusLoggerManager );

                container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );

                Thread.currentThread().setContextClassLoader( container.getContainerRealm() );

                executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );

                configurationProcessors = container.lookupMap( ConfigurationProcessor.class );

                configure( cliRequest );

                MavenExecutionRequest request = DefaultMavenExecutionRequest.copy( cliRequest.request );

                populateRequest( cliRequest, request );

                request = executionRequestPopulator.populateDefaults( request );

                BootstrapCoreExtensionManager resolver = container.lookup( BootstrapCoreExtensionManager.class );

                return Collections.unmodifiableList( resolver.loadCoreExtensions( request, providedArtifacts,
                                                                                  extensions ) );

            }
            finally
            {
                executionRequestPopulator = null;
                container.dispose();
            }
        }
        catch ( RuntimeException e )
        {
            // runtime exceptions are most likely bugs in maven, let them bubble up to the user
            throw e;
        }
        catch ( Exception e )
        {
            slf4jLogger.warn( "Failed to read extensions descriptor from '{}'", extensionsFile, e );
        }
        return Collections.emptyList();
    }

    private List<CoreExtension> readCoreExtensionsDescriptor( File extensionsFile )
        throws IOException, XmlPullParserException
    {
        CoreExtensionsXpp3Reader parser = new CoreExtensionsXpp3Reader();

        try ( InputStream is = new BufferedInputStream( new FileInputStream( extensionsFile ) ) )
        {

            return parser.read( is ).getExtensions();
        }

    }

    private ClassRealm setupContainerRealm( ClassWorld classWorld, ClassRealm coreRealm, List<File> extClassPath,
                                            List<CoreExtensionEntry> extensions )
        throws Exception
    {
        if ( !extClassPath.isEmpty() || !extensions.isEmpty() )
        {
            ClassRealm extRealm = classWorld.newRealm( "maven.ext", null );

            extRealm.setParentRealm( coreRealm );

            slf4jLogger.debug( "Populating class realm '{}'", extRealm.getId() );

            for ( File file : extClassPath )
            {
                slf4jLogger.debug( "  included '{}'", file );

                extRealm.addURL( file.toURI().toURL() );
            }

            for ( CoreExtensionEntry entry : reverse( extensions ) )
            {
                Set<String> exportedPackages = entry.getExportedPackages();
                ClassRealm realm = entry.getClassRealm();
                for ( String exportedPackage : exportedPackages )
                {
                    extRealm.importFrom( realm, exportedPackage );
                }
                if ( exportedPackages.isEmpty() )
                {
                    // sisu uses realm imports to establish component visibility
                    extRealm.importFrom( realm, realm.getId() );
                }
            }

            return extRealm;
        }

        return coreRealm;
    }

    private static <T> List<T> reverse( List<T> list )
    {
        List<T> copy = new ArrayList<>( list );
        Collections.reverse( copy );
        return copy;
    }

    private List<File> parseExtClasspath( CliRequest cliRequest )
    {
        String extClassPath = cliRequest.userProperties.getProperty( EXT_CLASS_PATH );
        if ( extClassPath == null )
        {
            extClassPath = cliRequest.systemProperties.getProperty( EXT_CLASS_PATH );
        }

        List<File> jars = new ArrayList<>();

        if ( StringUtils.isNotEmpty( extClassPath ) )
        {
            for ( String jar : StringUtils.split( extClassPath, File.pathSeparator ) )
            {
                File file = resolveFile( new File( jar ), cliRequest.workingDirectory );

                slf4jLogger.debug( "  included '{}'", file );

                jars.add( file );
            }
        }

        return jars;
    }

    //
    // This should probably be a separate tool and not be baked into Maven.
    //
    private void encryption( CliRequest cliRequest )
        throws Exception
    {
        if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_MASTER_PASSWORD ) )
        {
            String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_MASTER_PASSWORD );

            if ( passwd == null )
            {
                Console cons = System.console();
                char[] password = ( cons == null ) ? null : cons.readPassword( "Master password: " );
                if ( password != null )
                {
                    // Cipher uses Strings
                    passwd = String.copyValueOf( password );

                    // Sun/Oracle advises to empty the char array
                    java.util.Arrays.fill( password, ' ' );
                }
            }

            DefaultPlexusCipher cipher = new DefaultPlexusCipher();

            System.out.println(
                cipher.encryptAndDecorate( passwd, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION ) );

            throw new ExitException( 0 );
        }
        else if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_PASSWORD ) )
        {
            String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_PASSWORD );

            if ( passwd == null )
            {
                Console cons = System.console();
                char[] password = ( cons == null ) ? null : cons.readPassword( "Password: " );
                if ( password != null )
                {
                    // Cipher uses Strings
                    passwd = String.copyValueOf( password );

                    // Sun/Oracle advises to empty the char array
                    java.util.Arrays.fill( password, ' ' );
                }
            }

            String configurationFile = dispatcher.getConfigurationFile();

            if ( configurationFile.startsWith( "~" ) )
            {
                configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
            }

            String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );

            String master = null;

            SettingsSecurity sec = SecUtil.read( file, true );
            if ( sec != null )
            {
                master = sec.getMaster();
            }

            if ( master == null )
            {
                throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
            }

            DefaultPlexusCipher cipher = new DefaultPlexusCipher();
            String masterPasswd = cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
            System.out.println( cipher.encryptAndDecorate( passwd, masterPasswd ) );

            throw new ExitException( 0 );
        }
    }

    private void repository( CliRequest cliRequest )
        throws Exception
    {
        if ( cliRequest.commandLine.hasOption( CLIManager.LEGACY_LOCAL_REPOSITORY ) || Boolean.getBoolean(
            "maven.legacyLocalRepo" ) )
        {
            cliRequest.request.setUseLegacyLocalRepository( true );
        }
    }

    private int execute( CliRequest cliRequest )
        throws MavenExecutionRequestPopulationException
    {
        MavenExecutionRequest request = executionRequestPopulator.populateDefaults( cliRequest.request );

        eventSpyDispatcher.onEvent( request );

        MavenExecutionResult result = maven.execute( request );

        eventSpyDispatcher.onEvent( result );

        eventSpyDispatcher.close();

        if ( result.hasExceptions() )
        {
            ExceptionHandler handler = new DefaultExceptionHandler();

            Map<String, String> references = new LinkedHashMap<>();

            List<MavenProject> failedProjects = new ArrayList<>();

            for ( Throwable exception : result.getExceptions() )
            {
                ExceptionSummary summary = handler.handleException( exception );

                logSummary( summary, references, "", cliRequest.showErrors );

                if ( exception instanceof LifecycleExecutionException )
                {
                    failedProjects.add ( ( (LifecycleExecutionException) exception ).getProject() );
                }
            }

            slf4jLogger.error( "" );

            if ( !cliRequest.showErrors )
            {
                slf4jLogger.error( "To see the full stack trace of the errors, re-run Maven with the '{}' switch.",
                        buffer().strong( "-e" ) );
            }
            if ( !slf4jLogger.isDebugEnabled() )
            {
                slf4jLogger.error( "Re-run Maven using the '{}' switch to enable full debug logging.",
                        buffer().strong( "-X" ) );
            }

            if ( !references.isEmpty() )
            {
                slf4jLogger.error( "" );
                slf4jLogger.error( "For more information about the errors and possible solutions"
                                       + ", please read the following articles:" );

                for ( Map.Entry<String, String> entry : references.entrySet() )
                {
                    slf4jLogger.error( "{} {}", buffer().strong( entry.getValue() ), entry.getKey() );
                }
            }

            if ( result.canResume() )
            {
                logBuildResumeHint( "mvn <args> -r" );
            }
            else if ( !failedProjects.isEmpty() )
            {
                List<MavenProject> sortedProjects = result.getTopologicallySortedProjects();

                // Sort the failedProjects list in the topologically sorted order.
                failedProjects.sort( comparing( sortedProjects::indexOf ) );

                MavenProject firstFailedProject = failedProjects.get( 0 );
                if ( !firstFailedProject.equals( sortedProjects.get( 0 ) ) )
                {
                    String resumeFromSelector = getResumeFromSelector( sortedProjects, firstFailedProject );
                    logBuildResumeHint( "mvn <args> -rf " + resumeFromSelector );
                }
            }

            if ( MavenExecutionRequest.REACTOR_FAIL_NEVER.equals( cliRequest.request.getReactorFailureBehavior() ) )
            {
                slf4jLogger.info( "Build failures were ignored." );

                return 0;
            }
            else
            {
                return 1;
            }
        }
        else
        {
            return 0;
        }
    }

    private void logBuildResumeHint( String resumeBuildHint )
    {
        slf4jLogger.error( "" );
        slf4jLogger.error( "After correcting the problems, you can resume the build with the command" );
        slf4jLogger.error( buffer().a( "  " ).strong( resumeBuildHint ).toString() );
    }

    /**
     * A helper method to determine the value to resume the build with {@code -rf} taking into account the edge case
     *   where multiple modules in the reactor have the same artifactId.
     * <p>
     * {@code -rf :artifactId} will pick up the first module which matches, but when multiple modules in the reactor
     *   have the same artifactId, effective failed module might be later in build reactor.
     * This means that developer will either have to type groupId or wait for build execution of all modules which
     *   were fine, but they are still before one which reported errors.
     * <p>Then the returned value is {@code groupId:artifactId} when there is a name clash and
     * {@code :artifactId} if there is no conflict.
     * This method is made package-private for testing purposes.
     *
     * @param mavenProjects Maven projects which are part of build execution.
     * @param firstFailedProject The first project which has failed.
     * @return Value for -rf flag to resume build exactly from place where it failed ({@code :artifactId} in general
     * and {@code groupId:artifactId} when there is a name clash).
     */
    String getResumeFromSelector( List<MavenProject> mavenProjects, MavenProject firstFailedProject )
    {
        boolean hasOverlappingArtifactId = mavenProjects.stream()
                .filter( project -> firstFailedProject.getArtifactId().equals( project.getArtifactId() ) )
                .count() > 1;

        if ( hasOverlappingArtifactId )
        {
            return firstFailedProject.getGroupId() + ":" + firstFailedProject.getArtifactId();
        }

        return ":" + firstFailedProject.getArtifactId();
    }

    private void logSummary( ExceptionSummary summary, Map<String, String> references, String indent,
                             boolean showErrors )
    {
        String referenceKey = "";

        if ( StringUtils.isNotEmpty( summary.getReference() ) )
        {
            referenceKey = references.get( summary.getReference() );
            if ( referenceKey == null )
            {
                referenceKey = "[Help " + ( references.size() + 1 ) + "]";
                references.put( summary.getReference(), referenceKey );
            }
        }

        String msg = summary.getMessage();

        if ( StringUtils.isNotEmpty( referenceKey ) )
        {
            if ( msg.indexOf( '\n' ) < 0 )
            {
                msg += " -> " + buffer().strong( referenceKey );
            }
            else
            {
                msg += "\n-> " + buffer().strong( referenceKey );
            }
        }

        String[] lines = msg.split( "(\r\n)|(\r)|(\n)" );
        String currentColor = "";

        for ( int i = 0; i < lines.length; i++ )
        {
            // add eventual current color inherited from previous line
            String line = currentColor + lines[i];

            // look for last ANSI escape sequence to check if nextColor
            Matcher matcher = LAST_ANSI_SEQUENCE.matcher( line );
            String nextColor = "";
            if ( matcher.find() )
            {
                nextColor = matcher.group( 1 );
                if ( ANSI_RESET.equals( nextColor ) )
                {
                    // last ANSI escape code is reset: no next color
                    nextColor = "";
                }
            }

            // effective line, with indent and reset if end is colored
            line = indent + line + ( "".equals( nextColor ) ? "" : ANSI_RESET );

            if ( ( i == lines.length - 1 ) && ( showErrors
                || ( summary.getException() instanceof InternalErrorException ) ) )
            {
                slf4jLogger.error( line, summary.getException() );
            }
            else
            {
                slf4jLogger.error( line );
            }

            currentColor = nextColor;
        }

        indent += "  ";

        for ( ExceptionSummary child : summary.getChildren() )
        {
            logSummary( child, references, indent, showErrors );
        }
    }

    private static final Pattern LAST_ANSI_SEQUENCE = Pattern.compile( "(\u001B\\[[;\\d]*[ -/]*[@-~])[^\u001B]*$" );

    private static final String ANSI_RESET = "\u001B\u005Bm";

    private void configure( CliRequest cliRequest )
        throws Exception
    {
        //
        // This is not ideal but there are events specifically for configuration from the CLI which I don't
        // believe are really valid but there are ITs which assert the right events are published so this
        // needs to be supported so the EventSpyDispatcher needs to be put in the CliRequest so that
        // it can be accessed by configuration processors.
        //
        cliRequest.request.setEventSpyDispatcher( eventSpyDispatcher );

        //
        // We expect at most 2 implementations to be available. The SettingsXmlConfigurationProcessor implementation
        // is always available in the core and likely always will be, but we may have another ConfigurationProcessor
        // present supplied by the user. The rule is that we only allow the execution of one ConfigurationProcessor.
        // If there is more than one then we execute the one supplied by the user, otherwise we execute the
        // the default SettingsXmlConfigurationProcessor.
        //
        int userSuppliedConfigurationProcessorCount = configurationProcessors.size() - 1;

        if ( userSuppliedConfigurationProcessorCount == 0 )
        {
            //
            // Our settings.xml source is historically how we have configured Maven from the CLI so we are going to
            // have to honour its existence forever. So let's run it.
            //
            configurationProcessors.get( SettingsXmlConfigurationProcessor.HINT ).process( cliRequest );
        }
        else if ( userSuppliedConfigurationProcessorCount == 1 )
        {
            //
            // Run the user supplied ConfigurationProcessor
            //
            for ( Entry<String, ConfigurationProcessor> entry : configurationProcessors.entrySet() )
            {
                String hint = entry.getKey();
                if ( !hint.equals( SettingsXmlConfigurationProcessor.HINT ) )
                {
                    ConfigurationProcessor configurationProcessor = entry.getValue();
                    configurationProcessor.process( cliRequest );
                }
            }
        }
        else if ( userSuppliedConfigurationProcessorCount > 1 )
        {
            //
            // There are too many ConfigurationProcessors so we don't know which one to run so report the error.
            //
            StringBuilder sb = new StringBuilder(
                String.format( "%nThere can only be one user supplied ConfigurationProcessor, there are %s:%n%n",
                               userSuppliedConfigurationProcessorCount ) );
            for ( Entry<String, ConfigurationProcessor> entry : configurationProcessors.entrySet() )
            {
                String hint = entry.getKey();
                if ( !hint.equals( SettingsXmlConfigurationProcessor.HINT ) )
                {
                    ConfigurationProcessor configurationProcessor = entry.getValue();
                    sb.append( String.format( "%s%n", configurationProcessor.getClass().getName() ) );
                }
            }
            throw new Exception( sb.toString() );
        }
    }

    void toolchains( CliRequest cliRequest )
        throws Exception
    {
        File userToolchainsFile;

        if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
        {
            userToolchainsFile =
                new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
            userToolchainsFile = resolveFile( userToolchainsFile, cliRequest.workingDirectory );

            if ( !userToolchainsFile.isFile() )
            {
                throw new FileNotFoundException(
                    "The specified user toolchains file does not exist: " + userToolchainsFile );
            }
        }
        else
        {
            userToolchainsFile = DEFAULT_USER_TOOLCHAINS_FILE;
        }

        File globalToolchainsFile;

        if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) )
        {
            globalToolchainsFile =
                new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) );
            globalToolchainsFile = resolveFile( globalToolchainsFile, cliRequest.workingDirectory );

            if ( !globalToolchainsFile.isFile() )
            {
                throw new FileNotFoundException(
                    "The specified global toolchains file does not exist: " + globalToolchainsFile );
            }
        }
        else
        {
            globalToolchainsFile = DEFAULT_GLOBAL_TOOLCHAINS_FILE;
        }

        cliRequest.request.setGlobalToolchainsFile( globalToolchainsFile );
        cliRequest.request.setUserToolchainsFile( userToolchainsFile );

        DefaultToolchainsBuildingRequest toolchainsRequest = new DefaultToolchainsBuildingRequest();
        if ( globalToolchainsFile.isFile() )
        {
            toolchainsRequest.setGlobalToolchainsSource( new FileSource( globalToolchainsFile ) );
        }
        if ( userToolchainsFile.isFile() )
        {
            toolchainsRequest.setUserToolchainsSource( new FileSource( userToolchainsFile ) );
        }

        eventSpyDispatcher.onEvent( toolchainsRequest );

        slf4jLogger.debug( "Reading global toolchains from '{}'",
                getLocation( toolchainsRequest.getGlobalToolchainsSource(), globalToolchainsFile ) );
        slf4jLogger.debug( "Reading user toolchains from '{}'",
                getLocation( toolchainsRequest.getUserToolchainsSource(), userToolchainsFile ) );

        ToolchainsBuildingResult toolchainsResult = toolchainsBuilder.build( toolchainsRequest );

        eventSpyDispatcher.onEvent( toolchainsResult );

        executionRequestPopulator.populateFromToolchains( cliRequest.request,
                                                          toolchainsResult.getEffectiveToolchains() );

        if ( !toolchainsResult.getProblems().isEmpty() && slf4jLogger.isWarnEnabled() )
        {
            slf4jLogger.warn( "" );
            slf4jLogger.warn( "Some problems were encountered while building the effective toolchains" );

            for ( Problem problem : toolchainsResult.getProblems() )
            {
                slf4jLogger.warn( "{} @ {}", problem.getMessage(), problem.getLocation() );
            }

            slf4jLogger.warn( "" );
        }
    }

    private Object getLocation( Source source, File defaultLocation )
    {
        if ( source != null )
        {
            return source.getLocation();
        }
        return defaultLocation;
    }

    protected MavenExecutionRequest populateRequest( CliRequest cliRequest )
    {
        return populateRequest( cliRequest, cliRequest.request );
    }

    private MavenExecutionRequest populateRequest( CliRequest cliRequest, MavenExecutionRequest request )
    {
        slf4jLoggerFactory = LoggerFactory.getILoggerFactory();
        CommandLine commandLine = cliRequest.commandLine;
        String workingDirectory = cliRequest.workingDirectory;
        boolean quiet = cliRequest.quiet;
        request.setShowErrors( cliRequest.showErrors ); // default: false
        File baseDirectory = new File( workingDirectory, "" ).getAbsoluteFile();

        disableOnPresentOption( commandLine, CLIManager.BATCH_MODE, request::setInteractiveMode );
        enableOnPresentOption( commandLine, CLIManager.SUPRESS_SNAPSHOT_UPDATES, request::setNoSnapshotUpdates );
        request.setGoals( commandLine.getArgList() );
        request.setReactorFailureBehavior( determineReactorFailureBehaviour ( commandLine ) );
        disableOnPresentOption( commandLine, CLIManager.NON_RECURSIVE, request::setRecursive );
        enableOnPresentOption( commandLine, CLIManager.OFFLINE, request::setOffline );
        enableOnPresentOption( commandLine, CLIManager.UPDATE_SNAPSHOTS, request::setUpdateSnapshots );
        request.setGlobalChecksumPolicy( determineGlobalCheckPolicy( commandLine ) );
        request.setBaseDirectory( baseDirectory );
        request.setSystemProperties( cliRequest.systemProperties );
        request.setUserProperties( cliRequest.userProperties );
        request.setMultiModuleProjectDirectory( cliRequest.multiModuleProjectDirectory );
        request.setPom( determinePom( commandLine, workingDirectory, baseDirectory ) );
        request.setTransferListener( determineTransferListener( quiet, commandLine, request ) );
        request.setExecutionListener( determineExecutionListener() );

        if ( ( request.getPom() != null ) && ( request.getPom().getParentFile() != null ) )
        {
            request.setBaseDirectory( request.getPom().getParentFile() );
        }

        request.setResumeFrom( commandLine.getOptionValue( CLIManager.RESUME_FROM ) );
        enableOnPresentOption( commandLine, CLIManager.RESUME, request::setResume );
        request.setMakeBehavior( determineMakeBehavior( commandLine ) );
        request.setCacheNotFound( true );
        request.setCacheTransferError( false );

        final ProjectActivation projectActivation = determineProjectActivation( commandLine );
        request.setSelectedProjects( projectActivation.activeProjects );
        request.setExcludedProjects( projectActivation.inactiveProjects );

        final ProfileActivation profileActivation = determineProfileActivation( commandLine );
        request.addActiveProfiles( profileActivation.activeProfiles );
        request.addInactiveProfiles( profileActivation.inactiveProfiles );

        final String localRepositoryPath = determineLocalRepositoryPath( request );
        if ( localRepositoryPath != null )
        {
            request.setLocalRepositoryPath( localRepositoryPath );
        }

        //
        // Builder, concurrency and parallelism
        //
        // We preserve the existing methods for builder selection which is to look for various inputs in the threading
        // configuration. We don't have an easy way to allow a pluggable builder to provide its own configuration
        // parameters but this is sufficient for now. Ultimately we want components like Builders to provide a way to
        // extend the command line to accept its own configuration parameters.
        //
        final String threadConfiguration = commandLine.getOptionValue( CLIManager.THREADS );

        if ( threadConfiguration != null )
        {
            //
            // Default to the standard multithreaded builder
            //
            request.setBuilderId( "multithreaded" );

            if ( threadConfiguration.contains( "C" ) )
            {
                request.setDegreeOfConcurrency( calculateDegreeOfConcurrencyWithCoreMultiplier( threadConfiguration ) );
            }
            else
            {
                request.setDegreeOfConcurrency( Integer.parseInt( threadConfiguration ) );
            }
        }

        //
        // Allow the builder to be overridden by the user if requested. The builders are now pluggable.
        //
        request.setBuilderId( commandLine.getOptionValue( CLIManager.BUILDER, request.getBuilderId() ) );

        return request;
    }

    private String determineLocalRepositoryPath( final MavenExecutionRequest request )
    {
        String userDefinedLocalRepo = request.getUserProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
        if ( userDefinedLocalRepo != null )
        {
            return userDefinedLocalRepo;
        }

        return request.getSystemProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
    }

    private File determinePom( final CommandLine commandLine, final String workingDirectory, final File baseDirectory )
    {
        String alternatePomFile = null;
        if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) )
        {
            alternatePomFile = commandLine.getOptionValue( CLIManager.ALTERNATE_POM_FILE );
        }

        if ( alternatePomFile != null )
        {
            File pom = resolveFile( new File( alternatePomFile ), workingDirectory );
            if ( pom.isDirectory() )
            {
                pom = new File( pom, "pom.xml" );
            }

            return pom;
        }
        else if ( modelProcessor != null )
        {
            File pom = modelProcessor.locatePom( baseDirectory );

            if ( pom.isFile() )
            {
                return pom;
            }
        }

        return null;
    }

    // Visible for testing
    static ProjectActivation determineProjectActivation ( final CommandLine commandLine )
    {
        final ProjectActivation projectActivation = new ProjectActivation();

        if ( commandLine.hasOption( CLIManager.PROJECT_LIST ) )
        {
            String[] projectOptionValues = commandLine.getOptionValues( CLIManager.PROJECT_LIST );

            if ( projectOptionValues != null )
            {
                for ( String projectOptionValue : projectOptionValues )
                {
                    StringTokenizer projectTokens = new StringTokenizer( projectOptionValue, "," );

                    while ( projectTokens.hasMoreTokens() )
                    {
                        String projectAction = projectTokens.nextToken().trim();

                        if ( projectAction.startsWith( "-" ) || projectAction.startsWith( "!" ) )
                        {
                            projectActivation.deactivate( projectAction.substring( 1 ) );
                        }
                        else if ( projectAction.startsWith( "+" ) )
                        {
                            projectActivation.activate( projectAction.substring( 1 ) );
                        }
                        else
                        {
                            projectActivation.activate( projectAction );
                        }
                    }
                }
            }

        }

        return projectActivation;
    }

    // Visible for testing
    static ProfileActivation determineProfileActivation( final CommandLine commandLine )
    {
        final ProfileActivation result = new ProfileActivation();

        if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
        {
            String[] profileOptionValues = commandLine.getOptionValues( CLIManager.ACTIVATE_PROFILES );
            if ( profileOptionValues != null )
            {
                for ( String profileOptionValue : profileOptionValues )
                {
                    StringTokenizer profileTokens = new StringTokenizer( profileOptionValue, "," );

                    while ( profileTokens.hasMoreTokens() )
                    {
                        String profileAction = profileTokens.nextToken().trim();

                        if ( profileAction.startsWith( "-" ) || profileAction.startsWith( "!" ) )
                        {
                            result.deactivate( profileAction.substring( 1 ) );
                        }
                        else if ( profileAction.startsWith( "+" ) )
                        {
                            result.activate( profileAction.substring( 1 ) );
                        }
                        else
                        {
                            result.activate( profileAction );
                        }
                    }
                }
            }
        }

        return result;
    }

    private ExecutionListener determineExecutionListener()
    {
        ExecutionListener executionListener = new ExecutionEventLogger();
        if ( eventSpyDispatcher != null )
        {
            return eventSpyDispatcher.chainListener( executionListener );
        }
        else
        {
            return executionListener;
        }
    }

    private String determineReactorFailureBehaviour( final CommandLine commandLine )
    {
        if ( commandLine.hasOption( CLIManager.FAIL_FAST ) )
        {
            return MavenExecutionRequest.REACTOR_FAIL_FAST;
        }
        else if ( commandLine.hasOption( CLIManager.FAIL_AT_END ) )
        {
            return MavenExecutionRequest.REACTOR_FAIL_AT_END;
        }
        else if ( commandLine.hasOption( CLIManager.FAIL_NEVER ) )
        {
            return MavenExecutionRequest.REACTOR_FAIL_NEVER;
        }
        else
        {
            // this is the default behavior.
            return MavenExecutionRequest.REACTOR_FAIL_FAST;
        }
    }

    private TransferListener determineTransferListener( final boolean quiet,
                                                        final CommandLine commandLine,
                                                        final MavenExecutionRequest request )
    {
        if ( quiet || commandLine.hasOption( CLIManager.NO_TRANSFER_PROGRESS ) )
        {
            return new QuietMavenTransferListener();
        }
        else if ( request.isInteractiveMode() && !commandLine.hasOption( CLIManager.LOG_FILE ) )
        {
            //
            // If we're logging to a file then we don't want the console transfer listener as it will spew
            // download progress all over the place
            //
            return getConsoleTransferListener( commandLine.hasOption( CLIManager.DEBUG ) );
        }
        else
        {
            // default: batch mode which goes along with interactive
            return getBatchTransferListener();
        }
    }

    private String determineMakeBehavior( final CommandLine cl )
    {
        if ( cl.hasOption( CLIManager.ALSO_MAKE ) && !cl.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
        {
            return MavenExecutionRequest.REACTOR_MAKE_UPSTREAM;
        }
        else if ( !cl.hasOption( CLIManager.ALSO_MAKE ) && cl.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
        {
            return MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM;
        }
        else if ( cl.hasOption( CLIManager.ALSO_MAKE ) && cl.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
        {
            return MavenExecutionRequest.REACTOR_MAKE_BOTH;
        }
        else
        {
            return null;
        }
    }

    private String determineGlobalCheckPolicy( final CommandLine commandLine )
    {
        if ( commandLine.hasOption( CLIManager.CHECKSUM_FAILURE_POLICY ) )
        {
            return MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
        }
        else if ( commandLine.hasOption( CLIManager.CHECKSUM_WARNING_POLICY ) )
        {
            return MavenExecutionRequest.CHECKSUM_POLICY_WARN;
        }
        else
        {
            return null;
        }
    }

    private void disableOnPresentOption( final CommandLine commandLine,
                                         final String option,
                                         final Consumer<Boolean> setting )
    {
        if ( commandLine.hasOption( option ) )
        {
            setting.accept( false );
        }
    }

    private void disableOnPresentOption( final CommandLine commandLine,
                                         final char option,
                                         final Consumer<Boolean> setting )
    {
        disableOnPresentOption( commandLine, String.valueOf( option ), setting );
    }

    private void enableOnPresentOption( final CommandLine commandLine,
                                        final String option,
                                        final Consumer<Boolean> setting )
    {
        if ( commandLine.hasOption( option ) )
        {
            setting.accept( true );
        }
    }

    private void enableOnPresentOption( final CommandLine commandLine,
                                        final char option,
                                        final Consumer<Boolean> setting )
    {
        enableOnPresentOption( commandLine, String.valueOf( option ), setting );
    }

    private void enableOnAbsentOption( final CommandLine commandLine,
                                       final char option,
                                       final Consumer<Boolean> setting )
    {
        if ( !commandLine.hasOption( option ) )
        {
            setting.accept( true );
        }
    }

    int calculateDegreeOfConcurrencyWithCoreMultiplier( String threadConfiguration )
    {
        int procs = Runtime.getRuntime().availableProcessors();
        return (int) ( Float.parseFloat( threadConfiguration.replace( "C", "" ) ) * procs );
    }

    // ----------------------------------------------------------------------
    // System properties handling
    // ----------------------------------------------------------------------

    static void populateProperties( CommandLine commandLine, Properties systemProperties, Properties userProperties )
    {
        EnvironmentUtils.addEnvVars( systemProperties );

        // ----------------------------------------------------------------------
        // Options that are set on the command line become system properties
        // and therefore are set in the session properties. System properties
        // are most dominant.
        // ----------------------------------------------------------------------

        if ( commandLine.hasOption( CLIManager.SET_SYSTEM_PROPERTY ) )
        {
            String[] defStrs = commandLine.getOptionValues( CLIManager.SET_SYSTEM_PROPERTY );

            if ( defStrs != null )
            {
                for ( String defStr : defStrs )
                {
                    setCliProperty( defStr, userProperties );
                }
            }
        }

        SystemProperties.addSystemProperties( systemProperties );

        // ----------------------------------------------------------------------
        // Properties containing info about the currently running version of Maven
        // These override any corresponding properties set on the command line
        // ----------------------------------------------------------------------

        Properties buildProperties = CLIReportingUtils.getBuildProperties();

        String mavenVersion = buildProperties.getProperty( CLIReportingUtils.BUILD_VERSION_PROPERTY );
        systemProperties.setProperty( "maven.version", mavenVersion );

        String mavenBuildVersion = CLIReportingUtils.createMavenVersionString( buildProperties );
        systemProperties.setProperty( "maven.build.version", mavenBuildVersion );
    }

    private static void setCliProperty( String property, Properties properties )
    {
        String name;

        String value;

        int i = property.indexOf( '=' );

        if ( i <= 0 )
        {
            name = property.trim();

            value = "true";
        }
        else
        {
            name = property.substring( 0, i ).trim();

            value = property.substring( i + 1 );
        }

        properties.setProperty( name, value );

        // ----------------------------------------------------------------------
        // I'm leaving the setting of system properties here as not to break
        // the SystemPropertyProfileActivator. This won't harm embedding. jvz.
        // ----------------------------------------------------------------------

        System.setProperty( name, value );
    }

    static class ExitException
        extends Exception
    {
        int exitCode;

        ExitException( int exitCode )
        {
            this.exitCode = exitCode;
        }
    }

    //
    // Customizations available via the CLI
    //

    protected TransferListener getConsoleTransferListener( boolean printResourceNames )
    {
        return new ConsoleMavenTransferListener( System.out, printResourceNames );
    }

    protected TransferListener getBatchTransferListener()
    {
        return new Slf4jMavenTransferListener();
    }

    protected void customizeContainer( PlexusContainer container )
    {
    }

    protected ModelProcessor createModelProcessor( PlexusContainer container )
        throws ComponentLookupException
    {
        return container.lookup( ModelProcessor.class );
    }

    // Visible for testing
    static class ProfileActivation
    {
        final List<String> activeProfiles = new ArrayList<>();
        final List<String> inactiveProfiles = new ArrayList<>();

        public void deactivate( final String profile )
        {
            inactiveProfiles.add( profile );
        }

        public void activate( final String profile )
        {
            activeProfiles.add( profile );
        }
    }

    // Visible for testing
    static class ProjectActivation
    {
        List<String> activeProjects;
        List<String> inactiveProjects;

        public void deactivate( final String project )
        {
            if ( inactiveProjects == null )
            {
                inactiveProjects = new ArrayList<>();
            }
            inactiveProjects.add( project );
        }

        public void activate( final String project )
        {
            if ( activeProjects == null )
            {
                activeProjects = new ArrayList<>();
            }
            activeProjects.add( project );
        }
    }
}
