code: public DependencyExplorerOutput explore(GinjectorBindings origin) {
      DependencyExplorerOutput output = new DependencyExplorerOutput();
      DependencyGraph.Builder builder = new DependencyGraph.Builder(origin);
      
      for (Dependency edge : origin.getDependencies()) {
        Preconditions.checkState(
            Dependency.GINJECTOR.equals(edge.getSource()) || origin.isBound(edge.getSource()),
            "Expected non-null source %s to be bound in origin!", edge.getSource());
        builder.addEdge(edge);
        if (!edge.getSource().equals(Dependency.GINJECTOR) && visited.add(edge.getSource())) {
          // Need to register where we can find the "source".  Note that this will be always be
          // available somewhere, because it's already available at the origin (that's how we found
          // this dependency).
          PrettyPrinter.log(logger, TreeLogger.DEBUG,
                "Registering %s as available at %s because of the dependency %s", edge.getSource(),
                origin, edge);
          output.preExistingBindings.put(edge.getSource(), 
              locateHighestAccessibleSource(edge.getSource(), origin));
        }
  
        PrettyPrinter.log(logger, TreeLogger.DEBUG,
            "Exploring from %s in %s because of the dependency %s", edge.getTarget(), origin, edge);
        // Visit the target of the dependency to find additional bindings
        visit(edge.getTarget(), builder, output, origin);
      }
      
      output.setGraph(builder.build());
      return output;
    }
docs: Explore the unresolved dependencies in the origin Ginjector, and create the corresponding
  dependency graph.  Also gathers information about key in the dependency graph, such as which
  Ginjector it is already available on, or what implicit binding was created for it.
  
  @param origin the ginjector to build a dependency graph for