private Set<ResolvedArtifact> getArtifacts(ConfigurationNode childConfiguration) {
   String[] targetConfigurations =
       from.metaData.getHierarchy().toArray(new String[from.metaData.getHierarchy().size()]);
   DependencyArtifactDescriptor[] dependencyArtifacts =
       dependencyDescriptor.getDependencyArtifacts(targetConfigurations);
   if (dependencyArtifacts.length == 0) {
     return Collections.emptySet();
   }
   Set<ResolvedArtifact> artifacts = new LinkedHashSet<ResolvedArtifact>();
   for (DependencyArtifactDescriptor artifactDescriptor : dependencyArtifacts) {
     ModuleRevisionId id =
         childConfiguration.moduleRevision.metaData.getDescriptor().getModuleRevisionId();
     Artifact artifact =
         new DefaultArtifact(
             id,
             null,
             artifactDescriptor.getName(),
             artifactDescriptor.getType(),
             artifactDescriptor.getExt(),
             artifactDescriptor.getUrl(),
             artifactDescriptor.getQualifiedExtraAttributes());
     artifacts.add(
         resolveState.builder.newArtifact(
             childConfiguration.getResult(),
             artifact,
             targetModuleRevision.resolve().getArtifactResolver()));
   }
   return artifacts;
 }
 public void removeFromTargetConfigurations() {
   for (ConfigurationNode targetConfiguration : targetConfigurations) {
     targetConfiguration.removeIncomingEdge(this);
   }
   targetConfigurations.clear();
   if (targetModuleRevision != null) {
     selector.getSelectedModule().removeUnattachedDependency(this);
   }
 }
 public void validate() {
   for (DependencyEdge incomingEdge : incomingEdges) {
     ConfigurationNode fromNode = incomingEdge.from;
     if (!fromNode.isSelected()) {
       throw new IllegalStateException(
           String.format(
               "Unexpected state %s for parent node for dependency from %s to %s.",
               fromNode.moduleRevision.state, fromNode, this));
     }
   }
 }
 public void attachToTargetConfigurations() {
   if (targetModuleRevision.state != ModuleState.Selected) {
     return;
   }
   calculateTargetConfigurations();
   for (ConfigurationNode targetConfiguration : targetConfigurations) {
     targetConfiguration.addIncomingEdge(this);
   }
   if (!targetConfigurations.isEmpty()) {
     selector.getSelectedModule().removeUnattachedDependency(this);
   }
 }
 @Override
 public String toString() {
   return String.format(
       "%s -> %s(%s)",
       from.toString(),
       dependencyMetaData.getRequested(),
       Joiner.on(',').join(dependencyMetaData.getModuleConfigurations()));
 }
    public void attachToParents(
        ConfigurationNode childConfiguration, ResolvedConfigurationBuilder result) {
      ResolvedConfigurationIdentifier parent = from.getResult();
      ResolvedConfigurationIdentifier child = childConfiguration.getResult();
      result.addChild(parent, child);

      Set<ResolvedArtifact> artifacts = getArtifacts(childConfiguration);
      if (artifacts.isEmpty()) {
        artifacts = childConfiguration.getArtifacts();
      }
      // TODO SF merge with addChild
      result.addParentSpecificArtifacts(child, parent, artifacts);

      if (parent == resolveState.root.getResult()) {
        EnhancedDependencyDescriptor enhancedDependencyDescriptor =
            (EnhancedDependencyDescriptor) dependencyDescriptor;
        result.addFirstLevelDependency(enhancedDependencyDescriptor.getModuleDependency(), child);
      }
    }
  /** Populates the result from the graph traversal state. */
  private void assembleResult(ResolveState resolveState, DependencyGraphVisitor listener) {
    listener.start(resolveState.root);

    // Visit the nodes
    for (ConfigurationNode resolvedConfiguration : resolveState.getConfigurationNodes()) {
      if (resolvedConfiguration.isSelected()) {
        resolvedConfiguration.validate();
        listener.visitNode(resolvedConfiguration);
      }
    }
    // Visit the edges
    for (ConfigurationNode resolvedConfiguration : resolveState.getConfigurationNodes()) {
      if (resolvedConfiguration.isSelected()) {
        listener.visitEdge(resolvedConfiguration);
      }
    }

    listener.finish(resolveState.root);
  }
  /** Populates the result from the graph traversal state. */
  private void assembleResult(
      ResolveState resolveState,
      ResolvedConfigurationBuilder result,
      ResolvedConfigurationListener listener) {
    FailureState failureState = new FailureState(resolveState.root);
    ModuleVersionIdentifier root = resolveState.root.toId();
    listener.start(root);

    for (ConfigurationNode resolvedConfiguration : resolveState.getConfigurationNodes()) {
      if (resolvedConfiguration.isSelected()) {
        resolvedConfiguration.attachToParents(result);
        resolvedConfiguration.collectFailures(failureState);
        listener.resolvedModuleVersion(resolvedConfiguration.moduleRevision);
      }
    }
    for (ConfigurationNode resolvedConfiguration : resolveState.getConfigurationNodes()) {
      if (resolvedConfiguration.isSelected()) {
        listener.resolvedConfiguration(
            resolvedConfiguration.toId(), resolvedConfiguration.outgoingEdges);
      }
    }
    failureState.attachFailures(result);
    result.done(resolveState.root.getResult());
  }
  /**
   * Traverses the dependency graph, resolving conflicts and building the paths from the root
   * configuration.
   */
  private void traverseGraph(ResolveState resolveState) {
    Set<ModuleIdentifier> conflicts = new LinkedHashSet<ModuleIdentifier>();

    resolveState.onMoreSelected(resolveState.root);

    List<DependencyEdge> dependencies = new ArrayList<DependencyEdge>();
    while (resolveState.peek() != null || !conflicts.isEmpty()) {
      if (resolveState.peek() != null) {
        ConfigurationNode node = resolveState.pop();
        LOGGER.debug("Visiting configuration {}.", node);

        // Calculate the outgoing edges of this configuration
        dependencies.clear();
        node.visitOutgoingDependencies(dependencies);

        for (DependencyEdge dependency : dependencies) {
          LOGGER.debug("Visiting dependency {}", dependency);

          // Resolve dependency to a particular revision
          ModuleVersionResolveState moduleRevision = dependency.resolveModuleRevisionId();
          if (moduleRevision == null) {
            // Failed to resolve.
            continue;
          }
          ModuleIdentifier moduleId = moduleRevision.id.getModule();

          // Check for a new conflict
          if (moduleRevision.state == ModuleState.New) {
            ModuleResolveState module = resolveState.getModule(moduleId);

            // A new module revision. Check for conflict
            Collection<ModuleVersionResolveState> versions = module.getVersions();
            if (versions.size() == 1) {
              // First version of this module. Select it for now
              LOGGER.debug("Selecting new module version {}", moduleRevision);
              module.select(moduleRevision);
            } else {
              // Not the first version of this module. We have a new conflict
              LOGGER.debug("Found new conflicting module version {}", moduleRevision);
              conflicts.add(moduleId);

              // Deselect the currently selected version, and remove all outgoing edges from the
              // version
              // This will propagate through the graph and prune configurations that are no longer
              // required
              ModuleVersionResolveState previouslySelected = module.clearSelection();
              if (previouslySelected != null) {
                for (ConfigurationNode configuration : previouslySelected.configurations) {
                  configuration.removeOutgoingEdges();
                }
              }
            }
          }

          dependency.attachToTargetConfigurations();
        }
      } else {
        // We have some batched up conflicts. Resolve the first, and continue traversing the graph
        ModuleIdentifier moduleId = conflicts.iterator().next();
        conflicts.remove(moduleId);
        ModuleResolveState module = resolveState.getModule(moduleId);
        ModuleVersionResolveState selected =
            conflictResolver.select(module.getVersions(), resolveState.root.moduleRevision);
        LOGGER.debug("Selected {} from conflicting modules {}.", selected, module.getVersions());

        // Restart each configuration. For the evicted configuration, this means moving incoming
        // dependencies across to the
        // matching selected configuration. For the select configuration, this mean traversing its
        // dependencies.
        module.restart(selected);
      }
    }
  }
 public void restart(ModuleVersionResolveState selected) {
   for (ConfigurationNode configuration : configurations) {
     configuration.restart(selected);
   }
 }
 public void removeFromTargetConfigurations() {
   for (ConfigurationNode targetConfiguration : targetConfigurations) {
     targetConfiguration.removeIncomingEdge(this);
   }
   targetConfigurations.clear();
 }
 public boolean isTransitive() {
   return from.isTransitive() && dependencyMetaData.isTransitive();
 }
 @Override
 public String toString() {
   return String.format(
       "%s -> %s(%s)", from.toString(), dependencyMetaData.getRequested(), dependencyDescriptor);
 }
  /**
   * Traverses the dependency graph, resolving conflicts and building the paths from the root
   * configuration.
   */
  private void traverseGraph(
      final ResolveState resolveState, final ConflictHandler conflictHandler) {
    resolveState.onMoreSelected(resolveState.root);

    List<DependencyEdge> dependencies = new ArrayList<DependencyEdge>();
    while (resolveState.peek() != null || conflictHandler.hasConflicts()) {
      if (resolveState.peek() != null) {
        ConfigurationNode node = resolveState.pop();
        LOGGER.debug("Visiting configuration {}.", node);

        // Calculate the outgoing edges of this configuration
        dependencies.clear();
        node.visitOutgoingDependencies(dependencies);

        for (DependencyEdge dependency : dependencies) {
          LOGGER.debug("Visiting dependency {}", dependency);

          // Resolve dependency to a particular revision
          ModuleVersionResolveState moduleRevision = dependency.resolveModuleRevisionId();
          if (moduleRevision == null) {
            // Failed to resolve.
            continue;
          }
          ModuleIdentifier moduleId = moduleRevision.id.getModule();

          // Check for a new conflict
          if (moduleRevision.state == ModuleState.New) {
            ModuleResolveState module = resolveState.getModule(moduleId);

            // A new module revision. Check for conflict
            PotentialConflict c = conflictHandler.registerModule(module);
            if (!c.conflictExists()) {
              // No conflict. Select it for now
              LOGGER.debug("Selecting new module version {}", moduleRevision);
              module.select(moduleRevision);
            } else {
              // We have a conflict
              LOGGER.debug("Found new conflicting module version {}", moduleRevision);

              // Deselect the currently selected version, and remove all outgoing edges from the
              // version
              // This will propagate through the graph and prune configurations that are no longer
              // required
              // For each module participating in the conflict (many times there is only one
              // participating module that has multiple versions)
              c.withParticipatingModules(
                  new Action<ModuleIdentifier>() {
                    public void execute(ModuleIdentifier module) {
                      ModuleVersionResolveState previouslySelected =
                          resolveState.getModule(module).clearSelection();
                      if (previouslySelected != null) {
                        for (ConfigurationNode configuration : previouslySelected.configurations) {
                          configuration.deselect();
                        }
                      }
                    }
                  });
            }
          }

          dependency.attachToTargetConfigurations();
        }
      } else {
        // We have some batched up conflicts. Resolve the first, and continue traversing the graph
        conflictHandler.resolveNextConflict(
            new Action<ConflictResolutionResult>() {
              public void execute(final ConflictResolutionResult result) {
                result
                    .getConflict()
                    .withParticipatingModules(
                        new Action<ModuleIdentifier>() {
                          public void execute(ModuleIdentifier moduleIdentifier) {
                            ModuleVersionResolveState selected = result.getSelected();
                            // Restart each configuration. For the evicted configuration, this means
                            // moving incoming dependencies across to the
                            // matching selected configuration. For the select configuration, this
                            // mean traversing its dependencies.
                            resolveState.getModule(moduleIdentifier).restart(selected);
                          }
                        });
              }
            });
      }
    }
  }