private static Set<Dependency> collectFromDependencyMonitor(
      ThreadMXBean bean, Serializable locality, Map<Long, ThreadInfo> threadInfos) {
    HashSet<Dependency> results = new HashSet<Dependency>();

    // Convert the held resources into serializable dependencies
    Set<Dependency<Serializable, Thread>> heldResources =
        DependencyMonitorManager.getHeldResources();
    for (Dependency<Serializable, Thread> dep : heldResources) {
      Thread thread = dep.getDependsOn();
      Serializable resource = dep.getDepender();
      ThreadInfo info = threadInfos.get(thread.getId());
      if (info == null) {
        info = bean.getThreadInfo(thread.getId());
      }
      if (info != null) {
        results.add(new Dependency(resource, new LocalThread(locality, info)));
      }
    }

    Set<Dependency<Thread, Serializable>> blockedThreads =
        DependencyMonitorManager.getBlockedThreads();

    // Convert the blocked threads into serializable dependencies
    for (Dependency<Thread, Serializable> dep : blockedThreads) {
      Thread thread = dep.getDepender();
      ThreadInfo info = threadInfos.get(thread.getId());
      if (info == null) {
        info = bean.getThreadInfo(thread.getId());
      }
      final Serializable resource = dep.getDependsOn();
      results.add(new Dependency(new LocalThread(locality, info), resource));
    }
    return results;
  }
  /** Format deadlock displaying to a user. */
  public static String prettyFormat(Collection<Dependency> deadlock) {
    StringBuilder text = new StringBuilder();
    LinkedHashSet<LocalThread> threads = new LinkedHashSet<LocalThread>();

    Set<Object> seenDependers = new HashSet<>();
    Object lastDependsOn = text;
    Object lastDepender = text;

    for (Dependency dep : deadlock) {
      Object depender = dep.getDepender();
      Object dependsOn = dep.getDependsOn();

      String dependerString;
      if (lastDependsOn.equals(depender)) {
        dependerString = "which";
      } else if (lastDepender.equals(depender)) {
        dependerString = "and";
      } else {
        dependerString = String.valueOf(depender);
      }
      lastDepender = depender;
      lastDependsOn = dependsOn;

      String also = seenDependers.contains(depender) ? " also" : "";
      seenDependers.add(depender);

      if (depender instanceof LocalThread) {
        text.append(dependerString)
            .append(" is")
            .append(also)
            .append(" waiting on ")
            .append(dependsOn)
            .append("\n");
        threads.add((LocalThread) depender);
      } else if (dependsOn instanceof LocalThread) {
        text.append(dependerString).append(" is held by thread ").append(dependsOn).append("\n");
        threads.add((LocalThread) dependsOn);
      } else {
        text.append(dependerString)
            .append(" is")
            .append(also)
            .append(" waiting for ")
            .append(dependsOn)
            .append("\n");
      }
      text.append("\n");
    }

    text.append("\nStack traces for involved threads\n");
    for (LocalThread threadInfo : threads) {
      text.append(threadInfo.getLocatility())
          .append(":")
          .append(threadInfo.getThreadStack())
          .append("\n\n");
    }

    return text.toString();
  }