code: private void traceKey(Key<?> key, GinjectorBindings bindings) {
      Binding binding = bindings.getBinding(key);
      // Make sure the binding is present: optional bindings might be missing.
      if (binding != null) {
        if (!reachable.add(binding)) {
          // The binding was already marked as reachable.
          return;
        }
  
        getReachableMemberInjects(bindings).addAll(binding.getMemberInjectRequests());
  
        for (Dependency dependency : binding.getDependencies()) {
          if (dependency.getSource().equals(key)) {
            Key<?> target = dependency.getTarget();
  
            PrettyPrinter.log(logger, TreeLogger.DEBUG, "%s:%s -> %s:%s [%s]",
                bindings, key, bindings, dependency.getTarget(), binding);
            traceKey(target, bindings);
          }
        }
  
        // Special cases: parent / child bindings induce dependencies between
        // GinjectorBindings objects, which can't be represented in the standard
        // dependency graph.
        if (binding instanceof ParentBinding) {
          ParentBinding parentBinding = (ParentBinding) binding;
          PrettyPrinter.log(logger, TreeLogger.DEBUG, "%s:%s -> %s:%s [inherited]",
              bindings, key, parentBinding.getParentBindings(), key);
          traceKey(key, parentBinding.getParentBindings());
        } else if (binding instanceof ExposedChildBinding) {
          ExposedChildBinding exposedChildBinding = (ExposedChildBinding) binding;
          PrettyPrinter.log(logger, TreeLogger.DEBUG, "%s:%s -> %s:%s [exposed]",
              bindings, key, exposedChildBinding.getChildBindings(), key);
          traceKey(key, exposedChildBinding.getChildBindings());
        }
      }
    }
docs: Marks the binding of the given key in the given {@link GinjectorBindings}
  as reachable, and traces out its dependencies.