package org.apache.maven.plugin;

/*
 * 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 static org.apache.maven.container.ContainerUtils.findChildComponentHints;

import org.apache.maven.MavenArtifactFilterManager;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.metadata.ResolutionGroup;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.RuntimeInformation;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.monitor.event.EventDispatcher;
import org.apache.maven.monitor.event.MavenEvents;
import org.apache.maven.monitor.logging.DefaultLog;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugin.version.PluginVersionManager;
import org.apache.maven.plugin.version.PluginVersionNotFoundException;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.artifact.InvalidDependencyVersionException;
import org.apache.maven.project.artifact.MavenMetadataSource;
import org.apache.maven.project.path.PathTranslator;
import org.apache.maven.reporting.MavenReport;
import org.apache.maven.settings.Settings;
import org.apache.maven.wagon.Wagon;
import org.codehaus.classworlds.ClassRealm;
import org.codehaus.classworlds.NoSuchRealmException;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
import org.codehaus.plexus.component.configurator.ComponentConfigurator;
import org.codehaus.plexus.component.configurator.ConfigurationListener;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.component.discovery.ComponentDiscoveryListener;
import org.codehaus.plexus.component.repository.ComponentDescriptor;
import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.Xpp3Dom;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class DefaultPluginManager
    extends AbstractLogEnabled
    implements PluginManager, Initializable, Contextualizable
{
    protected PlexusContainer container;

    protected PluginDescriptorBuilder pluginDescriptorBuilder;

    protected ArtifactFilter artifactFilter;

    private Log mojoLogger;

    private Map resolvedCoreArtifactFiles = new HashMap();

    // component requirements
    protected PathTranslator pathTranslator;

    protected MavenPluginCollector pluginCollector;

    protected PluginVersionManager pluginVersionManager;

    protected ArtifactFactory artifactFactory;

    protected ArtifactResolver artifactResolver;

    protected ArtifactMetadataSource artifactMetadataSource;

    protected RuntimeInformation runtimeInformation;

    protected MavenProjectBuilder mavenProjectBuilder;
    
    protected PluginMappingManager pluginMappingManager;

    // END component requirements

    public DefaultPluginManager()
    {
        pluginDescriptorBuilder = new PluginDescriptorBuilder();
    }

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    public PluginDescriptor getPluginDescriptorForPrefix( String prefix )
    {
        return pluginCollector.getPluginDescriptorForPrefix( prefix );
    }

    public Plugin getPluginDefinitionForPrefix( String prefix,
                                                MavenSession session,
                                                MavenProject project )
    {
        // TODO: since this is only used in the lifecycle executor, maybe it should be moved there? There is no other
        // use for the mapping manager in here
        return pluginMappingManager.getByPrefix( prefix, session.getSettings().getPluginGroups(),
                                                 project.getPluginArtifactRepositories(),
                                                 session.getLocalRepository() );
    }

    /**
     * {@inheritDoc}
     */
    public PluginDescriptor verifyPlugin( Plugin plugin,
                                          MavenProject project,
                                          Settings settings,
                                          ArtifactRepository localRepository )
        throws ArtifactResolutionException, PluginVersionResolutionException, ArtifactNotFoundException,
        InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException,
        PluginVersionNotFoundException
    {
        // TODO: this should be possibly outside
        // All version-resolution logic has been moved to DefaultPluginVersionManager.
        if ( plugin.getVersion() == null )
        {
            String version = pluginVersionManager.resolvePluginVersion( plugin.getGroupId(), plugin.getArtifactId(),
                                                                        project, settings, localRepository );
            plugin.setVersion( version );
        }

        return verifyVersionedPlugin( plugin, project, localRepository );
    }

    private PluginDescriptor verifyVersionedPlugin( Plugin plugin,
                                                    MavenProject project,
                                                    ArtifactRepository localRepository )
        throws PluginVersionResolutionException, ArtifactNotFoundException, ArtifactResolutionException,
        InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException
    {
        // TODO: this might result in an artifact "RELEASE" being resolved continuously
        // FIXME: need to find out how a plugin gets marked as 'installed'
        // and no ChildContainer exists. The check for that below fixes
        // the 'Can't find plexus container for plugin: xxx' error.
        try
        {
            VersionRange versionRange = VersionRange.createFromVersionSpec( plugin.getVersion() );

            List remoteRepositories = new ArrayList();
            remoteRepositories.addAll( project.getPluginArtifactRepositories() );
            remoteRepositories.addAll( project.getRemoteArtifactRepositories() );

            checkRequiredMavenVersion( plugin, localRepository, remoteRepositories );

            Artifact pluginArtifact =
                artifactFactory.createPluginArtifact( plugin.getGroupId(), plugin.getArtifactId(), versionRange );

            pluginArtifact = project.replaceWithActiveArtifact( pluginArtifact );

            artifactResolver.resolve( pluginArtifact, project.getPluginArtifactRepositories(), localRepository );

            plugin.setVersion( pluginArtifact.getBaseVersion() );

            String pluginKey = PluginUtils.constructVersionedKey( plugin );

            PlexusContainer pluginContainer = container.getChildContainer( pluginKey );

            File pluginFile = pluginArtifact.getFile();

            if ( !pluginCollector.isPluginInstalled( plugin ) || ( pluginContainer == null ) )
            {
                addPlugin( plugin, pluginArtifact, project, localRepository );
            }
            else if ( pluginFile.lastModified() > pluginContainer.getCreationDate().getTime() )
            {
                getLogger().info(
                    "Reloading plugin container for: " + pluginKey + ". The plugin artifact has changed." );

                pluginContainer.dispose();

                pluginCollector.flushPluginDescriptor( plugin );

                addPlugin( plugin, pluginArtifact, project, localRepository );
            }

            project.addPlugin( plugin );
        }
        catch ( ArtifactNotFoundException e )
        {
            String groupId = plugin.getGroupId();
            String artifactId = plugin.getArtifactId();
            String version = plugin.getVersion();

            if ( ( groupId == null ) || ( artifactId == null ) || ( version == null ) )
            {
                throw new PluginNotFoundException( e );
            }
            else if ( groupId.equals( e.getGroupId() ) && artifactId.equals( e.getArtifactId() ) &&
                version.equals( e.getVersion() ) && "maven-plugin".equals( e.getType() ) )
            {
                throw new PluginNotFoundException( e );
            }
            else
            {
                throw e;
            }
        }

        return pluginCollector.getPluginDescriptor( plugin );
    }

    /**
     * @todo would be better to store this in the plugin descriptor, but then it won't be available to the version
     * manager which executes before the plugin is instantiated
     */
    private void checkRequiredMavenVersion( Plugin plugin,
                                            ArtifactRepository localRepository,
                                            List remoteRepositories )
        throws PluginVersionResolutionException, InvalidPluginException
    {
        try
        {
            Artifact artifact = artifactFactory.createProjectArtifact( plugin.getGroupId(), plugin.getArtifactId(),
                                                                       plugin.getVersion() );
            MavenProject project =
                mavenProjectBuilder.buildFromRepository( artifact, remoteRepositories, localRepository, false );
            // if we don't have the required Maven version, then ignore an update
            if ( ( project.getPrerequisites() != null ) && ( project.getPrerequisites().getMaven() != null ) )
            {
                DefaultArtifactVersion requiredVersion =
                    new DefaultArtifactVersion( project.getPrerequisites().getMaven() );
                if ( runtimeInformation.getApplicationVersion().compareTo( requiredVersion ) < 0 )
                {
                    throw new PluginVersionResolutionException( plugin.getGroupId(), plugin.getArtifactId(),
                                                                "Plugin requires Maven version " + requiredVersion );
                }
            }
        }
        catch ( ProjectBuildingException e )
        {
            throw new InvalidPluginException(
                "Unable to build project for plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
        }
    }

    protected void addPlugin( Plugin plugin,
                              Artifact pluginArtifact,
                              MavenProject project,
                              ArtifactRepository localRepository )
        throws PluginManagerException, InvalidPluginException
    {
        PlexusContainer child;

        try
        {
            MavenPluginValidator validator = new MavenPluginValidator( pluginArtifact );

            String key = PluginUtils.constructVersionedKey( plugin ).intern();
            child = container.createChildContainer( key,
                                                    Collections.singletonList( pluginArtifact.getFile() ),
                                                    Collections.EMPTY_MAP,
                                                    Arrays.asList( new ComponentDiscoveryListener[] { validator, pluginCollector } ) );

            // remove listeners for efficiency since they are only needed for the initial stage and
            // should not be applied to the plugin's dependencies
            child.removeComponentDiscoveryListener( validator );
            child.removeComponentDiscoveryListener( pluginCollector );

            if ( validator.hasErrors() )
            {
                String msg = "Plugin '" + key + "' has an invalid descriptor:";
                int count = 1;
                for ( Iterator i = validator.getErrors().iterator(); i.hasNext(); )
                {
                    msg += "\n" + count + ") " + i.next();
                    count++;
                }
                throw new PluginManagerException( msg );
            }

            try
            {
                child.getContainerRealm().importFrom( "plexus.core", "org.codehaus.plexus.util.xml.Xpp3Dom" );
                child.getContainerRealm().importFrom( "plexus.core", "org.codehaus.plexus.util.xml.pull.XmlPullParser" );
                child.getContainerRealm().importFrom( "plexus.core", "org.codehaus.plexus.util.xml.pull.XmlPullParserException" );
                child.getContainerRealm().importFrom( "plexus.core", "org.codehaus.plexus.util.xml.pull.XmlSerializer" );

                // MNG-2878
                child.getContainerRealm().importFrom( "plexus.core", "/default-report.xml" );
            }
            catch ( NoSuchRealmException e )
            {
                // won't happen
            }
        }
        catch ( PlexusContainerException e )
        {
            throw new PluginManagerException(
                "Failed to create plugin container for plugin '" + plugin + "': " + e.getMessage(), e );
        }

        // this plugin's descriptor should have been discovered in the child creation, so we should be able to
        // circle around and set the artifacts and class realm
        PluginDescriptor addedPlugin = pluginCollector.getPluginDescriptor( plugin );

        if ( addedPlugin == null )
        {
            throw new IllegalStateException( "The plugin descriptor for the plugin " + plugin + " was not found."
                + " Please verify that the plugin JAR " + pluginArtifact.getFile() + " is intact." );
        }

        addedPlugin.setClassRealm( child.getContainerRealm() );

        // we're only setting the plugin's artifact itself as the artifact list, to allow it to be retrieved
        // later when the plugin is first invoked. Retrieving this artifact will in turn allow us to
        // transitively resolve its dependencies, and add them to the plugin container...
        addedPlugin.setArtifacts( Collections.singletonList( pluginArtifact ) );
        addedPlugin.setPluginArtifact( pluginArtifact );

        try
        {
            // the only Plugin instance which will have dependencies is the one specified in the project.
            // We need to look for a Plugin instance there, in case the instance we're using didn't come from
            // the project.
            Plugin projectPlugin = (Plugin) project.getBuild().getPluginsAsMap().get( plugin.getKey() );

            if ( projectPlugin == null )
            {
                projectPlugin = plugin;
            }

            Set artifacts = MavenMetadataSource.createArtifacts( artifactFactory, projectPlugin.getDependencies(), null,
                                                                 null, project );

//            Set artifacts =
//                MavenMetadataSource.createArtifacts( artifactFactory, plugin.getDependencies(), null, null, project );

            addedPlugin.setIntroducedDependencyArtifacts( artifacts );
        }
        catch ( InvalidDependencyVersionException e )
        {
            throw new InvalidPluginException( "Plugin '" + plugin + "' is invalid: " + e.getMessage(), e );
        }
    }

    // ----------------------------------------------------------------------
    // Mojo execution
    // ----------------------------------------------------------------------

    public void executeMojo( MavenProject project,
                             MojoExecution mojoExecution,
                             MavenSession session )
        throws ArtifactResolutionException, MojoExecutionException, MojoFailureException, ArtifactNotFoundException,
        InvalidDependencyVersionException, PluginManagerException, PluginConfigurationException
    {
        MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();

        // NOTE: I'm putting these checks in here, since this is the central point of access for
        // anything that wants to execute a mojo.
        if ( mojoDescriptor.isProjectRequired() && !session.isUsingPOMsFromFilesystem() )
        {
            throw new MojoExecutionException( "Cannot execute mojo: " + mojoDescriptor.getGoal() +
                ". It requires a project with an existing pom.xml, but the build is not using one." );
        }

        if ( mojoDescriptor.isOnlineRequired() && session.getSettings().isOffline() )
        {
            // TODO: Should we error out, or simply warn and skip??
            throw new MojoExecutionException( "Mojo: " + mojoDescriptor.getGoal() +
                " requires online mode for execution. Maven is currently offline." );
        }

        if ( mojoDescriptor.isDependencyResolutionRequired() != null )
        {
            Collection projects;

            if ( mojoDescriptor.isAggregator() )
            {
                projects = session.getSortedProjects();
            }
            else
            {
                projects = Collections.singleton( project );
            }

            for ( Iterator i = projects.iterator(); i.hasNext(); )
            {
                MavenProject p = (MavenProject) i.next();

                resolveTransitiveDependencies( session, artifactResolver,
                                               mojoDescriptor.isDependencyResolutionRequired(), artifactFactory, p, mojoDescriptor.isAggregator() );
            }

            downloadDependencies( project, session, artifactResolver );
        }

        String goalName = mojoDescriptor.getFullGoalName();

        Mojo plugin;

        PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();

        String goalId = mojoDescriptor.getGoal();
        String groupId = pluginDescriptor.getGroupId();
        String artifactId = pluginDescriptor.getArtifactId();
        String executionId = mojoExecution.getExecutionId();

        Xpp3Dom dom = project.getGoalConfiguration( groupId, artifactId, executionId, goalId );
        Xpp3Dom reportDom = project.getReportConfiguration( groupId, artifactId, executionId );
        dom = Xpp3Dom.mergeXpp3Dom( dom, reportDom );
        if ( mojoExecution.getConfiguration() != null )
        {
            dom = Xpp3Dom.mergeXpp3Dom( dom, mojoExecution.getConfiguration() );
        }

        plugin = getConfiguredMojo( session, dom, project, false, mojoExecution );

        // Event monitoring.
        String event = MavenEvents.MOJO_EXECUTION;
        EventDispatcher dispatcher = session.getEventDispatcher();

        String goalExecId = goalName;

        if ( mojoExecution.getExecutionId() != null )
        {
            goalExecId += " {execution: " + mojoExecution.getExecutionId() + "}";
        }

        dispatcher.dispatchStart( event, goalExecId );

        ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();

        try
        {
            Thread.currentThread().setContextClassLoader(
                mojoDescriptor.getPluginDescriptor().getClassRealm().getClassLoader() );

            plugin.execute();

            dispatcher.dispatchEnd( event, goalExecId );
        }
        catch ( MojoExecutionException e )
        {
            session.getEventDispatcher().dispatchError( event, goalExecId, e );

            throw e;
        }
        catch ( MojoFailureException e )
        {
            session.getEventDispatcher().dispatchError( event, goalExecId, e );

            throw e;
        }
        catch ( LinkageError e )
        {
            if ( getLogger().isFatalErrorEnabled() )
            {
                getLogger().fatalError(
                                        plugin.getClass().getName() + "#execute() caused a linkage error ("
                                            + e.getClass().getName() + ") and may be out-of-date. Check the realms:" );

                ClassRealm pluginRealm = mojoDescriptor.getPluginDescriptor().getClassRealm();
                StringBuffer sb = new StringBuffer();
                sb.append( "Plugin realm = " + pluginRealm.getId() ).append( '\n' );
                for ( int i = 0; i < pluginRealm.getConstituents().length; i++ )
                {
                    sb.append( "urls[" + i + "] = " + pluginRealm.getConstituents()[i] );
                    if ( i != ( pluginRealm.getConstituents().length - 1 ) )
                    {
                        sb.append( '\n' );
                    }
                }
                getLogger().fatalError( sb.toString() );

                ClassRealm containerRealm = container.getContainerRealm();
                sb = new StringBuffer();
                sb.append( "Container realm = " + containerRealm.getId() ).append( '\n' );
                for ( int i = 0; i < containerRealm.getConstituents().length; i++ )
                {
                    sb.append( "urls[" + i + "] = " + containerRealm.getConstituents()[i] );
                    if ( i != ( containerRealm.getConstituents().length - 1 ) )
                    {
                        sb.append( '\n' );
                    }
                }
                getLogger().fatalError( sb.toString() );
            }

            session.getEventDispatcher().dispatchError( event, goalExecId, e );

            throw e;
        }
        finally
        {

            Thread.currentThread().setContextClassLoader( oldClassLoader );

            try
            {
                PlexusContainer pluginContainer = getPluginContainer( mojoDescriptor.getPluginDescriptor() );

                pluginContainer.release( plugin );
            }
            catch ( ComponentLifecycleException e )
            {
                if ( getLogger().isErrorEnabled() )
                {
                    getLogger().error( "Error releasing plugin - ignoring.", e );
                }
            }
        }
    }


    public MavenReport getReport( MavenProject project,
                                  MojoExecution mojoExecution,
                                  MavenSession session )
        throws ArtifactNotFoundException, PluginConfigurationException, PluginManagerException,
        ArtifactResolutionException
    {
        MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
        PluginDescriptor descriptor = mojoDescriptor.getPluginDescriptor();

        Xpp3Dom dom = project.getReportConfiguration( descriptor.getGroupId(), descriptor.getArtifactId(),
                                                      mojoExecution.getExecutionId() );
        if ( mojoExecution.getConfiguration() != null )
        {
            dom = Xpp3Dom.mergeXpp3Dom( dom, mojoExecution.getConfiguration() );
        }

        MavenReport report = (MavenReport) getConfiguredMojo( session, dom, project, true, mojoExecution );
        
        return report;
    }

    public PluginDescriptor verifyReportPlugin( ReportPlugin reportPlugin,
                                                MavenProject project,
                                                MavenSession session )
        throws PluginVersionResolutionException, ArtifactResolutionException, ArtifactNotFoundException,
        InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException,
        PluginVersionNotFoundException
    {
        String version = reportPlugin.getVersion();

        if ( version == null )
        {
            version = pluginVersionManager.resolveReportPluginVersion( reportPlugin.getGroupId(),
                                                                       reportPlugin.getArtifactId(), project,
                                                                       session.getSettings(),
                                                                       session.getLocalRepository() );
            reportPlugin.setVersion( version );
        }

        Plugin forLookup = new Plugin();

        forLookup.setGroupId( reportPlugin.getGroupId() );
        forLookup.setArtifactId( reportPlugin.getArtifactId() );
        forLookup.setVersion( version );

        return verifyVersionedPlugin( forLookup, project, session.getLocalRepository() );
    }

    private PlexusContainer getPluginContainer( PluginDescriptor pluginDescriptor )
        throws PluginManagerException
    {
        String pluginKey = PluginUtils.constructVersionedKey( pluginDescriptor );

        PlexusContainer pluginContainer = container.getChildContainer( pluginKey );

        if ( pluginContainer == null )
        {
            throw new PluginManagerException( "Cannot find Plexus container for plugin: " + pluginKey );
        }

        return pluginContainer;
    }

    private Mojo getConfiguredMojo( MavenSession session,
                                    Xpp3Dom dom,
                                    MavenProject project,
                                    boolean report,
                                    MojoExecution mojoExecution )
        throws PluginConfigurationException, ArtifactNotFoundException, PluginManagerException,
        ArtifactResolutionException
    {
        MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();

        PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();

        PlexusContainer pluginContainer = getPluginContainer( pluginDescriptor );

        // if this is the first time this plugin has been used, the plugin's container will only
        // contain the plugin's artifact in isolation; we need to finish resolving the plugin's
        // dependencies, and add them to the container.
        ensurePluginContainerIsComplete( pluginDescriptor, pluginContainer, project, session );

        Mojo plugin;
        try
        {
            plugin = (Mojo) pluginContainer.lookup( Mojo.ROLE, mojoDescriptor.getRoleHint() );
            if ( report && !( plugin instanceof MavenReport ) )
            {
                // TODO: the mojoDescriptor should actually capture this information so we don't get this far
                return null;
            }
        }
        catch ( ComponentLookupException e )
        {
            Throwable cause = e.getCause();
            while( cause != null && !(cause instanceof NoClassDefFoundError ) )
            {
                cause = cause.getCause();
            }
            
            if ( cause != null && ( cause instanceof NoClassDefFoundError ) )
            {
                throw new PluginManagerException( "Unable to load the mojo '" + mojoDescriptor.getRoleHint()
                                                  + "' in the plugin '" + pluginDescriptor.getPluginLookupKey() + "'. A required class is missing: "
                                                  + cause.getMessage(), e );
            }
            
            throw new PluginManagerException( "Unable to find the mojo '" + mojoDescriptor.getGoal() +
                "' (or one of its required components) in the plugin '" + pluginDescriptor.getPluginLookupKey() + "'", e );
        }
        catch ( NoClassDefFoundError e )
        {
            throw new PluginManagerException( "Unable to load the mojo '" + mojoDescriptor.getRoleHint()
                + "' in the plugin '" + pluginDescriptor.getPluginLookupKey() + "'. A required class is missing: "
                + e.getMessage(), e );
        }

        if ( plugin instanceof ContextEnabled )
        {
            Map pluginContext = session.getPluginContext( pluginDescriptor, project );

            ( (ContextEnabled) plugin ).setPluginContext( pluginContext );
        }

        plugin.setLog( mojoLogger );

        XmlPlexusConfiguration pomConfiguration;
        if ( dom == null )
        {
            pomConfiguration = new XmlPlexusConfiguration( "configuration" );
        }
        else
        {
            pomConfiguration = new XmlPlexusConfiguration( dom );
        }

        // Validate against non-editable (@readonly) parameters, to make sure users aren't trying to
        // override in the POM.
        validatePomConfiguration( mojoDescriptor, pomConfiguration );

        PlexusConfiguration mergedConfiguration = mergeMojoConfiguration( pomConfiguration, mojoDescriptor );

        // TODO: plexus changes to make this more like the component descriptor so this can be used instead
        //            PlexusConfiguration mergedConfiguration = mergeConfiguration( pomConfiguration,
        //                                                                          mojoDescriptor.getConfiguration() );

        ExpressionEvaluator expressionEvaluator = new PluginParameterExpressionEvaluator( session, mojoExecution,
                                                                                          pathTranslator,
                                                                                          getLogger(),
                                                                                          project,
                                                                                          session.getExecutionProperties() );

        PlexusConfiguration extractedMojoConfiguration =
            extractMojoConfiguration( mergedConfiguration, mojoDescriptor );

        checkRequiredParameters( mojoDescriptor, extractedMojoConfiguration, expressionEvaluator );

        populatePluginFields( plugin, mojoDescriptor, extractedMojoConfiguration, pluginContainer,
                              expressionEvaluator );
        return plugin;
    }

    private void ensurePluginContainerIsComplete( PluginDescriptor pluginDescriptor,
                                                  PlexusContainer pluginContainer,
                                                  MavenProject project,
                                                  MavenSession session )
        throws ArtifactNotFoundException, PluginManagerException, ArtifactResolutionException
    {
        // if the plugin's already been used once, don't re-do this step...
        // otherwise, we have to finish resolving the plugin's classpath and start the container.
        if ( ( pluginDescriptor.getArtifacts() != null ) && ( pluginDescriptor.getArtifacts().size() == 1 ) )
        {
            Artifact pluginArtifact = (Artifact) pluginDescriptor.getArtifacts().get( 0 );

            ArtifactRepository localRepository = session.getLocalRepository();

            ArtifactMetadataSource metadataSource = session.getProjectBuilderConfiguration().getMetadataSource();
            if ( metadataSource == null )
            {
                 metadataSource = artifactMetadataSource;
            }
            
            ResolutionGroup resolutionGroup;
            try
            {
                resolutionGroup = metadataSource.retrieve( pluginArtifact, localRepository,
                                                                   project.getPluginArtifactRepositories() );
            }
            catch ( ArtifactMetadataRetrievalException e )
            {
                throw new ArtifactResolutionException( "Unable to download metadata from repository for plugin '" +
                    pluginArtifact.getId() + "': " + e.getMessage(), pluginArtifact, e );
            }

            Set rgArtifacts = resolutionGroup.getArtifacts();

            rgArtifacts = checkPlexusUtils( rgArtifacts, artifactFactory );

            // [jdcasey; 20-March-2008]:
            // This is meant to eliminate the introduction of duplicated artifacts.
            // Since much of the reasoning for reversing the order of introduction of
            // plugin dependencies rests on the notion that we need to be able to
            // introduce upgraded versions of plugin dependencies on a case-by-case
            // basis, we need to remove the original version prior to artifact
            // resolution. This is consistent with recent thinking on duplicated
            // dependency specifications within a POM, where that case should
            // throw a model validation exception.
            //
            // Here, we just want to remove any chance that the ArtifactCollector
            // could make a bad choice, and use the old version in spite of our
            // explicit preference otherwise.

            // First, we're going to accumulate plugin dependencies in an ordered map,
            // keyed by dependencyConflictId (the ordered map is meant to preserve relative
            // ordering of the dependencies that do make the cut).
            Map dependencyMap = new LinkedHashMap();

            // Next, we need to accumulate all dependencies in a List, to make it
            // simpler to iterate through them all and add them to the map.
            List all = new ArrayList();

            // plugin-level dependencies from the consuming POM override dependencies
            // from the plugin's own POM.
            all.addAll( pluginDescriptor.getIntroducedDependencyArtifacts() );

            // add in the deps from the plugin POM now.
            all.addAll( rgArtifacts );

            for ( Iterator it = all.iterator(); it.hasNext(); )
            {
                Artifact artifact = (Artifact) it.next();
                String conflictId = artifact.getDependencyConflictId();

                // if the map already contains this dependencyConflictId, it constitutes an
                // overridden dependency. Don't use the old one (we know it's old from the
                // order in which dependencies were added to this list).
                if ( !dependencyMap.containsKey( conflictId ) )
                {
                    dependencyMap.put( conflictId, artifact );
                }
            }

            // Create an ordered set of dependencies from the ordered map we used above, to feed into the resolver.
            Set dependencies = new LinkedHashSet( dependencyMap.values() );

            if ( getLogger().isDebugEnabled() )
            {
                // list all dependencies to be used by this plugin (first-level deps, not transitive ones).
                getLogger().debug( "Plugin dependencies for:\n\n" + pluginDescriptor.getId()
                                   + "\n\nare:\n\n"
                                   + StringUtils.join( dependencies.iterator(), "\n" ) + "\n\n" );
            }

            List repositories = new ArrayList();
            repositories.addAll( resolutionGroup.getResolutionRepositories() );
            repositories.addAll( project.getRemoteArtifactRepositories() );

            /* get plugin managed versions */
            Map pluginManagedDependencies = new HashMap();
            try
            {
                MavenProject pluginProject =
                    mavenProjectBuilder.buildFromRepository( pluginArtifact, project.getRemoteArtifactRepositories(),
                                                             localRepository );
                if ( pluginProject != null )
                {
                    pluginManagedDependencies = pluginProject.getManagedVersionMap();
                }
            }
            catch ( ProjectBuildingException e )
            {
                // this can't happen, it would have blowed up at artifactMetadataSource.retrieve()
            }

            ArtifactResolutionResult result = artifactResolver.resolveTransitively( dependencies, pluginArtifact,
                                                                                    pluginManagedDependencies,
                                                                                    localRepository, repositories,
                                                                                    metadataSource,
                                                                                    artifactFilter );

            Set resolved = result.getArtifacts();

            for ( Iterator it = resolved.iterator(); it.hasNext(); )
            {
                Artifact artifact = (Artifact) it.next();

                if ( !artifact.equals( pluginArtifact ) )
                {
                    artifact = project.replaceWithActiveArtifact( artifact );

                    try
                    {
                        pluginContainer.addJarResource( artifact.getFile() );
                    }
                    catch ( PlexusContainerException e )
                    {
                        throw new PluginManagerException( "Error adding plugin dependency '" +
                            artifact.getDependencyConflictId() + "' into plugin manager: " + e.getMessage(), e );
                    }
                }
            }

            pluginDescriptor.setClassRealm( pluginContainer.getContainerRealm() );

            List unresolved = new ArrayList( dependencies );

            unresolved.removeAll( resolved );

            if ( getLogger().isDebugEnabled() )
            {
                // list all artifacts that were filtered out during the resolution process.
                // these are already present in the core container.
                getLogger().debug( " The following artifacts were filtered out for plugin: "
                                   + pluginDescriptor.getId()
                                   + " because they're already in the core of Maven:\n\n"
                                   + StringUtils.join( unresolved.iterator(), "\n" )
                                   + "\n\nThese will use the artifact files already in the core ClassRealm instead, to allow them to be included in PluginDescriptor.getArtifacts().\n\n" );
            }

            // Grab a file for all filtered artifacts, even if it means resolving them. This
            // is necessary in order to present a full complement of a plugin's transitive
            // dependencies to anyone who calls PluginDescriptor.getArtifacts().
            resolveCoreArtifacts( unresolved, localRepository, resolutionGroup.getResolutionRepositories() );

            // Re-join resolved and filtered-but-now-resolved artifacts.
            // NOTE: The process of filtering then re-adding some artifacts will
            // result in different ordering within the PluginDescriptor.getArtifacts()
            // List than should have happened if none had been filtered. All filtered
            // artifacts will be listed last...
            List allResolved = new ArrayList( resolved.size() + unresolved.size() );

            allResolved.addAll( resolved );
            allResolved.addAll( unresolved );

            pluginDescriptor.setArtifacts( allResolved );
        }
    }

    public static Set checkPlexusUtils( Set dependencyArtifacts, ArtifactFactory artifactFactory )
    {
        // ----------------------------------------------------------------------------
        // If the plugin already declares a dependency on plexus-utils then we're all
        // set as the plugin author is aware of its use. If we don't have a dependency
        // on plexus-utils then we must protect users from stupid plugin authors who
        // did not declare a direct dependency on plexus-utils because the version
        // Maven uses is hidden from downstream use. We will also bump up any
        // anything below 1.1 to 1.1 as this mimics the behaviour in 2.0.5 where
        // plexus-utils 1.1 was being forced into use.
        // ----------------------------------------------------------------------------

        VersionRange vr = null;

        try
        {
            vr = VersionRange.createFromVersionSpec( "[1.1,)" );
        }
        catch ( InvalidVersionSpecificationException e )
        {
            // Won't happen
        }

        boolean plexusUtilsPresent = false;

        for ( Iterator i = dependencyArtifacts.iterator(); i.hasNext(); )
        {
            Artifact a = (Artifact) i.next();

            if ( a.getArtifactId().equals( "plexus-utils" ) &&
                vr.containsVersion( new DefaultArtifactVersion( a.getVersion() ) ) )
            {
                plexusUtilsPresent = true;

                break;
            }
        }

        if ( !plexusUtilsPresent )
        {
            // We will add plexus-utils as every plugin was getting this anyway from Maven itself. We will set the
            // version to the latest version we know that works as of the 2.0.6 release. We set the scope to runtime
            // as this is what's implicitly happening in 2.0.6.

            Set result = new LinkedHashSet();
            if ( !dependencyArtifacts.isEmpty() )
            {
                result.addAll( dependencyArtifacts );
            }

            result.add( artifactFactory.createArtifact( "org.codehaus.plexus", "plexus-utils", "1.1", Artifact.SCOPE_RUNTIME, "jar" ) );

            return result;
        }
        else
        {
            return dependencyArtifacts;
        }
    }

    private void resolveCoreArtifacts( List unresolved,
                                       ArtifactRepository localRepository,
                                       List resolutionRepositories )
        throws ArtifactResolutionException, ArtifactNotFoundException
    {
        for ( Iterator it = unresolved.iterator(); it.hasNext(); )
        {
            Artifact artifact = (Artifact) it.next();

            File artifactFile = (File) resolvedCoreArtifactFiles.get( artifact.getId() );

            if ( artifactFile == null )
            {
                String resource =
                    "/META-INF/maven/" + artifact.getGroupId() + "/" + artifact.getArtifactId() + "/pom.xml";

                URL resourceUrl = container.getContainerRealm().getResource( resource );

                if ( resourceUrl == null )
                {
                    artifactResolver.resolve( artifact, resolutionRepositories, localRepository );

                    artifactFile = artifact.getFile();
                }
                else
                {
                    String artifactPath = resourceUrl.getPath();

                    if ( artifactPath.startsWith( "file:" ) )
                    {
                        artifactPath = artifactPath.substring( "file:".length() );
                    }

                    artifactPath = artifactPath.substring( 0, artifactPath.length() - resource.length() );

                    if ( artifactPath.endsWith( "/" ) )
                    {
                        artifactPath = artifactPath.substring( 0, artifactPath.length() - 1 );
                    }

                    if ( artifactPath.endsWith( "!" ) )
                    {
                        artifactPath = artifactPath.substring( 0, artifactPath.length() - 1 );
                    }

                    artifactFile = new File( artifactPath ).getAbsoluteFile();
                }

                resolvedCoreArtifactFiles.put( artifact.getId(), artifactFile );
            }

            artifact.setFile( artifactFile );
        }
    }

    private PlexusConfiguration extractMojoConfiguration( PlexusConfiguration mergedConfiguration,
                                                          MojoDescriptor mojoDescriptor )
    {
        Map parameterMap = mojoDescriptor.getParameterMap();

        PlexusConfiguration[] mergedChildren = mergedConfiguration.getChildren();

        XmlPlexusConfiguration extractedConfiguration = new XmlPlexusConfiguration( "configuration" );

        for ( int i = 0; i < mergedChildren.length; i++ )
        {
            PlexusConfiguration child = mergedChildren[i];

            if ( parameterMap.containsKey( child.getName() ) )
            {
                extractedConfiguration.addChild( copyConfiguration( child ) );
            }
            else
            {
                // TODO: I defy anyone to find these messages in the '-X' output! Do we need a new log level?
                // ideally, this would be elevated above the true debug output, but below the default INFO level...
                // [BP] (2004-07-18): need to understand the context more but would prefer this could be either WARN or
                // removed - shouldn't need DEBUG to diagnose a problem most of the time.
                getLogger().debug( "*** WARNING: Configuration \'" + child.getName() + "\' is not used in goal \'" +
                    mojoDescriptor.getFullGoalName() + "; this may indicate a typo... ***" );
            }
        }

        return extractedConfiguration;
    }

    private void checkRequiredParameters( MojoDescriptor goal,
                                          PlexusConfiguration configuration,
                                          ExpressionEvaluator expressionEvaluator )
        throws PluginConfigurationException
    {
        // TODO: this should be built in to the configurator, as we presently double process the expressions

        List parameters = goal.getParameters();

        if ( parameters == null )
        {
            return;
        }

        List invalidParameters = new ArrayList();

        for ( int i = 0; i < parameters.size(); i++ )
        {
            Parameter parameter = (Parameter) parameters.get( i );

            if ( parameter.isRequired() )
            {
                // the key for the configuration map we're building.
                String key = parameter.getName();

                Object fieldValue = null;
                String expression = null;
                PlexusConfiguration value = configuration.getChild( key, false );
                try
                {
                    if ( value != null )
                    {
                        expression = value.getValue( null );

                        fieldValue = expressionEvaluator.evaluate( expression );

                        if ( fieldValue == null )
                        {
                            fieldValue = value.getAttribute( "default-value", null );
                        }
                    }

                    if ( ( fieldValue == null ) && StringUtils.isNotEmpty( parameter.getAlias() ) )
                    {
                        value = configuration.getChild( parameter.getAlias(), false );
                        if ( value != null )
                        {
                            expression = value.getValue( null );
                            fieldValue = expressionEvaluator.evaluate( expression );
                            if ( fieldValue == null )
                            {
                                fieldValue = value.getAttribute( "default-value", null );
                            }
                        }
                    }
                }
                catch ( ExpressionEvaluationException e )
                {
                    throw new PluginConfigurationException( goal.getPluginDescriptor(), e.getMessage(), e );
                }

                // only mark as invalid if there are no child nodes
                if ( ( fieldValue == null ) && ( ( value == null ) || ( value.getChildCount() == 0 ) ) )
                {
                    parameter.setExpression( expression );
                    invalidParameters.add( parameter );
                }
            }
        }

        if ( !invalidParameters.isEmpty() )
        {
            throw new PluginParameterException( goal, invalidParameters );
        }
    }

    private void validatePomConfiguration( MojoDescriptor goal,
                                           PlexusConfiguration pomConfiguration )
        throws PluginConfigurationException
    {
        List parameters = goal.getParameters();

        if ( parameters == null )
        {
            return;
        }

        for ( int i = 0; i < parameters.size(); i++ )
        {
            Parameter parameter = (Parameter) parameters.get( i );

            // the key for the configuration map we're building.
            String key = parameter.getName();

            PlexusConfiguration value = pomConfiguration.getChild( key, false );

            if ( ( value == null ) && StringUtils.isNotEmpty( parameter.getAlias() ) )
            {
                key = parameter.getAlias();
                value = pomConfiguration.getChild( key, false );
            }

            if ( value != null )
            {
                // Make sure the parameter is either editable/configurable, or else is NOT specified in the POM
                if ( !parameter.isEditable() )
                {
                    StringBuffer errorMessage = new StringBuffer()
                        .append( "ERROR: Cannot override read-only parameter: " );
                    errorMessage.append( key );
                    errorMessage.append( " in goal: " ).append( goal.getFullGoalName() );

                    throw new PluginConfigurationException( goal.getPluginDescriptor(), errorMessage.toString() );
                }

                String deprecated = parameter.getDeprecated();
                if ( StringUtils.isNotEmpty( deprecated ) )
                {
                    getLogger().warn( "DEPRECATED [" + parameter.getName() + "]: " + deprecated );
                }
            }
        }
    }

    private PlexusConfiguration mergeMojoConfiguration( XmlPlexusConfiguration fromPom,
                                                        MojoDescriptor mojoDescriptor )
    {
        XmlPlexusConfiguration result = new XmlPlexusConfiguration( fromPom.getName() );
        result.setValue( fromPom.getValue( null ) );

        if ( mojoDescriptor.getParameters() != null )
        {
            PlexusConfiguration fromMojo = mojoDescriptor.getMojoConfiguration();

            for ( Iterator it = mojoDescriptor.getParameters().iterator(); it.hasNext(); )
            {
                Parameter parameter = (Parameter) it.next();

                String paramName = parameter.getName();
                String alias = parameter.getAlias();
                String implementation = parameter.getImplementation();

                PlexusConfiguration pomConfig = fromPom.getChild( paramName );
                PlexusConfiguration aliased = null;

                if ( alias != null )
                {
                    aliased = fromPom.getChild( alias );
                }

                PlexusConfiguration mojoConfig = fromMojo.getChild( paramName, false );

                // first we'll merge configurations from the aliased and real params.
                // TODO: Is this the right thing to do?
                if ( aliased != null )
                {
                    if ( pomConfig == null )
                    {
                        pomConfig = new XmlPlexusConfiguration( paramName );
                    }

                    pomConfig = buildTopDownMergedConfiguration( pomConfig, aliased );
                }

                PlexusConfiguration toAdd = null;

                if ( pomConfig != null )
                {
                    pomConfig = buildTopDownMergedConfiguration( pomConfig, mojoConfig );

                    if ( StringUtils.isNotEmpty( pomConfig.getValue( null ) ) || ( pomConfig.getChildCount() > 0 ) )
                    {
                        toAdd = pomConfig;
                    }
                }

                if ( ( toAdd == null ) && ( mojoConfig != null ) )
                {
                    toAdd = copyConfiguration( mojoConfig );
                }

                if ( toAdd != null )
                {
                    if ( ( implementation != null ) && ( toAdd.getAttribute( "implementation", null ) == null ) )
                    {

                        XmlPlexusConfiguration implementationConf = new XmlPlexusConfiguration( paramName );

                        implementationConf.setAttribute( "implementation", parameter.getImplementation() );

                        toAdd = buildTopDownMergedConfiguration( toAdd, implementationConf );
                    }

                    result.addChild( toAdd );
                }
            }
        }
        return result;
    }

    private XmlPlexusConfiguration buildTopDownMergedConfiguration( PlexusConfiguration dominant,
                                                                    PlexusConfiguration recessive )
    {
        XmlPlexusConfiguration result = new XmlPlexusConfiguration( dominant.getName() );

        String value = dominant.getValue( null );

        if ( StringUtils.isEmpty( value ) && ( recessive != null ) )
        {
            value = recessive.getValue( null );
        }

        if ( StringUtils.isNotEmpty( value ) )
        {
            result.setValue( value );
        }

        String[] attributeNames = dominant.getAttributeNames();

        for ( int i = 0; i < attributeNames.length; i++ )
        {
            String attributeValue = dominant.getAttribute( attributeNames[i], null );

            result.setAttribute( attributeNames[i], attributeValue );
        }

        if ( recessive != null )
        {
            attributeNames = recessive.getAttributeNames();

            for ( int i = 0; i < attributeNames.length; i++ )
            {
                String attributeValue = recessive.getAttribute( attributeNames[i], null );
                // TODO: recessive seems to be dominant here?
                result.setAttribute( attributeNames[i], attributeValue );
            }
        }

        PlexusConfiguration[] children = dominant.getChildren();

        for ( int i = 0; i < children.length; i++ )
        {
            PlexusConfiguration childDom = children[i];
            PlexusConfiguration childRec = recessive == null ? null : recessive.getChild( childDom.getName(), false );

            if ( childRec != null )
            {
                result.addChild( buildTopDownMergedConfiguration( childDom, childRec ) );
            }
            else
            {   // FIXME: copy, or use reference?
                result.addChild( copyConfiguration( childDom ) );
            }
        }

        return result;
    }

    public static PlexusConfiguration copyConfiguration( PlexusConfiguration src )
    {
        // TODO: shouldn't be necessary
        XmlPlexusConfiguration dom = new XmlPlexusConfiguration( src.getName() );
        dom.setValue( src.getValue( null ) );

        String[] attributeNames = src.getAttributeNames();
        for ( int i = 0; i < attributeNames.length; i++ )
        {
            String attributeName = attributeNames[i];
            dom.setAttribute( attributeName, src.getAttribute( attributeName, null ) );
        }

        PlexusConfiguration[] children = src.getChildren();
        for ( int i = 0; i < children.length; i++ )
        {
            dom.addChild( copyConfiguration( children[i] ) );
        }

        return dom;
    }

    // ----------------------------------------------------------------------
    // Mojo Parameter Handling
    // ----------------------------------------------------------------------

    private void populatePluginFields( Mojo plugin,
                                       MojoDescriptor mojoDescriptor,
                                       PlexusConfiguration configuration,
                                       PlexusContainer pluginContainer,
                                       ExpressionEvaluator expressionEvaluator )
        throws PluginConfigurationException
    {
        ComponentConfigurator configurator = null;

        try
        {
            String configuratorId = mojoDescriptor.getComponentConfigurator();

            // TODO: could the configuration be passed to lookup and the configurator known to plexus via the descriptor
            // so that this meethod could entirely be handled by a plexus lookup?
            if ( StringUtils.isNotEmpty( configuratorId ) )
            {
                configurator =
                    (ComponentConfigurator) pluginContainer.lookup( ComponentConfigurator.ROLE, configuratorId );
            }
            else
            {
                configurator = (ComponentConfigurator) pluginContainer.lookup( ComponentConfigurator.ROLE );
            }

            ConfigurationListener listener = new DebugConfigurationListener( getLogger() );

            getLogger().debug( "Configuring mojo '" + mojoDescriptor.getId() + "' -->" );
            configurator.configureComponent( plugin, configuration, expressionEvaluator,
                                             pluginContainer.getContainerRealm(), listener );
            getLogger().debug( "-- end configuration --" );
        }
        catch ( ComponentConfigurationException e )
        {
            throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(),
                                                    "Unable to parse the created DOM for plugin configuration", e );
        }
        catch ( ComponentLookupException e )
        {
            throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(),
                                                    "Unable to retrieve component configurator for plugin configuration",
                                                    e );
        }
        catch ( NoClassDefFoundError e )
        {
            throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(),
                                                    "A required class was missing during mojo configuration: " + e.getMessage(), e );
        }
        catch ( LinkageError e )
        {
            if ( getLogger().isFatalErrorEnabled() )
            {
                getLogger().fatalError(
                                        configurator.getClass().getName() + "#configureComponent(...) caused a linkage error ("
                                            + e.getClass().getName() + ") and may be out-of-date. Check the realms:" );

                ClassRealm pluginRealm = mojoDescriptor.getPluginDescriptor().getClassRealm();
                StringBuffer sb = new StringBuffer();
                sb.append( "Plugin realm = " + pluginRealm.getId() ).append( '\n' );
                for ( int i = 0; i < pluginRealm.getConstituents().length; i++ )
                {
                    sb.append( "urls[" + i + "] = " + pluginRealm.getConstituents()[i] );
                    if ( i != ( pluginRealm.getConstituents().length - 1 ) )
                    {
                        sb.append( '\n' );
                    }
                }
                getLogger().fatalError( sb.toString() );

                ClassRealm containerRealm = container.getContainerRealm();
                sb = new StringBuffer();
                sb.append( "Container realm = " + containerRealm.getId() ).append( '\n' );
                for ( int i = 0; i < containerRealm.getConstituents().length; i++ )
                {
                    sb.append( "urls[" + i + "] = " + containerRealm.getConstituents()[i] );
                    if ( i != ( containerRealm.getConstituents().length - 1 ) )
                    {
                        sb.append( '\n' );
                    }
                }
                getLogger().fatalError( sb.toString() );
            }

            throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(),
                                                    e.getClass().getName() + ": " + e.getMessage(), e );
        }
        finally
        {
            if ( configurator != null )
            {
                try
                {
                    pluginContainer.release( configurator );
                }
                catch ( ComponentLifecycleException e )
                {
                    getLogger().debug( "Failed to release plugin container - ignoring." );
                }
            }
        }
    }

    public static String createPluginParameterRequiredMessage( MojoDescriptor mojo,
                                                               Parameter parameter,
                                                               String expression )
    {
        StringBuffer message = new StringBuffer();

        message.append( "The '" );
        message.append( parameter.getName() );
        message.append( "' parameter is required for the execution of the " );
        message.append( mojo.getFullGoalName() );
        message.append( " mojo and cannot be null." );
        if ( expression != null )
        {
            message.append( " The retrieval expression was: " ).append( expression );
        }

        return message.toString();
    }

    // ----------------------------------------------------------------------
    // Lifecycle
    // ----------------------------------------------------------------------

    public void contextualize( Context context )
        throws ContextException
    {
        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );

        mojoLogger = new DefaultLog( container.getLoggerManager().getLoggerForComponent( Mojo.ROLE ) );
    }

    public void initialize()
    {
        artifactFilter = MavenArtifactFilterManager.createStandardFilter();
    }

    // ----------------------------------------------------------------------
    // Artifact resolution
    // ----------------------------------------------------------------------

    private void resolveTransitiveDependencies( MavenSession context,
                                                ArtifactResolver artifactResolver,
                                                String scope,
                                                ArtifactFactory artifactFactory,
                                                MavenProject project, boolean isAggregator )
        throws ArtifactResolutionException, ArtifactNotFoundException, InvalidDependencyVersionException
    {
        ArtifactFilter filter = new ScopeArtifactFilter( scope );

        // TODO: such a call in MavenMetadataSource too - packaging not really the intention of type
        Artifact artifact = artifactFactory.createBuildArtifact( project.getGroupId(), project.getArtifactId(),
                                                                 project.getVersion(), project.getPackaging() );

        // TODO: we don't need to resolve over and over again, as long as we are sure that the parameters are the same
        // check this with yourkit as a hot spot.
        // Don't recreate if already created - for effeciency, and because clover plugin adds to it
        if ( project.getDependencyArtifacts() == null )
        {
            project.setDependencyArtifacts( project.createArtifacts( artifactFactory, null, null ) );
        }
        else
        {
            project.resolveActiveArtifacts();
        }

        Set resolvedArtifacts;
        try
        {
            ArtifactResolutionResult result = artifactResolver.resolveTransitively( project.getDependencyArtifacts(),
                                                                                artifact,
                                                                                project.getManagedVersionMap(),
                                                                                context.getLocalRepository(),
                                                                                project.getRemoteArtifactRepositories(),
                                                                                artifactMetadataSource, filter );
            resolvedArtifacts = result.getArtifacts();
        }
        catch (MultipleArtifactsNotFoundException me)
        {
            /*only do this if we are an aggregating plugin: MNG-2277
            if the dependency doesn't yet exist but is in the reactor, then
            all we can do is warn and skip it. A better fix can be inserted into 2.1*/
            if (isAggregator && checkMissingArtifactsInReactor( context.getSortedProjects(), me.getMissingArtifacts() ))
            {
                resolvedArtifacts = new HashSet(me.getResolvedArtifacts());
            }
            else
            {
                //we can't find all the artifacts in the reactor so bubble the exception up.
                throw me;
            }
        }
        project.setArtifacts( resolvedArtifacts );
    }

    /**
     * This method is checking to see if the artifacts that can't be resolved are all
     * part of this reactor. This is done to prevent a chicken or egg scenario with
     * fresh projects that have a plugin that is an aggregator and requires dependencies. See
     * MNG-2277 for more info.
     * @param projects the sibling projects in the reactor
     * @param missing the artifacts that can't be found
     * @return true if ALL missing artifacts are found in the reactor.
     */
    private boolean checkMissingArtifactsInReactor(Collection projects, Collection missing)
    {
        Collection foundInReactor = new HashSet();
        Iterator iter = missing.iterator();
        while (iter.hasNext())
        {
            Artifact mArtifact = (Artifact) iter.next();
            Iterator pIter = projects.iterator();
            while (pIter.hasNext())
            {
                MavenProject p = (MavenProject) pIter.next();
                if (p.getArtifactId().equals( mArtifact.getArtifactId()) &&
                    p.getGroupId().equals( mArtifact.getGroupId()) &&
                    p.getVersion().equals( mArtifact.getVersion()))
                {
                    //TODO: the packaging could be different, but the exception doesn't contain that info
                    //most likely it would be produced by the project we just found in the reactor since all
                    //the other info matches. Assume it's ok.
                    getLogger().warn( "The dependency: "+ p.getId()+" can't be resolved but has been found in the reactor.\nThis dependency has been excluded from the plugin execution. You should rerun this mojo after executing mvn install.\n" );

                    //found it, move on.
                    foundInReactor.add( p );
                    break;
                }
            }
        }

        //if all of them have been found, we can continue.
        return foundInReactor.size() == missing.size();
    }


    // ----------------------------------------------------------------------
    // Artifact downloading
    // ----------------------------------------------------------------------

    private void downloadDependencies( MavenProject project,
                                       MavenSession context,
                                       ArtifactResolver artifactResolver )
        throws ArtifactResolutionException, ArtifactNotFoundException
    {
        ArtifactRepository localRepository = context.getLocalRepository();
        List remoteArtifactRepositories = project.getRemoteArtifactRepositories();

        for ( Iterator it = project.getArtifacts().iterator(); it.hasNext(); )
        {
            Artifact artifact = (Artifact) it.next();

            artifactResolver.resolve( artifact, remoteArtifactRepositories, localRepository );
        }
    }

    public Object getPluginComponent( Plugin plugin,
                                      String role,
                                      String roleHint )
        throws PluginManagerException, ComponentLookupException
    {
        PluginDescriptor pluginDescriptor = pluginCollector.getPluginDescriptor( plugin );

        PlexusContainer pluginContainer = getPluginContainer( pluginDescriptor );
        
        return pluginContainer.lookup( role, roleHint );
    }

    @SuppressWarnings( "unchecked" )
    public Map getPluginComponents( Plugin plugin,
                                    String role )
        throws ComponentLookupException, PluginManagerException
    {
        PluginDescriptor pluginDescriptor = pluginCollector.getPluginDescriptor( plugin );

        PlexusContainer pluginContainer = getPluginContainer( pluginDescriptor );
        
        Set<String> pluginHints = findChildComponentHints( role, container, pluginContainer );
        Map<String, Object> components = new HashMap<String, Object>( pluginHints.size() );
        for ( String hint : pluginHints )
        {
            getLogger().debug( "Looking up plugin component: " + role + " with hint: " + hint );
            components.put( hint, pluginContainer.lookup( role, hint ) );
        }

        return components;
    }
    
    /**
     * {@inheritDoc}
     */
    public PluginDescriptor loadPluginFully( Plugin plugin, MavenProject project, MavenSession session )
        throws ArtifactResolutionException, PluginVersionResolutionException, ArtifactNotFoundException,
        InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException,
        PluginVersionNotFoundException
    {
        PluginDescriptor pd = verifyPlugin( plugin, project, session.getSettings(), session.getLocalRepository() );
        
        PlexusContainer pluginContainer = getPluginContainer( pd );
        ensurePluginContainerIsComplete( pd, pluginContainer, project, session );
        
        return pd;
    }

    /**
     * {@inheritDoc}
     */
    public PluginDescriptor loadPluginDescriptor( Plugin plugin, MavenProject project, MavenSession session )
        throws ArtifactResolutionException, PluginVersionResolutionException, ArtifactNotFoundException,
        InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException,
        PluginVersionNotFoundException
    {
        return verifyPlugin( plugin, project, session.getSettings(), session.getLocalRepository() );
    }
}
