예제 #1
1
 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;
 }
예제 #2
0
  private ModuleDescriptor findProject(DependencyDescriptor descriptor) {
    String projectPathValue = descriptor.getAttribute(DependencyDescriptorFactory.PROJECT_PATH_KEY);
    if (projectPathValue == null) {
      return null;
    }
    Project project = gradle.getRootProject().project(projectPathValue);
    Module projectModule = ((ProjectInternal) project).getModule();
    ModuleDescriptor projectDescriptor =
        moduleDescriptorConverter.convert(
            project.getConfigurations().getAll(),
            projectModule,
            IvyContext.getContext().getIvy().getSettings());

    for (DependencyArtifactDescriptor artifactDescriptor : descriptor.getAllDependencyArtifacts()) {
      for (Artifact artifact : projectDescriptor.getAllArtifacts()) {
        if (artifact.getName().equals(artifactDescriptor.getName())
            && artifact.getExt().equals(artifactDescriptor.getExt())) {
          String path =
              artifact.getExtraAttribute(DefaultIvyDependencyPublisher.FILE_PATH_EXTRA_ATTRIBUTE);
          ReflectionUtil.invoke(
              artifactDescriptor,
              "setExtraAttribute",
              new Object[] {DefaultIvyDependencyPublisher.FILE_PATH_EXTRA_ATTRIBUTE, path});
        }
      }
    }

    return projectDescriptor;
  }
 private void fillModuleDependencies()
     throws IvySettingsNotFoundException, IvySettingsFileReadException {
   final ModuleDescriptor descriptor = ivyManager.getModuleDescriptor(module);
   if (descriptor != null) {
     final DependencyDescriptor[] ivyDependencies = descriptor.getDependencies();
     for (Module dependencyModule :
         IntellijUtils.getAllModulesWithIvyIdeaFacet(module.getProject())) {
       if (!module.equals(dependencyModule)) {
         for (DependencyDescriptor ivyDependency : ivyDependencies) {
           final ModuleId ivyDependencyId = ivyDependency.getDependencyId();
           final ModuleId dependencyModuleId = getModuleId(dependencyModule);
           if (ivyDependencyId.equals(dependencyModuleId)) {
             LOGGER.info(
                 "Recognized dependency "
                     + ivyDependency
                     + " as intellij module '"
                     + dependencyModule.getName()
                     + "' in this project!");
             moduleDependencies.put(dependencyModuleId, dependencyModule);
             break;
           }
         }
       }
     }
   }
 }
예제 #4
0
    public void visitOutgoingDependencies(Collection<DependencyEdge> target) {
      // If this configuration's version is in conflict, don't do anything
      // If not traversed before, add all selected outgoing edges
      // If traversed before, and the selected modules have changed, remove previous outgoing edges
      // and add outgoing edges again with
      //    the new selections.
      // If traversed before, and the selected modules have not changed, ignore
      // If none of the incoming edges are transitive, then the node has no outgoing edges

      if (moduleRevision.state != ModuleState.Selected) {
        LOGGER.debug("version for {} is not selected. ignoring.", this);
        return;
      }

      List<DependencyEdge> transitiveIncoming = new ArrayList<DependencyEdge>();
      for (DependencyEdge edge : incomingEdges) {
        if (edge.isTransitive()) {
          transitiveIncoming.add(edge);
        }
      }

      if (transitiveIncoming.isEmpty() && this != resolveState.root) {
        if (previousTraversal != null) {
          removeOutgoingEdges();
        }
        if (incomingEdges.isEmpty()) {
          LOGGER.debug("{} has no incoming edges. ignoring.", this);
        } else {
          LOGGER.debug("{} has no transitive incoming edges. ignoring outgoing edges.", this);
        }
        return;
      }

      ModuleVersionSpec selectorSpec = getSelector(transitiveIncoming);
      if (previousTraversal != null) {
        if (previousTraversal.acceptsSameModulesAs(selectorSpec)) {
          LOGGER.debug(
              "Changed edges for {} selects same versions as previous traversal. ignoring", this);
          return;
        }
        removeOutgoingEdges();
      }

      for (DependencyMetaData dependency : metaData.getDependencies()) {
        DependencyDescriptor dependencyDescriptor = dependency.getDescriptor();
        ModuleId targetModuleId = dependencyDescriptor.getDependencyRevisionId().getModuleId();
        if (!selectorSpec.isSatisfiedBy(targetModuleId)) {
          LOGGER.debug("{} is excluded from {}.", targetModuleId, this);
          continue;
        }
        DependencyEdge dependencyEdge =
            new DependencyEdge(this, dependency, selectorSpec, resolveState);
        outgoingEdges.add(dependencyEdge);
        target.add(dependencyEdge);
      }
      previousTraversal = selectorSpec;
    }
예제 #5
0
 public ModuleVersionSpec getSelector() {
   String[] configurations =
       from.metaData.getHierarchy().toArray(new String[from.metaData.getHierarchy().size()]);
   ModuleVersionSpec selector =
       ModuleVersionSpec.forExcludes(dependencyDescriptor.getExcludeRules(configurations));
   return selector.intersect(selectorSpec);
 }
 public void getDependency(
     DependencyDescriptor dependencyDescriptor, BuildableModuleVersionDescriptor result) {
   result.failed(
       new ModuleVersionResolveException(
           dependencyDescriptor.getDependencyRevisionId(),
           "No cached version of %s available for offline mode."));
 }
 private void collectTargetConfiguration(
     DependencyDescriptor dependencyDescriptor,
     ConfigurationMetaData fromConfiguration,
     String mappingRhs,
     ModuleDescriptor targetModule,
     Collection<String> targetConfigs) {
   String[] dependencyConfigurations =
       dependencyDescriptor.getDependencyConfigurations(mappingRhs, fromConfiguration.getName());
   for (String target : dependencyConfigurations) {
     String candidate = target;
     int startFallback = candidate.indexOf('(');
     if (startFallback >= 0) {
       if (candidate.charAt(candidate.length() - 1) == ')') {
         String preferred = candidate.substring(0, startFallback);
         if (targetModule.getConfiguration(preferred) != null) {
           targetConfigs.add(preferred);
           continue;
         }
         candidate = candidate.substring(startFallback + 1, candidate.length() - 1);
       }
     }
     if (candidate.equals("*")) {
       Collections.addAll(targetConfigs, targetModule.getPublicConfigurationsNames());
       continue;
     }
     targetConfigs.add(candidate);
   }
 }
 /**
  * Return true if this module match the DependencyDescriptor with the given versionMatcher. If
  * this module has no version defined, then true is always returned.
  */
 public boolean match(DependencyDescriptor descriptor, VersionMatcher versionMatcher) {
   ModuleDescriptor md = module;
   return md.getResolvedModuleRevisionId().getRevision() == null
       || md.getResolvedModuleRevisionId().getRevision().equals(Ivy.getWorkingRevision())
       || versionMatcher.accept(descriptor.getDependencyRevisionId(), md);
   // Checking md.getResolvedModuleRevisionId().getRevision().equals(Ivy.getWorkingRevision()
   // allow to consider any local non resolved ivy.xml
   // as a valid module.
 }
  // TODO - don't pass in 'from' configuration - the dependency should have whatever context it
  // needs
  public Set<ConfigurationMetaData> resolveTargetConfigurations(
      DependencyMetaData dependencyMetaData,
      ConfigurationMetaData fromConfiguration,
      ModuleVersionMetaData targetModuleVersion) {
    // TODO - resolve directly to config meta data
    ModuleDescriptor targetDescriptor = targetModuleVersion.getDescriptor();
    DependencyDescriptor dependencyDescriptor = dependencyMetaData.getDescriptor();
    Set<String> targetConfigurationNames = new LinkedHashSet<String>();
    for (String config : dependencyDescriptor.getModuleConfigurations()) {
      if (config.equals("*") || config.equals("%")) {
        collectTargetConfiguration(
            dependencyDescriptor,
            fromConfiguration,
            fromConfiguration.getName(),
            targetDescriptor,
            targetConfigurationNames);
      } else if (fromConfiguration.getHierarchy().contains(config)) {
        collectTargetConfiguration(
            dependencyDescriptor,
            fromConfiguration,
            config,
            targetDescriptor,
            targetConfigurationNames);
      }
    }

    Set<ConfigurationMetaData> targets = new LinkedHashSet<ConfigurationMetaData>();
    for (String targetConfigurationName : targetConfigurationNames) {
      // TODO - move this down below
      if (targetDescriptor.getConfiguration(targetConfigurationName) == null) {
        throw new RuntimeException(
            String.format(
                "Module version %s, configuration '%s' declares a dependency on configuration '%s' which is not declared in the module descriptor for %s",
                fromConfiguration.getModuleVersion().getId(),
                fromConfiguration.getName(),
                targetConfigurationName,
                targetModuleVersion.getId()));
      }
      ConfigurationMetaData targetConfiguration =
          targetModuleVersion.getConfiguration(targetConfigurationName);
      targets.add(targetConfiguration);
    }
    return targets;
  }
예제 #10
0
  protected boolean shouldReturnResolvedModule(DependencyDescriptor dd, ResolvedModuleRevision mr) {
    // a resolved module revision has already been found by a prior dependency resolver
    // let's see if it should be returned and bypass this resolver

    ModuleRevisionId mrid = dd.getDependencyRevisionId();
    boolean isDynamic = getSettings().getVersionMatcher().isDynamic(mrid);
    boolean shouldReturn = mr.isForce();
    shouldReturn |= !isDynamic && !mr.getDescriptor().isDefault();
    shouldReturn &= !isForce();

    return shouldReturn;
  }
예제 #11
0
 private DependencyDescriptor enrichDependencyDescriptorWithSnapshotVersionInfo(
     DependencyDescriptor dd,
     ModuleRevisionId dependencyRevisionId,
     String uniqueSnapshotVersion) {
   Map<String, String> extraAttributes = new HashMap<String, String>(1);
   extraAttributes.put("timestamp", uniqueSnapshotVersion);
   final ModuleRevisionId newModuleRevisionId =
       ModuleRevisionId.newInstance(
           dependencyRevisionId.getOrganisation(),
           dependencyRevisionId.getName(),
           dependencyRevisionId.getRevision(),
           extraAttributes);
   return dd.clone(newModuleRevisionId);
 }
예제 #12
0
  protected ResolvedArtifact findIvyFileRef(DependencyDescriptor dd) {
    if (isUsepoms()) {
      ModuleRevisionId moduleRevisionId = dd.getDependencyRevisionId();
      ArtifactRevisionId artifactRevisionId =
          ArtifactRevisionId.newInstance(
              moduleRevisionId,
              moduleRevisionId.getName(),
              "pom",
              "pom",
              moduleRevisionId.getExtraAttributes());
      Artifact pomArtifact = new DefaultArtifact(artifactRevisionId, null, null, true);
      return findResourceUsingPatterns(moduleRevisionId, getIvyPatterns(), pomArtifact, true);
    }

    return null;
  }
예제 #13
0
 private void getSnapshotDependency(
     DependencyDescriptor dd, BuildableModuleVersionMetaDataResolveResult result) {
   final ModuleRevisionId dependencyRevisionId = dd.getDependencyRevisionId();
   final String uniqueSnapshotVersion = findUniqueSnapshotVersion(dependencyRevisionId);
   if (uniqueSnapshotVersion != null) {
     DependencyDescriptor enrichedDependencyDescriptor =
         enrichDependencyDescriptorWithSnapshotVersionInfo(
             dd, dependencyRevisionId, uniqueSnapshotVersion);
     super.getDependency(enrichedDependencyDescriptor, result);
     if (result.getState() == BuildableModuleVersionMetaDataResolveResult.State.Resolved) {
       result.setModuleSource(new TimestampedModuleSource(uniqueSnapshotVersion));
     }
   } else {
     super.getDependency(dd, result);
   }
 }
예제 #14
0
  public ResolvedModuleRevision parse(
      final ResolvedResource mdRef, DependencyDescriptor dd, ResolveData data)
      throws ParseException {

    DependencyDescriptor nsDd = dd;
    dd = toSystem(nsDd);

    ModuleRevisionId mrid = dd.getDependencyRevisionId();
    ModuleDescriptorParser parser =
        ModuleDescriptorParserRegistry.getInstance().getParser(mdRef.getResource());
    if (parser == null) {
      Message.warn("no module descriptor parser available for " + mdRef.getResource());
      return null;
    }
    Message.verbose("\t" + getName() + ": found md file for " + mrid);
    Message.verbose("\t\t=> " + mdRef);
    Message.debug("\tparser = " + parser);

    ModuleRevisionId resolvedMrid = mrid;

    // first check if this dependency has not yet been resolved
    if (getSettings().getVersionMatcher().isDynamic(mrid)) {
      resolvedMrid = ModuleRevisionId.newInstance(mrid, mdRef.getRevision());
      IvyNode node = data.getNode(resolvedMrid);
      if (node != null && node.getModuleRevision() != null) {
        // this revision has already be resolved : return it
        if (node.getDescriptor() != null && node.getDescriptor().isDefault()) {
          Message.verbose(
              "\t"
                  + getName()
                  + ": found already resolved revision: "
                  + resolvedMrid
                  + ": but it's a default one, maybe we can find a better one");
        } else {
          Message.verbose("\t" + getName() + ": revision already resolved: " + resolvedMrid);
          node.getModuleRevision().getReport().setSearched(true);
          return node.getModuleRevision();
        }
      }
    }

    Artifact moduleArtifact = parser.getMetadataArtifact(resolvedMrid, mdRef.getResource());
    return getRepositoryCacheManager()
        .cacheModuleDescriptor(this, mdRef, dd, moduleArtifact, downloader, getCacheOptions(data));
  }
예제 #15
0
  public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data)
      throws ParseException {
    IvyContext context = IvyContext.pushNewCopyContext();
    try {
      ResolvedModuleRevision mr = data.getCurrentResolvedModuleRevision();
      if (mr != null) {
        if (shouldReturnResolvedModule(dd, mr)) {
          return mr;
        }
      }

      if (isForce()) {
        dd =
            dd.clone(
                ModuleRevisionId.newInstance(dd.getDependencyRevisionId(), "latest.integration"));
      }
      DependencyDescriptor systemDd = dd;
      DependencyDescriptor nsDd = fromSystem(dd);
      context.setDependencyDescriptor(systemDd);
      context.setResolveData(data);

      clearIvyAttempts();
      clearArtifactAttempts();
      ModuleRevisionId systemMrid = systemDd.getDependencyRevisionId();
      ModuleRevisionId nsMrid = nsDd.getDependencyRevisionId();

      checkRevision(systemMrid);

      boolean isDynamic = getAndCheckIsDynamic(systemMrid);

      // we first search for the dependency in cache
      ResolvedModuleRevision rmr = null;
      rmr = findModuleInCache(systemDd, data);
      if (rmr != null) {
        if (rmr.getDescriptor().isDefault() && rmr.getResolver() != this) {
          Message.verbose(
              "\t"
                  + getName()
                  + ": found revision in cache: "
                  + systemMrid
                  + " (resolved by "
                  + rmr.getResolver().getName()
                  + "): but it's a default one, maybe we can find a better one");
        } else if (isForce() && rmr.getResolver() != this) {
          Message.verbose(
              "\t"
                  + getName()
                  + ": found revision in cache: "
                  + systemMrid
                  + " (resolved by "
                  + rmr.getResolver().getName()
                  + "): but we are in force mode, let's try to find one ourself");
        } else {
          Message.verbose("\t" + getName() + ": revision in cache: " + systemMrid);
          return checkLatest(systemDd, checkForcedResolvedModuleRevision(rmr), data);
        }
      }
      if (data.getOptions().isUseCacheOnly()) {
        throw new UnresolvedDependencyException(
            "\t" + getName() + " (useCacheOnly) : no ivy file found for " + systemMrid, false);
      }

      checkInterrupted();

      ResolvedResource ivyRef = findIvyFileRef(nsDd, data);
      checkInterrupted();

      // get module descriptor
      ModuleDescriptor nsMd;
      ModuleDescriptor systemMd = null;
      if (ivyRef == null) {
        if (!isAllownomd()) {
          throw new UnresolvedDependencyException(
              "\t" + getName() + ": no ivy file found for " + systemMrid, false);
        }
        nsMd = DefaultModuleDescriptor.newDefaultInstance(nsMrid, nsDd.getAllDependencyArtifacts());
        ResolvedResource artifactRef = findFirstArtifactRef(nsMd, nsDd, data);
        checkInterrupted();
        if (artifactRef == null) {
          throw new UnresolvedDependencyException(
              "\t" + getName() + ": no ivy file nor artifact found for " + systemMrid, false);
        } else {
          long lastModified = artifactRef.getLastModified();
          if (lastModified != 0 && nsMd instanceof DefaultModuleDescriptor) {
            ((DefaultModuleDescriptor) nsMd).setLastModified(lastModified);
          }
          Message.verbose(
              "\t" + getName() + ": no ivy file found for " + systemMrid + ": using default data");
          if (isDynamic) {
            nsMd.setResolvedModuleRevisionId(
                ModuleRevisionId.newInstance(nsMrid, artifactRef.getRevision()));
          }
          systemMd = toSystem(nsMd);
          MetadataArtifactDownloadReport madr =
              new MetadataArtifactDownloadReport(systemMd.getMetadataArtifact());
          madr.setDownloadStatus(DownloadStatus.NO);
          madr.setSearched(true);
          rmr = new ResolvedModuleRevision(this, this, systemMd, madr, isForce());
          getRepositoryCacheManager()
              .cacheModuleDescriptor(
                  this,
                  artifactRef,
                  toSystem(dd),
                  systemMd.getAllArtifacts()[0],
                  null,
                  getCacheOptions(data));
        }
      } else {
        if (ivyRef instanceof MDResolvedResource) {
          rmr = ((MDResolvedResource) ivyRef).getResolvedModuleRevision();
        }
        if (rmr == null) {
          rmr = parse(ivyRef, systemDd, data);
          if (rmr == null) {
            throw new UnresolvedDependencyException();
          }
        }
        if (!rmr.getReport().isDownloaded() && rmr.getReport().getLocalFile() != null) {
          return checkLatest(systemDd, checkForcedResolvedModuleRevision(rmr), data);
        } else {
          nsMd = rmr.getDescriptor();

          // check descriptor data is in sync with resource revision and names
          systemMd = toSystem(nsMd);
          if (isCheckconsistency()) {
            checkDescriptorConsistency(systemMrid, systemMd, ivyRef);
            checkDescriptorConsistency(nsMrid, nsMd, ivyRef);
          } else {
            if (systemMd instanceof DefaultModuleDescriptor) {
              DefaultModuleDescriptor defaultMd = (DefaultModuleDescriptor) systemMd;
              ModuleRevisionId revision = getRevision(ivyRef, systemMrid, systemMd);
              defaultMd.setModuleRevisionId(revision);
              defaultMd.setResolvedModuleRevisionId(revision);
            } else {
              Message.warn(
                  "consistency disabled with instance of non DefaultModuleDescriptor..."
                      + " module info can't be updated, so consistency check will be done");
              checkDescriptorConsistency(nsMrid, nsMd, ivyRef);
              checkDescriptorConsistency(systemMrid, systemMd, ivyRef);
            }
          }
          rmr =
              new ResolvedModuleRevision(
                  this, this, systemMd, toSystem(rmr.getReport()), isForce());
        }
      }

      resolveAndCheckRevision(systemMd, systemMrid, ivyRef, isDynamic);
      resolveAndCheckPublicationDate(systemDd, systemMd, systemMrid, data);
      checkNotConvertedExclusionRule(systemMd, ivyRef, data);

      if (ivyRef == null || ivyRef.getResource() != null) {
        cacheModuleDescriptor(systemMd, systemMrid, ivyRef, rmr);
      }

      return checkLatest(systemDd, checkForcedResolvedModuleRevision(rmr), data);
    } catch (UnresolvedDependencyException ex) {
      if (ex.getMessage().length() > 0) {
        if (ex.isError()) {
          Message.error(ex.getMessage());
        } else {
          Message.verbose(ex.getMessage());
        }
      }
      return data.getCurrentResolvedModuleRevision();
    } finally {
      IvyContext.popContext();
    }
  }
예제 #16
0
 private boolean isSnapshotVersion(DependencyDescriptor dd) {
   return dd.getDependencyRevisionId().getRevision().endsWith("SNAPSHOT");
 }
예제 #17
0
  /**
   * When the resolver has many choices, this function helps choosing one
   *
   * @param rress the list of resolved resource which the resolver found to fit the requirement
   * @param rmdparser the parser of module descriptor
   * @param mrid the module being resolved
   * @param date the current date
   * @return the selected resource
   */
  public ResolvedResource findResource(
      ResolvedResource[] rress, ResourceMDParser rmdparser, ModuleRevisionId mrid, Date date) {
    String name = getName();
    VersionMatcher versionMatcher = getSettings().getVersionMatcher();

    ResolvedResource found = null;
    List sorted = getLatestStrategy().sort(rress);
    List rejected = new ArrayList();
    List foundBlacklisted = new ArrayList();
    IvyContext context = IvyContext.getContext();

    for (ListIterator iter = sorted.listIterator(sorted.size()); iter.hasPrevious(); ) {
      ResolvedResource rres = (ResolvedResource) iter.previous();
      // we start by filtering based on information already available,
      // even though we don't even know if the resource actually exist.
      // But checking for existence is most of the time more costly than checking
      // name, blacklisting and first level version matching
      if (filterNames(new ArrayList(Collections.singleton(rres.getRevision()))).isEmpty()) {
        Message.debug("\t" + name + ": filtered by name: " + rres);
        continue;
      }
      ModuleRevisionId foundMrid = ModuleRevisionId.newInstance(mrid, rres.getRevision());

      ResolveData data = context.getResolveData();
      if (data != null
          && data.getReport() != null
          && data.isBlacklisted(data.getReport().getConfiguration(), foundMrid)) {
        Message.debug("\t" + name + ": blacklisted: " + rres);
        rejected.add(rres.getRevision() + " (blacklisted)");
        foundBlacklisted.add(foundMrid);
        continue;
      }

      if (!versionMatcher.accept(mrid, foundMrid)) {
        Message.debug("\t" + name + ": rejected by version matcher: " + rres);
        rejected.add(rres.getRevision());
        continue;
      }
      if (rres.getResource() != null && !rres.getResource().exists()) {
        Message.debug("\t" + name + ": unreachable: " + rres + "; res=" + rres.getResource());
        rejected.add(rres.getRevision() + " (unreachable)");
        continue;
      }
      if ((date != null && rres.getLastModified() > date.getTime())) {
        Message.verbose("\t" + name + ": too young: " + rres);
        rejected.add(rres.getRevision() + " (" + rres.getLastModified() + ")");
        continue;
      }
      if (versionMatcher.needModuleDescriptor(mrid, foundMrid)) {
        ResolvedResource r = rmdparser.parse(rres.getResource(), rres.getRevision());
        if (r == null) {
          Message.debug("\t" + name + ": impossible to get module descriptor resource: " + rres);
          rejected.add(rres.getRevision() + " (no or bad MD)");
          continue;
        }
        ModuleDescriptor md = ((MDResolvedResource) r).getResolvedModuleRevision().getDescriptor();
        if (md.isDefault()) {
          Message.debug(
              "\t"
                  + name
                  + ": default md rejected by version matcher"
                  + "requiring module descriptor: "
                  + rres);
          rejected.add(rres.getRevision() + " (MD)");
          continue;
        } else if (!versionMatcher.accept(mrid, md)) {
          Message.debug("\t" + name + ": md rejected by version matcher: " + rres);
          rejected.add(rres.getRevision() + " (MD)");
          continue;
        } else {
          found = r;
        }
      } else {
        found = rres;
      }

      if (found != null) {
        break;
      }
    }
    if (found == null && !rejected.isEmpty()) {
      logAttempt(rejected.toString());
    }
    if (found == null && !foundBlacklisted.isEmpty()) {
      // all acceptable versions have been blacklisted, this means that an unsolvable conflict
      // has been found
      DependencyDescriptor dd = context.getDependencyDescriptor();
      IvyNode parentNode = context.getResolveData().getNode(dd.getParentRevisionId());
      ConflictManager cm = parentNode.getConflictManager(mrid.getModuleId());
      cm.handleAllBlacklistedRevisions(dd, foundBlacklisted);
    }

    return found;
  }