Example usage for org.apache.maven.artifact.resolver ResolutionListener SELECT_VERSION_FROM_RANGE

List of usage examples for org.apache.maven.artifact.resolver ResolutionListener SELECT_VERSION_FROM_RANGE

Introduction

In this page you can find the example usage for org.apache.maven.artifact.resolver ResolutionListener SELECT_VERSION_FROM_RANGE.

Prototype

int SELECT_VERSION_FROM_RANGE

To view the source code for org.apache.maven.artifact.resolver ResolutionListener SELECT_VERSION_FROM_RANGE.

Click Source Link

Usage

From source file:com.adviser.maven.GraphArtifactCollector.java

License:Apache License

private void recurse(ResolutionNode node, Map resolvedArtifacts, Map managedVersions,
        ArtifactRepository localRepository, List remoteRepositories, ArtifactMetadataSource source,
        ArtifactFilter filter, List listeners)
        throws CyclicDependencyException, ArtifactResolutionException, OverConstrainedVersionException {
    fireEvent(ResolutionListener.TEST_ARTIFACT, listeners, node);

    // TODO: use as a conflict resolver
    Object key = node.getKey();/*from w  ww .j  ava2  s.  co m*/
    if (managedVersions.containsKey(key)) {
        Artifact artifact = (Artifact) managedVersions.get(key);
        fireEvent(ResolutionListener.MANAGE_ARTIFACT, listeners, node, artifact);
        if (artifact.getVersion() != null) {
            node.getArtifact().setVersion(artifact.getVersion());
        }
        if (artifact.getScope() != null) {
            node.getArtifact().setScope(artifact.getScope());
        }
    }

    List previousNodes = (List) resolvedArtifacts.get(key);
    if (previousNodes != null) {
        node = checkPreviousNodes(node, listeners, previousNodes);
    } else {
        previousNodes = new ArrayList();
        resolvedArtifacts.put(key, previousNodes);
    }
    previousNodes.add(node);

    if (node.isActive()) {
        fireEvent(ResolutionListener.INCLUDE_ARTIFACT, listeners, node);
    }

    // don't pull in the transitive deps of a system-scoped dependency.
    if (node.isActive() && !Artifact.SCOPE_SYSTEM.equals(node.getArtifact().getScope())) {
        fireEvent(ResolutionListener.PROCESS_CHILDREN, listeners, node);
        for (Iterator i = node.getChildrenIterator(); i.hasNext();) {
            ResolutionNode child = (ResolutionNode) i.next();
            // We leave in optional ones, but don't pick up its dependencies
            if (!child.isResolved() && (!child.getArtifact().isOptional() || child.isChildOfRootNode())) {
                Artifact artifact = child.getArtifact();
                try {
                    if (artifact.getVersion() == null) {
                        // set the recommended version
                        // TODO: maybe its better to just pass the range
                        // through to retrieval and use a transformation?
                        ArtifactVersion version;
                        version = getArtifactVersion(localRepository, remoteRepositories, source, artifact);

                        artifact.selectVersion(version.toString());
                        fireEvent(ResolutionListener.SELECT_VERSION_FROM_RANGE, listeners, child);
                    }

                    ResolutionGroup rGroup = source.retrieve(artifact, localRepository, remoteRepositories);

                    // TODO might be better to have source.retreive() throw
                    // a specific exception for this situation
                    // and catch here rather than have it return null
                    if (rGroup == null) {
                        // relocated dependency artifact is declared
                        // excluded, no need to add and recurse further
                        continue;
                    }

                    child.addDependencies(rGroup.getArtifacts(), rGroup.getResolutionRepositories(), filter);
                } catch (CyclicDependencyException e) {
                    // would like to throw this, but we have crappy stuff in
                    // the repo

                    fireEvent(ResolutionListener.OMIT_FOR_CYCLE, listeners,
                            new ResolutionNode(e.getArtifact(), remoteRepositories, child));
                } catch (ArtifactMetadataRetrievalException e) {
                    artifact.setDependencyTrail(node.getDependencyTrail());
                    throw new ArtifactResolutionException(
                            "Unable to get dependency information: " + e.getMessage(), artifact, e);
                }

                recurse(child, resolvedArtifacts, managedVersions, localRepository, remoteRepositories, source,
                        filter, listeners);
            }
        }
        fireEvent(ResolutionListener.FINISH_PROCESSING_CHILDREN, listeners, node);
    }
}

From source file:com.adviser.maven.GraphArtifactCollector.java

License:Apache License

private ResolutionNode checkPreviousNodes(ResolutionNode node, List listeners, List previousNodes)
        throws OverConstrainedVersionException {
    for (Iterator i = previousNodes.iterator(); i.hasNext();) {
        ResolutionNode previous = (ResolutionNode) i.next();
        if (previous.isActive()) {
            // Version mediation
            VersionRange previousRange = previous.getArtifact().getVersionRange();
            VersionRange currentRange = node.getArtifact().getVersionRange();
            // TODO: why do we force the version on it? what if they
            // don't match?
            if (previousRange == null) {
                // version was already resolved
                node.getArtifact().setVersion(previous.getArtifact().getVersion());
            } else if (currentRange == null) {
                // version was already resolved
                previous.getArtifact().setVersion(node.getArtifact().getVersion());
            } else {
                // TODO: shouldn't need to double up on this work, only
                // done for simplicity of handling recommended
                // version but the restriction is identical
                VersionRange newRange = previousRange.restrict(currentRange);
                // TODO: ick. this forces the OCE that should have come
                // from the previous call. It is still correct
                if (newRange.isSelectedVersionKnown(previous.getArtifact())) {
                    fireEvent(ResolutionListener.RESTRICT_RANGE, listeners, node, previous.getArtifact(),
                            newRange);/* ww w .  ja  va  2 s .c  om*/
                }
                previous.getArtifact().setVersionRange(newRange);
                node.getArtifact().setVersionRange(currentRange.restrict(previousRange));

                // Select an appropriate available version from the (now
                // restricted) range
                // Note this version was selected before to get the
                // appropriate POM
                // But it was reset by the call to setVersionRange on
                // restricting the version
                ResolutionNode[] resetNodes = { previous, node };
                for (int j = 0; j < 2; j++) {
                    Artifact resetArtifact = resetNodes[j].getArtifact();
                    if (resetArtifact.getVersion() == null && resetArtifact.getVersionRange() != null
                            && resetArtifact.getAvailableVersions() != null) {

                        resetArtifact.selectVersion(resetArtifact.getVersionRange()
                                .matchVersion(resetArtifact.getAvailableVersions()).toString());
                        fireEvent(ResolutionListener.SELECT_VERSION_FROM_RANGE, listeners, resetNodes[j]);
                    }
                }
            }

            // Conflict Resolution
            // TODO: use as conflict resolver(s), chain

            // TODO: should this be part of mediation?
            // previous one is more dominant
            if (previous.getDepth() <= node.getDepth()) {
                checkScopeUpdate(node, previous, listeners);
            } else {
                checkScopeUpdate(previous, node, listeners);
            }

            if (previous.getDepth() <= node.getDepth()) {
                // previous was nearer
                fireEvent(ResolutionListener.OMIT_FOR_NEARER, listeners, node, previous.getArtifact());
                node.disable();
                node = previous;
            } else {
                fireEvent(ResolutionListener.OMIT_FOR_NEARER, listeners, previous, node.getArtifact());
                previous.disable();
            }
        }
    }
    return node;
}

From source file:com.adviser.maven.GraphArtifactCollector.java

License:Apache License

private void fireEvent(int event, List listeners, ResolutionNode node, Artifact replacement,
        VersionRange newRange) {/* ww  w.j a  v  a  2  s.c  om*/
    for (Iterator i = listeners.iterator(); i.hasNext();) {
        ResolutionListener listener = (ResolutionListener) i.next();

        switch (event) {
        case ResolutionListener.TEST_ARTIFACT:
            listener.testArtifact(node.getArtifact());
            break;
        case ResolutionListener.PROCESS_CHILDREN:
            listener.startProcessChildren(node.getArtifact());
            break;
        case ResolutionListener.FINISH_PROCESSING_CHILDREN:
            listener.endProcessChildren(node.getArtifact());
            break;
        case ResolutionListener.INCLUDE_ARTIFACT:
            listener.includeArtifact(node.getArtifact());
            break;
        case ResolutionListener.OMIT_FOR_NEARER:
            String version = node.getArtifact().getVersion();
            String replacementVersion = replacement.getVersion();
            if (version != null ? !version.equals(replacementVersion) : replacementVersion != null) {
                listener.omitForNearer(node.getArtifact(), replacement);
            }
            break;
        case ResolutionListener.OMIT_FOR_CYCLE:
            listener.omitForCycle(node.getArtifact());
            break;
        case ResolutionListener.UPDATE_SCOPE:
            listener.updateScope(node.getArtifact(), replacement.getScope());
            break;
        case ResolutionListener.UPDATE_SCOPE_CURRENT_POM:
            listener.updateScopeCurrentPom(node.getArtifact(), replacement.getScope());
            break;
        case ResolutionListener.MANAGE_ARTIFACT:
            listener.manageArtifact(node.getArtifact(), replacement);
            break;
        case ResolutionListener.SELECT_VERSION_FROM_RANGE:
            listener.selectVersionFromRange(node.getArtifact());
            break;
        case ResolutionListener.RESTRICT_RANGE:
            if (node.getArtifact().getVersionRange().hasRestrictions()
                    || replacement.getVersionRange().hasRestrictions()) {
                listener.restrictRange(node.getArtifact(), replacement, newRange);
            }
            break;
        default:
            throw new IllegalStateException("Unknown event: " + event);
        }
    }
}

From source file:org.universAAL.maven.treebuilder.DependencyTreeBuilder.java

License:Apache License

/**
 * FireEvent methods are used for sending events related resolution process
 * to the listeners passed as arguments.
 * /*  w  w w  .  j a va2s  .com*/
 * @param event
 *            Integer value of the event.
 * @param listener
 *            Listener which will be notified about the event.
 * @param node
 *            Node related to the event.
 * @param replacement
 *            Node which will replace the one passed in the previous
 *            argument.
 * @param newRange
 *            A new range which will be applied in case of RESTRICT_RANGE
 *            event.
 */
private void fireEvent(final int event, final DependencyTreeResolutionListener listener,
        final ResolutionNode node, final ResolutionNode replacement, final VersionRange newRange) {
    switch (event) {
    case ResolutionListener.TEST_ARTIFACT:
        listener.testArtifact(node.getArtifact());
        break;
    case ResolutionListener.PROCESS_CHILDREN:
        listener.startProcessChildren(node.getArtifact());
        break;
    case ResolutionListener.FINISH_PROCESSING_CHILDREN:
        listener.endProcessChildren(node.getArtifact());
        break;
    case ResolutionListener.INCLUDE_ARTIFACT:
        listener.includeArtifact(node);
        break;
    case ResolutionListener.OMIT_FOR_NEARER:
        listener.omitForNearer(node, replacement);
        break;
    case ResolutionListener.OMIT_FOR_CYCLE:
        listener.omitForCycle(node);
        break;
    case ResolutionListener.UPDATE_SCOPE:
        listener.updateScope(node, replacement.getArtifact().getScope());
        break;
    case ResolutionListener.UPDATE_SCOPE_CURRENT_POM:
        listener.updateScopeCurrentPom(node, replacement.getArtifact().getScope());
        break;
    case ResolutionListener.MANAGE_ARTIFACT_VERSION:
        if (listener instanceof ResolutionListenerForDepMgmt) {
            ResolutionListenerForDepMgmt asImpl = listener;
            asImpl.manageArtifactVersion(node.getArtifact(), replacement.getArtifact());
        } else {
            listener.manageArtifact(node.getArtifact(), replacement.getArtifact());
        }
        break;
    case ResolutionListener.MANAGE_ARTIFACT_SCOPE:
        if (listener instanceof ResolutionListenerForDepMgmt) {
            ResolutionListenerForDepMgmt asImpl = listener;
            asImpl.manageArtifactScope(node.getArtifact(), replacement.getArtifact());
        } else {
            listener.manageArtifact(node.getArtifact(), replacement.getArtifact());
        }
        break;
    case ResolutionListener.SELECT_VERSION_FROM_RANGE:
        listener.selectVersionFromRange(node.getArtifact());
        break;
    case ResolutionListener.RESTRICT_RANGE:
        if (node.getArtifact().getVersionRange().hasRestrictions()
                || replacement.getArtifact().getVersionRange().hasRestrictions()) {
            listener.restrictRange(node.getArtifact(), replacement.getArtifact(), newRange);
        }
        break;
    default:
        throw new IllegalStateException("Unknown event: " + event);
    }
}

From source file:org.universAAL.maven.treebuilder.DependencyTreeBuilder.java

License:Apache License

/**
 * Method resolves provided node with the use of provided
 * ArtifactMetadataSource and taking into account ManagedVersionMap. Output
 * is passed to listeners, passed as argument, which are notified about all
 * events related to dependencies detected in the tree.
 * /*w  w w .j a va  2s  . co m*/
 * @param parentNode
 *            Parent node
 * @param child
 *            Child node
 * @param filter
 *            Filter for filtering artifacts for the resolving process.
 * @param managedVersions
 *            Map of managed versions.
 * @param listener
 *            Listener to be notified about events related to resolution
 *            process.
 * @param source
 *            ArtifactMetadataSource object passed by maven.
 * @param parentArtifact
 *            Parent artifact
 * @return returns true if the child should be recursively resolved.
 * @throws OverConstrainedVersionException
 *             Occurs when ranges exclude each other and no valid value
 *             remains.
 * @throws ArtifactMetadataRetrievalException
 *             Error while retrieving repository metadata from the
 *             repository
 */
private boolean resolveChildNode(final ResolutionNode parentNode, final ResolutionNode child,
        final ArtifactFilter filter, final ManagedVersionMap managedVersions,
        final DependencyTreeResolutionListener listener, final ArtifactMetadataSource source,
        final Artifact parentArtifact)
        throws OverConstrainedVersionException, ArtifactMetadataRetrievalException {
    // We leave in optional ones, but don't pick up its dependencies
    if (!child.isResolved() && (!child.getArtifact().isOptional() || child.isChildOfRootNode())) {
        Artifact artifact = child.getArtifact();
        artifact.setDependencyTrail(parentNode.getDependencyTrail());

        List childRemoteRepositories = child.getRemoteRepositories();
        try {
            Object childKey;
            do {
                childKey = child.getKey();

                if (managedVersions.containsKey(childKey)) {
                    // If this child node is a managed dependency,
                    // ensure
                    // we are using the dependency management
                    // version
                    // of this child if applicable b/c we want to
                    // use the
                    // managed version's POM, *not* any other
                    // version's POM.
                    // We retrieve the POM below in the retrieval
                    // step.
                    manageArtifact(child, managedVersions);

                    // Also, we need to ensure that any exclusions
                    // it presents are
                    // added to the artifact before we retrieve the
                    // metadata
                    // for the artifact; otherwise we may end up
                    // with unwanted
                    // dependencies.
                    Artifact ma = (Artifact) managedVersions.get(childKey);
                    ArtifactFilter managedExclusionFilter = ma.getDependencyFilter();
                    if (null != managedExclusionFilter) {
                        if (null != artifact.getDependencyFilter()) {
                            AndArtifactFilter aaf = new AndArtifactFilter();
                            aaf.add(artifact.getDependencyFilter());
                            aaf.add(managedExclusionFilter);
                            artifact.setDependencyFilter(aaf);
                        } else {
                            artifact.setDependencyFilter(managedExclusionFilter);
                        }
                    }
                }

                if (artifact.getVersion() == null) {
                    // set the recommended version
                    // TODO: maybe its better to just pass the range
                    // through to retrieval and use a
                    // transformation?
                    ArtifactVersion version;
                    if (artifact.isSelectedVersionKnown()) {
                        version = artifact.getSelectedVersion();
                    } else {
                        // go find the version
                        List versions = artifact.getAvailableVersions();
                        if (versions == null) {
                            versions = source.retrieveAvailableVersions(artifact, localRepository,
                                    childRemoteRepositories);
                            artifact.setAvailableVersions(versions);
                        }

                        Collections.sort(versions);

                        VersionRange versionRange = artifact.getVersionRange();

                        version = versionRange.matchVersion(versions);

                        if (version == null) {
                            if (versions.isEmpty()) {
                                throw new OverConstrainedVersionException(
                                        "No versions are present in the repository for the artifact with a range "
                                                + versionRange,
                                        artifact, childRemoteRepositories);
                            }

                            throw new OverConstrainedVersionException("Couldn't find a version in " + versions
                                    + " to match range " + versionRange, artifact, childRemoteRepositories);
                        }
                    }

                    // this is dangerous because
                    // artifact.getSelectedVersion() can
                    // return null. However it is ok here because we
                    // first check if the
                    // selected version is known. As currently coded
                    // we can't get a null here.
                    artifact.selectVersion(version.toString());
                    fireEvent(ResolutionListener.SELECT_VERSION_FROM_RANGE, listener, child);
                }

                // rotgier: it is not compatible with maven 3
                // Artifact relocated = source.retrieveRelocatedArtifact(
                // artifact, localRepository, childRemoteRepositories);
                // if (relocated != null && !artifact.equals(relocated)) {
                // relocated.setDependencyFilter(artifact
                // .getDependencyFilter());
                // artifact = relocated;
                // child.setArtifact(artifact);
                // }
            } while (!childKey.equals(child.getKey()));

            if (parentArtifact != null && parentArtifact.getDependencyFilter() != null
                    && !parentArtifact.getDependencyFilter().include(artifact)) {
                // MNG-3769: the [probably relocated] artifact is
                // excluded.
                // We could process exclusions on relocated artifact
                // details in the
                // MavenMetadataSource.createArtifacts(..) step, BUT
                // that would
                // require resolving the POM from the repository
                // very early on in
                // the build.
                return true;
            }

            ResolutionGroup rGroup = source.retrieve(artifact, localRepository, childRemoteRepositories);

            // TODO might be better to have source.retrieve() throw
            // a specific exception for this situation
            // and catch here rather than have it return null
            if (rGroup == null) {
                // relocated dependency artifact is declared
                // excluded, no need to add and recurse further
                return true;
            }
            child.addDependencies(rGroup.getArtifacts(), rGroup.getResolutionRepositories(), filter);

        } catch (CyclicDependencyException e) {
            // would like to throw this, but we have crappy stuff in
            // the repo

            fireEvent(ResolutionListener.OMIT_FOR_CYCLE, listener,
                    new ResolutionNode(e.getArtifact(), childRemoteRepositories, child));
        } catch (ArtifactMetadataRetrievalException e) {
            artifact.setDependencyTrail(parentNode.getDependencyTrail());
            throw e;
        }
    } else {
        return true;
    }
    return false;
}

From source file:org.universAAL.maven.treebuilder.DependencyTreeBuilder.java

License:Apache License

/**
 * The heart of the tree builder. Recursively resolves provided artifact.
 * Output is passed to listeners, passed as argument, which are notified
 * about all dependencies detected in the tree. Resolving of each child node
 * is delegated to resolveChildNode method.
 * //from w  ww .j av a2s  .  c  om
 * @param originatingArtifact
 *            Rootnode of recursed subtree.
 * @param node
 *            Current node which is resolved.
 * @param resolvedArtifacts
 *            Map which is used for remembering already resolved artifacts.
 *            Artifacts are indexed by a key which calculation algorithm is
 *            the same as the one present in calculateDepKey method. Thanks
 *            to this map, duplicates and conflicts are detected and
 *            resolved.
 * @param managedVersions
 *            Information about dependency management extracted from the
 *            subtree rootnode - a maven project.
 * @param localRepository
 *            Local maven repository.
 * @param remoteRepositories
 *            Remote repositories provided by maven.
 * @param source
 *            ArtifactMetadataSource provided by maven.
 * @param filter
 *            Filter used for unfiltering artifacts which should not be
 *            included in the dependency tree.
 * @param listener
 *            Listener used for providing the output of the resolve process.
 * @param transitive
 *            If this parameter is false than the children of current node
 *            are not resolved.
 * 
 * @throws CyclicDependencyException
 *             Exception thrown when cyclic dependency detected.
 * @throws ArtifactResolutionException
 *             Exception thrown when a problem with artifact resolution
 *             occurs.
 * @throws OverConstrainedVersionException
 *             Occurs when ranges exclude each other and no valid value
 *             remains.
 * @throws ArtifactMetadataRetrievalException
 *             Error while retrieving repository metadata from the
 *             repository.
 * @throws NoSuchFieldException
 *             Signals that the class doesn't have a field of a specified
 *             name.
 * @throws SecurityException
 *             Thrown by the security manager to indicate a security
 *             violation.
 * @throws IllegalAccessException
 *             When illegal access is performed in the curse of java
 *             reflection operations.
 * @throws IllegalArgumentException
 *             Thrown to indicate that an illegal or inappropriate argument
 *             has been passed.
 */
private void recurse(final Artifact originatingArtifact, final ResolutionNode node, final Map resolvedArtifacts,
        final ManagedVersionMap managedVersions, final ArtifactRepository localRepository,
        final List remoteRepositories, final ArtifactMetadataSource source, final ArtifactFilter filter,
        final DependencyTreeResolutionListener listener, final boolean transitive,
        final Set<String> separatedGroupIds) throws CyclicDependencyException, ArtifactResolutionException,
        OverConstrainedVersionException, ArtifactMetadataRetrievalException, SecurityException,
        NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
    try {

        fireEvent(ResolutionListener.TEST_ARTIFACT, listener, node);
        Object key = node.getKey();

        // TODO: Does this check need to happen here? Had to add the same
        // call
        // below when we iterate on child nodes -- will that suffice?
        if (managedVersions.containsKey(key)) {
            manageArtifact(node, managedVersions);
        }

        List previousNodes = (List) resolvedArtifacts.get(key);
        if (previousNodes != null) {
            for (Iterator i = previousNodes.iterator(); i.hasNext();) {
                ResolutionNode previous = (ResolutionNode) i.next();

                if (previous.isActive()) {
                    // Version mediation
                    VersionRange previousRange = previous.getArtifact().getVersionRange();
                    VersionRange currentRange = node.getArtifact().getVersionRange();

                    if (previousRange != null && currentRange != null) {
                        // TODO: shouldn't need to double up on this work,
                        // only
                        // done for simplicity of handling recommended
                        // version but the restriction is identical
                        VersionRange newRange = previousRange.restrict(currentRange);
                        // TODO: ick. this forces the OCE that should have
                        // come
                        // from the previous call. It is still correct
                        if (newRange.isSelectedVersionKnown(previous.getArtifact())) {
                            fireEvent(ResolutionListener.RESTRICT_RANGE, listener, node, previous, newRange);
                        }
                        previous.getArtifact().setVersionRange(newRange);
                        node.getArtifact().setVersionRange(currentRange.restrict(previousRange));

                        // Select an appropriate available version from the
                        // (now
                        // restricted) range
                        // Note this version was selected before to get the
                        // appropriate POM
                        // But it was reset by the call to setVersionRange
                        // on
                        // restricting the version
                        ResolutionNode[] resetNodes = { previous, node };
                        for (int j = 0; j < 2; j++) {
                            Artifact resetArtifact = resetNodes[j].getArtifact();

                            // MNG-2123: if the previous node was not a
                            // range,
                            // then it wouldn't have any available
                            // versions. We just clobbered the selected
                            // version
                            // above. (why? i have no idea.)
                            // So since we are here and this is ranges we
                            // must
                            // go figure out the version (for a third
                            // time...)
                            if (resetArtifact.getVersion() == null && resetArtifact.getVersionRange() != null) {

                                // go find the version. This is a total
                                // hack.
                                // See previous comment.
                                List versions = resetArtifact.getAvailableVersions();
                                if (versions == null) {
                                    try {
                                        versions = source.retrieveAvailableVersions(resetArtifact,
                                                localRepository, remoteRepositories);
                                        resetArtifact.setAvailableVersions(versions);
                                    } catch (ArtifactMetadataRetrievalException e) {
                                        resetArtifact.setDependencyTrail(node.getDependencyTrail());
                                        throw e;
                                    }
                                }
                                // end hack

                                // MNG-2861: match version can return null
                                ArtifactVersion selectedVersion = resetArtifact.getVersionRange()
                                        .matchVersion(resetArtifact.getAvailableVersions());
                                if (selectedVersion != null) {
                                    resetArtifact.selectVersion(selectedVersion.toString());
                                } else {
                                    throw new OverConstrainedVersionException(
                                            " Unable to find a version in "
                                                    + resetArtifact.getAvailableVersions()
                                                    + " to match the range " + resetArtifact.getVersionRange(),
                                            resetArtifact);
                                }
                                fireEvent(ResolutionListener.SELECT_VERSION_FROM_RANGE, listener,
                                        resetNodes[j]);
                            }
                        }
                    }

                    // Conflict Resolution
                    // TODO: use as conflict resolver(s), chain

                    // TODO: should this be part of mediation?
                    // previous one is more dominant
                    ResolutionNode nearest;
                    ResolutionNode farthest;
                    if (previous.getDepth() <= node.getDepth()) {
                        nearest = previous;
                        farthest = node;
                    } else {
                        nearest = node;
                        farthest = previous;
                    }

                    if (checkScopeUpdate(farthest, nearest)) {
                        // if we need to update scope of nearest to use
                        // farthest
                        // scope, use the nearest version, but farthest
                        // scope
                        nearest.disable();
                        farthest.getArtifact().setVersion(nearest.getArtifact().getVersion());
                        fireEvent(ResolutionListener.OMIT_FOR_NEARER, listener, nearest, farthest);
                    } else {
                        farthest.disable();
                        fireEvent(ResolutionListener.OMIT_FOR_NEARER, listener, farthest, nearest);
                    }
                }
            }
        } else {
            previousNodes = new ArrayList();
            resolvedArtifacts.put(key, previousNodes);
        }
        previousNodes.add(node);

        if (node.isActive()) {
            fireEvent(ResolutionListener.INCLUDE_ARTIFACT, listener, node);
        }

        // don't pull in the transitive deps of a system-scoped dependency.
        if (node.isActive() && !Artifact.SCOPE_SYSTEM.equals(node.getArtifact().getScope())) {
            fireEvent(ResolutionListener.PROCESS_CHILDREN, listener, node);
            if (transitive) {
                Artifact parentArtifact = node.getArtifact();
                for (Iterator i = node.getChildrenIterator(); i.hasNext();) {
                    ResolutionNode child = (ResolutionNode) i.next();
                    if (!filter.include(child.getArtifact())) {
                        continue;
                    }
                    /*
                     * rotgier: In case of regular dependencies provided
                     * scope is simply ignored (artifact versions specified
                     * there conflict with the ones of runtime deps)
                     */
                    if (Artifact.SCOPE_PROVIDED.equals(child.getArtifact().getScope())) {
                        continue;
                    }
                    changeArtifactCoreToOsgi(node, child, separatedGroupIds, listener);
                    boolean isContinue = resolveChildNode(node, child, filter, managedVersions, listener,
                            source, parentArtifact);
                    if (isContinue) {
                        continue;
                    }
                    List<String> extractedSeparatedGroupIds = extractSeparatedGroupIds(child.getArtifact(),
                            remoteRepositories);
                    Set<String> combinedSeparatedGroupIds = new HashSet<String>(separatedGroupIds);
                    combinedSeparatedGroupIds.addAll(extractedSeparatedGroupIds);
                    recurse(originatingArtifact, child, resolvedArtifacts, managedVersions, localRepository,
                            child.getRemoteRepositories(), source, filter, listener, true,
                            combinedSeparatedGroupIds);
                }
                List runtimeDeps = getRuntimeDeps(node.getArtifact(), managedVersions, remoteRepositories);
                Field childrenField = node.getClass().getDeclaredField("children");
                childrenField.setAccessible(true);
                List nodesChildren = (List) childrenField.get(node);
                /* nodesChildren can be empty when dealing with parent POMs */
                if (nodesChildren == Collections.EMPTY_LIST) {
                    nodesChildren = new ArrayList();
                    childrenField.set(node, nodesChildren);
                }
                for (Object runtimeDepObj : runtimeDeps) {
                    DependencyNode runtimeDep = (DependencyNode) runtimeDepObj;
                    Artifact artifact = runtimeDep.getArtifact();
                    ResolutionNode childRuntime = new ResolutionNode(artifact, node.getRemoteRepositories(),
                            node);
                    /*
                     * rotgier: In case of runtime dependencies provided
                     * scope should be allowed
                     */
                    if (!filter.include(childRuntime.getArtifact())) {

                        if (!Artifact.SCOPE_PROVIDED.equals(artifact.getScope())) {
                            continue;
                        }
                    }
                    changeArtifactCoreToOsgi(node, childRuntime, separatedGroupIds, listener);
                    boolean isContinue = resolveChildNode(node, childRuntime, filter, managedVersions, listener,
                            source, parentArtifact);
                    if (isContinue) {
                        continue;
                    }
                    List<String> extractedSeparatedGroupIds = extractSeparatedGroupIds(
                            childRuntime.getArtifact(), remoteRepositories);
                    Set<String> combinedSeparatedGroupIds = new HashSet<String>(separatedGroupIds);
                    combinedSeparatedGroupIds.addAll(extractedSeparatedGroupIds);
                    recurse(originatingArtifact, childRuntime, resolvedArtifacts, managedVersions,
                            localRepository, childRuntime.getRemoteRepositories(), source, filter, listener,
                            true, combinedSeparatedGroupIds);
                    nodesChildren.add(childRuntime);
                }
            }
            fireEvent(ResolutionListener.FINISH_PROCESSING_CHILDREN, listener, node);
        }
    } catch (Exception ex) {
        StringBuilder msg = new StringBuilder();
        msg.append(String.format("\nUnpredicted exception during dependency tree recursion at node %s",
                FilteringVisitorSupport.stringify(node.getArtifact())));
        msg.append("\nNode's parent tree:\n");
        msg.append(printNodeParentsTree(node));
        throw new IllegalStateException(msg.toString(), ex);
    }
}