private Collection<List<ModuleVersionIdentifier>> calculatePaths(
        BrokenDependency brokenDependency) {
      // Include the shortest path from each version that has a direct dependency on the broken
      // dependency, back to the root

      Map<ModuleVersionResolveState, List<ModuleVersionIdentifier>> shortestPaths =
          new LinkedHashMap<ModuleVersionResolveState, List<ModuleVersionIdentifier>>();
      List<ModuleVersionIdentifier> rootPath = new ArrayList<ModuleVersionIdentifier>();
      rootPath.add(root.moduleRevision.id);
      shortestPaths.put(root.moduleRevision, rootPath);

      Set<ModuleVersionResolveState> directDependees =
          new LinkedHashSet<ModuleVersionResolveState>();
      for (ConfigurationNode node : brokenDependency.requiredBy) {
        directDependees.add(node.moduleRevision);
      }

      Set<ModuleVersionResolveState> seen = new HashSet<ModuleVersionResolveState>();
      LinkedList<ModuleVersionResolveState> queue = new LinkedList<ModuleVersionResolveState>();
      queue.addAll(directDependees);
      while (!queue.isEmpty()) {
        ModuleVersionResolveState version = queue.getFirst();
        if (version == root.moduleRevision) {
          queue.removeFirst();
        } else if (seen.add(version)) {
          for (ConfigurationNode configuration : version.configurations) {
            for (DependencyEdge dependencyEdge : configuration.incomingEdges) {
              queue.add(0, dependencyEdge.from.moduleRevision);
            }
          }
        } else {
          queue.remove();
          List<ModuleVersionIdentifier> shortest = null;
          for (ConfigurationNode configuration : version.configurations) {
            for (DependencyEdge dependencyEdge : configuration.incomingEdges) {
              List<ModuleVersionIdentifier> candidate =
                  shortestPaths.get(dependencyEdge.from.moduleRevision);
              if (candidate == null) {
                continue;
              }
              if (shortest == null) {
                shortest = candidate;
              } else if (shortest.size() > candidate.size()) {
                shortest = candidate;
              }
            }
          }
          if (shortest == null) {
            continue;
          }
          List<ModuleVersionIdentifier> path = new ArrayList<ModuleVersionIdentifier>();
          path.addAll(shortest);
          path.add(version.id);
          shortestPaths.put(version, path);
        }
      }

      List<List<ModuleVersionIdentifier>> paths = new ArrayList<List<ModuleVersionIdentifier>>();
      for (ModuleVersionResolveState version : directDependees) {
        List<ModuleVersionIdentifier> path = shortestPaths.get(version);
        paths.add(path);
      }
      return paths;
    }