<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/VerboseJavaScopeSelector.java<|end_filename|>
package org.apache.maven.shared.dependency.graph.internal.maven30;

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

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictContext;
import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ScopeSelector;
import org.sonatype.aether.RepositoryException;

/**
 * A JavaScopeSelector that keeps track of reduced scopes
 * 
 */
public class VerboseJavaScopeSelector extends ScopeSelector
{
    public static final String REDUCED_SCOPE = "REDUCED_SCOPE";
    
    private final ScopeSelector scopeSelector = new JavaScopeSelector();

    @Override
    public void selectScope( ConflictContext context )
        throws RepositoryException
    {
        scopeSelector.selectScope( context );
        
        context.getItems().stream()
            .flatMap( i -> i.getScopes().stream() )
            .distinct()
            .max( new ScopeComparator() )
            .filter( s -> s != context.getScope() )
            .ifPresent( s -> context.getWinner().getNode().setData( REDUCED_SCOPE, s ) );
    }
    
    static class ScopeComparator implements Comparator<String>
    {
        List<String> orderedScopes = Arrays.asList( "compile", "runtime", "provided", "test" );

        @Override
        public int compare( String lhs, String rhs )
        {
            return orderedScopes.indexOf( rhs ) - orderedScopes.indexOf( lhs );
        }
    }    
}


<|start_filename|>src/it/setup-extension/src/main/java/org/apache/maven/its/deptree/ResolveDependenciesLifecycleParticipant.java<|end_filename|>
package org.apache.maven.its.deptree;

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

import org.apache.maven.AbstractMavenLifecycleParticipant;
import org.apache.maven.MavenExecutionException;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * Resolves all the dependencies in the project immediately after the Project has been read.
 *
 * It needs to resolve dependencies from the reactor because in a multi-module build
 * sibling modules may never have been built yet, so will not exist in any repo.
 *
 * It is crucial that reactor dependencies can be found at this point in the build because
 * this is the only time at which we can modify the classpath. And for modules that produce
 * archives (eg Android AAR) which contain the actual Java Jar dependency, we need to know
 * that they exist so that we can add a placeholder for them onto the classpath,
 * which we can replace with the real classes once they are built.
 */
@Component( role = AbstractMavenLifecycleParticipant.class, hint = "default" )
public final class ResolveDependenciesLifecycleParticipant extends AbstractMavenLifecycleParticipant
{
    @Requirement( hint = "default" )
    private DependencyGraphBuilder dependencyGraphBuilder;

    @Requirement
    private Logger log;

    @Override
    public void afterProjectsRead( MavenSession session ) throws MavenExecutionException
    {
        log.info( "" );
        log.info( "ResolveDependenciesLifecycleParticipant#afterProjectsRead" );

        final List<MavenProject> projects = session.getProjects();
        File basedir = new File( session.getExecutionRootDirectory() );

        for ( MavenProject project : projects )
        {
            ProjectBuildingRequest buildingRequest =
                new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
            
            buildingRequest.setProject( project );
            
            log.info( "building dependency graph for project " + project.getArtifact() );

            File resolved = new File( basedir, "resolved-" + project.getArtifactId() + ".txt" );

            try
            {
                log.info( "building without reactor projects" );
                // resolution without reactor projects, to check that it is not possible at this point
                dependencyGraphBuilder.buildDependencyGraph( buildingRequest, null );
            }
            catch ( DependencyGraphBuilderException e )
            {
                log.info( "unexpected resolution failure: " + e.getMessage() );

                try
                {
                    FileUtils.fileWrite( resolved.getAbsolutePath(), e.getMessage() );
                }
                catch ( IOException ioe )
                {
                    throw new MavenExecutionException( "Could not write " + resolved, ioe );
                }
            }
        }

        log.info( "" );
    }
}
  


<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/traversal/SerializingDependencyNodeVisitor.java<|end_filename|>
package org.apache.maven.shared.dependency.graph.traversal;

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

import java.io.PrintWriter;
import java.io.Writer;
import java.util.List;

import org.apache.maven.shared.dependency.graph.DependencyNode;

/**
 * A dependency node visitor that serializes visited nodes to a writer.
 * 
 * @author <a href="mailto:<EMAIL>"><NAME></a>
 */
public class SerializingDependencyNodeVisitor
    implements DependencyNodeVisitor
{
    // classes ----------------------------------------------------------------

    /**
     * Provides tokens to use when serializing the dependency graph.
     */
    public static class GraphTokens
    {
        private final String nodeIndent;

        private final String lastNodeIndent;

        private final String fillIndent;

        private final String lastFillIndent;

        public GraphTokens( String nodeIndent, String lastNodeIndent, String fillIndent, String lastFillIndent )
        {
            this.nodeIndent = nodeIndent;
            this.lastNodeIndent = lastNodeIndent;
            this.fillIndent = fillIndent;
            this.lastFillIndent = lastFillIndent;
        }

        public String getNodeIndent( boolean last )
        {
            return last ? lastNodeIndent : nodeIndent;
        }

        public String getFillIndent( boolean last )
        {
            return last ? lastFillIndent : fillIndent;
        }
    }

    // constants --------------------------------------------------------------

    /**
     * Whitespace tokens to use when outputing the dependency graph.
     */
    public static final GraphTokens WHITESPACE_TOKENS = new GraphTokens( "   ", "   ", "   ", "   " );

    /**
     * The standard ASCII tokens to use when outputing the dependency graph.
     */
    public static final GraphTokens STANDARD_TOKENS = new GraphTokens( "+- ", "\\- ", "|  ", "   " );

    /**
     * The extended ASCII tokens to use when outputing the dependency graph.
     */
    public static final GraphTokens EXTENDED_TOKENS = new GraphTokens( "\u251C\u2500 ", "\u2514\u2500 ", "\u2502  ",
                                                                       "   " );

    // fields -----------------------------------------------------------------

    /**
     * The writer to serialize to.
     */
    private final PrintWriter writer;

    /**
     * The tokens to use when serializing the dependency graph.
     */
    private final GraphTokens tokens;

    /**
     * The depth of the currently visited dependency node.
     */
    private int depth;

    // constructors -----------------------------------------------------------

    /**
     * Creates a dependency node visitor that serializes visited nodes to the specified writer using whitespace tokens.
     * 
     * @param writer the writer to serialize to
     */
    public SerializingDependencyNodeVisitor( Writer writer )
    {
        this( writer, WHITESPACE_TOKENS );
    }

    /**
     * Creates a dependency node visitor that serializes visited nodes to the specified writer using the specified
     * tokens.
     * 
     * @param writer the writer to serialize to
     * @param tokens the tokens to use when serializing the dependency graph
     */
    public SerializingDependencyNodeVisitor( Writer writer, GraphTokens tokens )
    {
        if ( writer instanceof PrintWriter )
        {
            this.writer = (PrintWriter) writer;
        }
        else
        {
            this.writer = new PrintWriter( writer, true );
        }

        this.tokens = tokens;

        depth = 0;
    }

    // DependencyNodeVisitor methods ------------------------------------------

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit( DependencyNode node )
    {
        indent( node );

        writer.println( node.toNodeString() );

        depth++;

        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean endVisit( DependencyNode node )
    {
        depth--;

        return true;
    }

    // private methods --------------------------------------------------------

    /**
     * Writes the necessary tokens to indent the specified dependency node to this visitor's writer.
     * 
     * @param node the dependency node to indent
     */
    private void indent( DependencyNode node )
    {
        for ( int i = 1; i < depth; i++ )
        {
            writer.write( tokens.getFillIndent( isLast( node, i ) ) );
        }

        if ( depth > 0 )
        {
            writer.write( tokens.getNodeIndent( isLast( node ) ) );
        }
    }

    /**
     * Gets whether the specified dependency node is the last of its siblings.
     * 
     * @param node the dependency node to check
     * @return <code>true</code> if the specified dependency node is the last of its last siblings
     */
    private boolean isLast( DependencyNode node )
    {
        // TODO: remove node argument and calculate from visitor calls only

        DependencyNode parent = node.getParent();

        boolean last;

        if ( parent == null )
        {
            last = true;
        }
        else
        {
            List<DependencyNode> siblings = parent.getChildren();

            last = ( siblings.indexOf( node ) == siblings.size() - 1 );
        }

        return last;
    }

    /**
     * Gets whether the specified dependency node ancestor is the last of its siblings.
     * 
     * @param node the dependency node whose ancestor to check
     * @param ancestorDepth the depth of the ancestor of the specified dependency node to check
     * @return <code>true</code> if the specified dependency node ancestor is the last of its siblings
     */
    private boolean isLast( DependencyNode node, int ancestorDepth )
    {
        // TODO: remove node argument and calculate from visitor calls only

        int distance = depth - ancestorDepth;

        while ( distance-- > 0 )
        {
            node = node.getParent();
        }

        return isLast( node );
    }
}


<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/DependencyNode.java<|end_filename|>
package org.apache.maven.shared.dependency.graph;

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

import java.util.List;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Exclusion;
import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;

/**
 * Represents an artifact node within a Maven project's dependency graph. Notice there is no support for omitted nodes
 * at the moment, only dependencies kept in the resolved dependency list are available.
 *
 * @author <NAME>
 * @since 2.0
 */
public interface DependencyNode
{
    /**
     * @return Artifact for this DependencyNode.
     */
    Artifact getArtifact();

    /**
     * @return children of this DependencyNode.
     */
    List<DependencyNode> getChildren();

    /**
     * Applies the specified dependency node visitor to this dependency node and its children.
     * 
     * @param visitor the dependency node visitor to use
     * @return the visitor result of ending the visit to this node
     * @since 1.1
     */
    boolean accept( DependencyNodeVisitor visitor );

    /**
     * Gets the parent dependency node of this dependency node.
     * 
     * @return the parent dependency node
     */
    DependencyNode getParent();

    /**
     * Gets the version or version range for the dependency before dependency management was applied (if any).
     * 
     * @return The dependency version before dependency management or {@code null} if the version was not managed.
     */
    String getPremanagedVersion();

    /**
     * Gets the scope for the dependency before dependency management was applied (if any).
     * 
     * @return The dependency scope before dependency management or {@code null} if the scope was not managed.
     */
    String getPremanagedScope();

    /**
     * A constraint on versions for a dependency. A constraint can either consist of one or more version ranges or a
     * single version.
     * 
     * @return The constraint on the dependency.
     */
    String getVersionConstraint();

    /**
     * Returns a string representation of this dependency node.
     * 
     * @return the string representation
     */
    String toNodeString();

    /**
     * @return true for an optional dependency.
     */
    Boolean getOptional();
    
    /**
     * 
     * @return the exclusions of the dependency
     */
    List<Exclusion> getExclusions();
}


<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/internal/ArtifactKey.java<|end_filename|>
package org.apache.maven.shared.dependency.graph.internal;

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

import java.util.Objects;

import org.apache.maven.project.MavenProject;

/**
 * Uniquely defines an artifact by groupId, artifactId and version.
 */
final class ArtifactKey
{
    private final String groupId;
    private final String artifactId;
    private final String version;
    private final int hashCode;

    ArtifactKey( String groupId, String artifactId, String version )
    {
        this.groupId = groupId;
        this.artifactId = artifactId;
        this.version = version;
        this.hashCode = Objects.hash( groupId, artifactId, version );
    }

    ArtifactKey( MavenProject project )
    {
        this( project.getGroupId(), project.getArtifactId(), project.getVersion() );
    }

    @Override
    public boolean equals( Object o )
    {
        if ( this == o )
        {
            return true;
        }

        if ( !( o instanceof ArtifactKey ) )
        {
            return false;
        }

        ArtifactKey that = (ArtifactKey) o;

        return artifactId.equals( that.artifactId ) && groupId.equals( that.groupId ) && version.equals( that.version );
    }

    @Override
    public int hashCode()
    {
        return hashCode;
    }
}


<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/filter/AncestorOrSelfDependencyNodeFilter.java<|end_filename|>
package org.apache.maven.shared.dependency.graph.filter;

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

import java.util.Collections;
import java.util.List;

import org.apache.maven.shared.dependency.graph.DependencyNode;

/**
 * A dependency node filter than only accepts nodes that are ancestors of, or equal to, a given list of nodes.
 * 
 * @author <a href="mailto:<EMAIL>"><NAME></a>
 * @version $Id$
 * @since 1.1
 */
public class AncestorOrSelfDependencyNodeFilter
    implements DependencyNodeFilter
{
    // fields -----------------------------------------------------------------

    /**
     * The list of nodes that this filter accepts ancestors-or-self of.
     */
    private final List<DependencyNode> descendantNodes;

    // constructors -----------------------------------------------------------

    public AncestorOrSelfDependencyNodeFilter( DependencyNode descendantNode )
    {
        this( Collections.singletonList( descendantNode ) );
    }

    /**
     * Creates a dependency node filter that only accepts nodes that are ancestors of, or equal to, the specified list
     * of nodes.
     * 
     * @param descendantNodes the list of nodes to accept ancestors-or-self of
     */
    public AncestorOrSelfDependencyNodeFilter( List<DependencyNode> descendantNodes )
    {
        this.descendantNodes = descendantNodes;
    }

    // DependencyNodeFilter methods -------------------------------------------

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean accept( DependencyNode node )
    {
        for ( DependencyNode descendantNode : descendantNodes )
        {
            if ( isAncestorOrSelf( node, descendantNode ) )
            {
                return true;
            }
        }

        return false;
    }

    // private methods --------------------------------------------------------

    /**
     * Gets whether the first dependency node is an ancestor-or-self of the second.
     * 
     * @param ancestorNode the ancestor-or-self dependency node
     * @param descendantNode the dependency node to test
     * @return <code>true</code> if <code>ancestorNode</code> is an ancestor, or equal to, <code>descendantNode</code>
     */
    private boolean isAncestorOrSelf( DependencyNode ancestorNode, DependencyNode descendantNode )
    {
        boolean ancestor = false;

        while ( !ancestor && descendantNode != null )
        {
            ancestor = ancestorNode.equals( descendantNode );

            descendantNode = descendantNode.getParent();
        }

        return ancestor;
    }
}


<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/internal/VerboseDependencyNode.java<|end_filename|>
package org.apache.maven.shared.dependency.graph.internal;

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

import java.util.List;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Exclusion;
import org.apache.maven.shared.dependency.graph.DependencyNode;

class VerboseDependencyNode
    extends DefaultDependencyNode
{

    private final ConflictData data;
    
    VerboseDependencyNode( DependencyNode parent, Artifact artifact, String premanagedVersion,
                                  String premanagedScope, String versionConstraint, Boolean optional,
                                  List<Exclusion> exclusions, ConflictData data )
    {
        super( parent, artifact, premanagedVersion, premanagedScope, versionConstraint, optional, exclusions );

        this.data = data;
    }
    
    @Override
    public String toNodeString()
    {
        StringBuilder buffer = new StringBuilder();

        boolean included = ( data.getWinnerVersion() == null );

        if ( !included )
        {
            buffer.append( '(' );
        }

        buffer.append( getArtifact() );

        ItemAppender appender = new ItemAppender( buffer, included ? " (" : " - ", "; ", included ? ")" : "" );

        if ( getPremanagedVersion() != null )
        {
            appender.append( "version managed from ", getPremanagedVersion() );
        }

        if ( getPremanagedScope() != null )
        {
            appender.append( "scope managed from ", getPremanagedScope() );
        }

        if ( data.getOriginalScope() != null )
        {
            appender.append( "scope updated from ", data.getOriginalScope() );
        }

        if ( data.getIgnoredScope() != null )
        {
            appender.append( "scope not updated to ", data.getIgnoredScope() );
        }

//        if ( getVersionSelectedFromRange() != null )
//        {
//            appender.append( "version selected from range ", getVersionSelectedFromRange().toString() );
//            appender.append( "available versions ", getAvailableVersions().toString() );
//        }

        if ( !included )
        {
            String winnerVersion = data.getWinnerVersion(); 
            if ( winnerVersion.equals( getArtifact().getVersion() ) )
            {
              appender.append( "omitted for duplicate" );
            }
            else
            {
              appender.append( "omitted for conflict with ", winnerVersion );
            }
        }

        appender.flush();

        if ( !included )
        {
            buffer.append( ')' );
        }

        return buffer.toString();
    }

    /**
     * Utility class to concatenate a number of parameters with separator tokens.
     */
    private static class ItemAppender
    {
        private StringBuilder buffer;

        private String startToken;

        private String separatorToken;

        private String endToken;

        private boolean appended;

        ItemAppender( StringBuilder buffer, String startToken, String separatorToken, String endToken )
        {
            this.buffer = buffer;
            this.startToken = startToken;
            this.separatorToken = separatorToken;
            this.endToken = endToken;

            appended = false;
        }

        public ItemAppender append( String item1 )
        {
            appendToken();

            buffer.append( item1 );

            return this;
        }

        public ItemAppender append( String item1, String item2 )
        {
            appendToken();

            buffer.append( item1 ).append( item2 );

            return this;
        }

        public void flush()
        {
            if ( appended )
            {
                buffer.append( endToken );

                appended = false;
            }
        }

        private void appendToken()
        {
            buffer.append( appended ? separatorToken : startToken );

            appended = true;
        }
    }
}


<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/internal/Invoker.java<|end_filename|>
package org.apache.maven.shared.dependency.graph.internal;

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

import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;

/**
 * Invokes method on objects using reflection.
 */
final class Invoker
{
    private Invoker()
    {
        // do not instantiate
    }

    static <T extends Exception> Object invoke( Object object, String method, ExceptionHandler<T> exceptionHandler )
        throws T
    {
        return invoke( object.getClass(), object, method, exceptionHandler );
    }

    static <T extends Exception> Object invoke( Class<?> objectClazz, Object object, String method,
                                                ExceptionHandler<T> exceptionHandler )
        throws T
    {
        try
        {
            return objectClazz.getMethod( method ).invoke( object );
        }
        catch ( ReflectiveOperationException e )
        {
            throw exceptionHandler.create( e.getMessage(), e );
        }
    }

    static Object invoke( Object object, String method, Class<?> clazz, Object arg )
        throws DependencyGraphBuilderException
    {
        try
        {
            final Class<?> objectClazz = object.getClass();
            return objectClazz.getMethod( method, clazz ).invoke( object, arg );
        }
        catch ( ReflectiveOperationException e )
        {
            throw new DependencyGraphBuilderException( e.getMessage(), e );
        }
    }
    
    static <T extends Exception> Object invoke( Class<?> objectClazz, String staticMethod,
                                                               Class<?> argClazz, Object arg,
                                                               ExceptionHandler<T> exceptionHandler )
        throws T
    {
        try
        {
            return objectClazz.getMethod( staticMethod, argClazz ).invoke( null, arg );
        }
        catch ( ReflectiveOperationException e )
        {
            throw exceptionHandler.create( e.getMessage(), e );
        }
    }

    static <T extends Exception> Object invoke( Class<?> objectClazz, String staticMethod, Class<?> argClazz1,
                                                Class<?> argClazz2, Object arg1, Object arg2,
                                                ExceptionHandler<T> exceptionHandler )
        throws T
    {
        try
        {
            return objectClazz.getMethod( staticMethod, argClazz1, argClazz2 ).invoke( null, arg1, arg2 );
        }
        catch ( ReflectiveOperationException e )
        {
            throw exceptionHandler.create( e.getMessage(), e );
        }
    }
}


<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/internal/ConflictData.java<|end_filename|>
package org.apache.maven.shared.dependency.graph.internal;

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

/**
 * Excplicit subset of Aethers DependencyNode.getData()
 * 
 * @author <NAME>
 *
 */
public class ConflictData
{
    private String winnerVersion;

    private String originalScope;
    
    private String ignoredScope;
    
    private Boolean originaOptionality;
    
    public ConflictData( String winnerVersion, String ignoredScope )
    {
        this.winnerVersion = winnerVersion;
        this.ignoredScope = ignoredScope;
    }
    
    public String getWinnerVersion()
    {
        return winnerVersion;
    }
    
    public String getOriginalScope()
    {
        return originalScope;
    }

    public void setOriginalScope( String originalScope )
    {
        this.originalScope = originalScope;
    }

    public Boolean getOriginaOptionality()
    {
        return originaOptionality;
    }

    public void setOriginaOptionality( Boolean originaOptionality )
    {
        this.originaOptionality = originaOptionality;
    }

    public String getIgnoredScope()
    {
        return ignoredScope;
    }
}


<|start_filename|>src/it/verbose/verify.groovy<|end_filename|>
/*
 * 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.
 */

def actual = new File( basedir, "target/tree-verbose.txt" ).readLines()
// omitted for cycle not supported anymore, but should probably return
// omitted for exclusion is not supported yet
def expected = new File( basedir, "expected-verbose.txt" ).readLines().findAll{!((it.contains('omitted for cycle')||it.contains('omitted for exclusion')))}

assert actual.equals( expected )

actual = new File( basedir, "target/tree-default.txt" ).readLines()
expected = new File( basedir, "expected-default.txt" ).readLines()

assert actual.equals( expected )

<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/Maven3DirectScopeDependencySelector.java<|end_filename|>
package org.apache.maven.shared.dependency.graph.internal.maven30;

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

import org.sonatype.aether.collection.DependencyCollectionContext;
import org.sonatype.aether.collection.DependencySelector;
import org.sonatype.aether.graph.Dependency;

/**
 * A dependency selector that excludes dependencies of an specific Scope which occur beyond level one of the dependency
 * graph.
 * 
 * @see Dependency#getScope()
 * @author <NAME>
 * @since 3.1.0
 */
public class Maven3DirectScopeDependencySelector
    implements DependencySelector
{

    private final String scope;

    private final int depth;

    public Maven3DirectScopeDependencySelector( String scope )
    {
        this( scope, 0 );
    }

    private Maven3DirectScopeDependencySelector( String scope, int depth )
    {
        if ( scope == null )
        {
            throw new IllegalArgumentException( "scope is null!" );
        }
        this.scope = scope;
        this.depth = depth;
    }

    /**
     * Decides whether the specified dependency should be included in the dependency graph.
     * 
     * @param dependency The dependency to check, must not be {@code null}.
     * @return {@code false} if the dependency should be excluded from the children of the current node, {@code true}
     *         otherwise.
     */
    @Override
    public boolean selectDependency( Dependency dependency )
    {
        return depth < 2 || !scope.equals( dependency.getScope() );
    }

    /**
     * Derives a dependency selector for the specified collection context. When calculating the child selector,
     * implementors are strongly advised to simply return the current instance if nothing changed to help save memory.
     * 
     * @param context The dependency collection context, must not be {@code null}.
     * @return The dependency selector for the target node, must not be {@code null}.
     */
    @Override
    public DependencySelector deriveChildSelector( DependencyCollectionContext context )
    {
        if ( depth >= 2 )
        {
            return this;
        }

        return new Maven3DirectScopeDependencySelector( scope, depth + 1 );
    }

    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + depth;
        result = prime * result + ( ( scope == null ) ? 0 : scope.hashCode() );
        return result;
    }

    @Override
    public boolean equals( Object obj )
    {
        if ( this == obj )
        {
            return true;
        }
        if ( obj == null )
        {
            return false;
        }
        if ( getClass() != obj.getClass() )
        {
            return false;
        }
        Maven3DirectScopeDependencySelector other = (Maven3DirectScopeDependencySelector) obj;
        if ( depth != other.depth )
        {
            return false;
        }
        if ( scope == null )
        {
            if ( other.scope != null )
            {
                return false;
            }
        }
        else if ( !scope.equals( other.scope ) )
        {
            return false;
        }
        return true;
    }

}


<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/DependencyGraphBuilder.java<|end_filename|>
package org.apache.maven.shared.dependency.graph;

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

import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingRequest;

import java.util.Collection;

/**
 * Maven project dependency graph builder API, neutral against Maven 2 or Maven 3.
 *
 * @author <NAME>
 * @since 2.0
 */
public interface DependencyGraphBuilder
{
    /**
     * Build the dependency graph.
     *
     * @param buildingRequest the buildingRequest
     * @param filter artifact filter (can be <code>null</code>)
     * @return the dependency graph
     * @throws DependencyGraphBuilderException if some of the dependencies could not be resolved.
     */
    DependencyNode buildDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter )
        throws DependencyGraphBuilderException;

    /**
     *
     * @param buildingRequest the buildingRequest
     * @param filter artifact filter (can be <code>null</code>)
     * @param reactorProjects ignored
     * @return the dependency graph
     * @throws DependencyGraphBuilderException if some of the dependencies could not be resolved.
     * @deprecated Use {@link #buildDependencyGraph(ProjectBuildingRequest, ArtifactFilter)} instead
     */
    @Deprecated
    default DependencyNode buildDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter,
                                         Collection<MavenProject> reactorProjects )
        throws DependencyGraphBuilderException 
    {
      return buildDependencyGraph( buildingRequest, filter );    
    }
}


<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/DependencyCollectorBuilder.java<|end_filename|>
package org.apache.maven.shared.dependency.graph;

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

import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.project.ProjectBuildingRequest;

/**
 * Maven project dependency raw dependency collector API, providing an abstraction layer against Maven 3 and Maven 3.1+
 * particular Aether implementations.
 * 
 * @author <NAME>
 * @since 3.1.0
 */
public interface DependencyCollectorBuilder
{

    /**
     * collect the project's raw dependency graph, with information to allow the API client to reason on its own about
     * dependencies.
     * 
     * @param buildingRequest the request with the project to process its dependencies.
     * @param filter an artifact filter if not all dependencies are required (can be <code>null</code>)
     * @return the raw dependency tree
     * @throws DependencyCollectorBuilderException if some of the dependencies could not be collected.
     */
    DependencyNode collectDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter )
        throws DependencyCollectorBuilderException;

}


<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeDeriver.java<|end_filename|>
package org.apache.maven.shared.dependency.graph.internal.maven30;

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

import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ScopeContext;
import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ScopeDeriver;
import org.sonatype.aether.RepositoryException;
import org.sonatype.aether.util.artifact.JavaScopes;

/**
 * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether.
 * 
 * @author <NAME>
 * @since 3.1.0
 */
public class JavaScopeDeriver
    extends ScopeDeriver
{

    @Override
    public void deriveScope( ScopeContext context )
        throws RepositoryException
    {
        context.setDerivedScope( getDerivedScope( context.getParentScope(), context.getChildScope() ) );
    }

    private String getDerivedScope( String parentScope, String childScope )
    {
        String derivedScope;

        if ( JavaScopes.SYSTEM.equals( childScope ) || JavaScopes.TEST.equals( childScope ) )
        {
            derivedScope = childScope;
        }
        else if ( parentScope == null || parentScope.length() <= 0 || JavaScopes.COMPILE.equals( parentScope ) )
        {
            derivedScope = childScope;
        }
        else if ( JavaScopes.TEST.equals( parentScope ) || JavaScopes.RUNTIME.equals( parentScope ) )
        {
            derivedScope = parentScope;
        }
        else if ( JavaScopes.SYSTEM.equals( parentScope ) || JavaScopes.PROVIDED.equals( parentScope ) )
        {
            derivedScope = JavaScopes.PROVIDED;
        }
        else
        {
            derivedScope = JavaScopes.RUNTIME;
        }

        return derivedScope;
    }

}


<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/traversal/FilteringDependencyNodeVisitor.java<|end_filename|>
package org.apache.maven.shared.dependency.graph.traversal;

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

import org.apache.maven.shared.dependency.graph.DependencyNode;
import org.apache.maven.shared.dependency.graph.filter.DependencyNodeFilter;

/**
 * A dependency node visitor that filters nodes and delegates to another visitor.
 * 
 * @author <a href="mailto:<EMAIL>"><NAME></a>
 * @version $Id$
 * @since 1.1
 */
public class FilteringDependencyNodeVisitor
    implements DependencyNodeVisitor
{
    // fields -----------------------------------------------------------------

    /**
     * The dependency node visitor to delegate to.
     */
    private final DependencyNodeVisitor visitor;

    /**
     * The dependency node filter to apply before delegation.
     */
    private final DependencyNodeFilter filter;

    // constructors -----------------------------------------------------------

    /**
     * Creates a dependency node visitor that delegates nodes that are accepted by the specified filter to the specified
     * visitor.
     * 
     * @param visitor the dependency node visitor to delegate to
     * @param filter the dependency node filter to apply before delegation
     */
    public FilteringDependencyNodeVisitor( DependencyNodeVisitor visitor, DependencyNodeFilter filter )
    {
        this.visitor = visitor;
        this.filter = filter;
    }

    // DependencyNodeVisitor methods ------------------------------------------

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit( DependencyNode node )
    {
        boolean visit;

        if ( filter.accept( node ) )
        {
            visit = visitor.visit( node );
        }
        else
        {
            visit = true;
        }

        return visit;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean endVisit( DependencyNode node )
    {
        boolean visit;

        if ( filter.accept( node ) )
        {
            visit = visitor.endVisit( node );
        }
        else
        {
            visit = true;
        }

        return visit;
    }

    // public methods ---------------------------------------------------------

    /**
     * Gets the dependency node visitor that this visitor delegates to.
     * 
     * @return the dependency node visitor
     */
    public DependencyNodeVisitor getDependencyNodeVisitor()
    {
        return visitor;
    }

    /**
     * Gets the dependency node filter that this visitor applies before delegation.
     * 
     * @return the dependency node filter
     */
    public DependencyNodeFilter getDependencyNodeFilter()
    {
        return filter;
    }
}


<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/filter/ArtifactDependencyNodeFilter.java<|end_filename|>
package org.apache.maven.shared.dependency.graph.filter;

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

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.shared.dependency.graph.DependencyNode;

/**
 * A dependency node filter that delegates to an artifact filter.
 * 
 * @author <a href="mailto:<EMAIL>"><NAME></a>
 * @version $Id$
 * @since 1.1
 */
public class ArtifactDependencyNodeFilter
    implements DependencyNodeFilter
{
    // fields -----------------------------------------------------------------

    /**
     * The artifact filter this dependency node filter delegates to.
     */
    private final ArtifactFilter filter;

    // constructors -----------------------------------------------------------

    /**
     * Creates a dependency node filter that delegates to the specified artifact filter.
     * 
     * @param filter the artifact filter to delegate to
     */
    public ArtifactDependencyNodeFilter( ArtifactFilter filter )
    {
        this.filter = filter;
    }

    // DependencyNodeFilter methods -------------------------------------------

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean accept( DependencyNode node )
    {
        Artifact artifact = node.getArtifact();

        return filter.include( artifact );
    }

    // public methods ---------------------------------------------------------

    /**
     * Gets the artifact filter this dependency node filter delegates to.
     * 
     * @return the artifact filter this dependency node filter delegates to
     */
    public ArtifactFilter getArtifactFilter()
    {
        return filter;
    }
}


<|start_filename|>src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyGraphBuilder.java<|end_filename|>
package org.apache.maven.shared.dependency.graph.internal;

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

import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
import org.apache.maven.shared.dependency.graph.DependencyNode;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
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;

/**
 * Default dependency graph builder that detects current Maven version to delegate to either Maven 3.0 or 3.1+ specific
 * code.
 *
 * @see Maven3DependencyGraphBuilder
 * @see Maven31DependencyGraphBuilder
 * @author <NAME>
 * @since 2.0
 */
@Component( role = DependencyGraphBuilder.class )
public class DefaultDependencyGraphBuilder
    extends AbstractLogEnabled
    implements DependencyGraphBuilder, Contextualizable
{
    protected PlexusContainer container;

    /**
     * Builds a dependency graph.
     *
     * @param buildingRequest the buildingRequest
     * @param filter artifact filter (can be <code>null</code>)
     * @return DependencyNode containing the dependency graph.
     * @throws DependencyGraphBuilderException if some of the dependencies could not be resolved.
     */
    @Override
    public DependencyNode buildDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter )
        throws DependencyGraphBuilderException
    {
        try
        {
            String hint = isMaven31() ? "maven31" : "maven3";

            DependencyGraphBuilder effectiveGraphBuilder =
                (DependencyGraphBuilder) container.lookup( DependencyGraphBuilder.class.getCanonicalName(), hint );
            
            if ( getLogger().isDebugEnabled() )
            {
                MavenProject project = buildingRequest.getProject();
                
                getLogger().debug( "building " + hint + " dependency graph for " + project.getId() + " with "
                                + effectiveGraphBuilder.getClass().getSimpleName() );
            }

            return effectiveGraphBuilder.buildDependencyGraph( buildingRequest, filter );
        }
        catch ( ComponentLookupException e )
        {
            throw new DependencyGraphBuilderException( e.getMessage(), e );
        }
    }

    /**
     * @return true if the current Maven version is Maven 3.1.
     */
    protected static boolean isMaven31()
    {
        try
        {
            Class<?> repoSessionClass =  MavenSession.class.getMethod( "getRepositorySession" ).getReturnType();
            
            return "org.eclipse.aether.RepositorySystemSession".equals( repoSessionClass.getName() );
        }
        catch ( NoSuchMethodException e )
        {
            throw new IllegalStateException( "Cannot determine return type of MavenSession.getRepositorySession" );
        }
    }

    /**
     * Injects the Plexus content.
     *
     * @param context   Plexus context to inject.
     * @throws ContextException if the PlexusContainer could not be located.
     */
    @Override
    public void contextualize( Context context )
        throws ContextException
    {
        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
    }
}


<|start_filename|>src/it/setup-plugin/src/main/java/graph/GraphMojo.java<|end_filename|>
package graph;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;

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

import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilder;
import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
import org.apache.maven.shared.dependency.graph.DependencyNode;
import org.apache.maven.shared.dependency.graph.traversal.SerializingDependencyNodeVisitor;

@Mojo( name = "graph" )
public class GraphMojo
    extends AbstractMojo
{

    @Parameter( defaultValue = "${session}", readonly = true, required = true )
    private MavenSession session;

    @Parameter( defaultValue = "${project}", readonly = true, required = true )
    private MavenProject project;
    
    @Parameter
    private ArtifactFilter artifactFilter;
    
    @Parameter
    private File outputFile;
    
    @Parameter
    private boolean verbose;

    @Component
    private DependencyGraphBuilder graphBuilder;

    @Component
    private DependencyCollectorBuilder collectorBuilder;
    
    @Override
    public void execute() throws MojoExecutionException
    {
        // Code currently assumes project has been set...
        ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
        buildingRequest.setProject( project );
        
        try
        {
            DependencyNode node;
            if ( verbose )
            {
                node = collectorBuilder.collectDependencyGraph( buildingRequest, artifactFilter );
            }
            else
            {
                node = graphBuilder.buildDependencyGraph( buildingRequest, artifactFilter );
            }
            
            if ( outputFile != null )
            {
                outputFile.getParentFile().mkdirs();

                try ( Writer writer = new FileWriter( outputFile ) )
                {
                    node.accept( new SerializingDependencyNodeVisitor( writer,
                                                                       SerializingDependencyNodeVisitor.STANDARD_TOKENS ) );
                }
            }
        }
        catch ( Exception e ) // Catch all is good enough for IT
        {
            throw new MojoExecutionException( "Failed to build dependency graph", e );
        }
    }

    
    
}