compiler/src/main/java/dagger/internal/codegen/Util.java
public static ExecutableElement getNoArgsConstructor(TypeElement type) {
  for (Element enclosed : type.getEnclosedElements()) {
    if (enclosed.getKind() != ElementKind.CONSTRUCTOR) {
      continue;
    }
    ExecutableElement constructor = (ExecutableElement) enclosed;
    if (constructor.getParameters().isEmpty()) {
      return constructor;
    }
  }
  return null;
}
compiler/src/main/java/dagger/internal/codegen/Util.java
public static boolean isCallableConstructor(ExecutableElement constructor) {
  if (constructor.getModifiers().contains(Modifier.PRIVATE)) {
    return false;
  }
  TypeElement type = (TypeElement) constructor.getEnclosingElement();
  return type.getEnclosingElement().getKind() == ElementKind.PACKAGE
      || type.getModifiers().contains(Modifier.STATIC);
}
compiler/src/main/java/dagger/internal/codegen/Util.java
public static TypeName injectableType(TypeMirror type) {
  return type.accept(new SimpleTypeVisitor6<TypeName, Void>() {
    @Override public TypeName visitPrimitive(PrimitiveType primitiveType, Void v) {
      return box(primitiveType);
    }

    @Override public TypeName visitError(ErrorType errorType, Void v) {
      // Error type found, a type may not yet have been generated, but we need the type
      // so we can generate the correct code in anticipation of the type being available
      // to the compiler.

      // Paramterized types which don't exist are returned as an error type whose name is "<any>"
      if ("<any>".equals(errorType.toString())) {
        throw new CodeGenerationIncompleteException(
            "Type reported as <any> is likely a not-yet generated parameterized type.");
      }

      return ClassName.bestGuess(errorType.toString());
    }

    @Override protected TypeName defaultAction(TypeMirror typeMirror, Void v) {
      return TypeName.get(typeMirror);
    }
  }, null);
}
compiler/src/main/java/dagger/internal/codegen/Util.java
public static PackageElement getPackage(Element type) {
  while (type.getKind() != ElementKind.PACKAGE) {
    type = type.getEnclosingElement();
  }
  return (PackageElement) type;
}
compiler/src/main/java/dagger/internal/codegen/Util.java
public static String rawTypeToString(TypeMirror type, char innerClassSeparator) {
  if (!(type instanceof DeclaredType)) {
    throw new IllegalArgumentException("Unexpected type: " + type);
  }
  StringBuilder result = new StringBuilder();
  DeclaredType declaredType = (DeclaredType) type;
  rawTypeToString(result, (TypeElement) declaredType.asElement(), innerClassSeparator);
  return result.toString();
}
core/src/main/java/dagger/ObjectGraph.java
public abstract class ObjectGraph {
  ObjectGraph() {
  }

  /**
   * Returns an instance of {@code type}.
   *
   * @throws IllegalArgumentException if {@code type} is not one of this object
   *     graph's {@link Module#injects injectable types}.
   */
  public abstract <T> T get(Class<T> type);

  /**
   * Injects the members of {@code instance}, including injectable members
   * inherited from its supertypes.
   *
   * @throws IllegalArgumentException if the runtime type of {@code instance} is
   *     not one of this object graph's {@link Module#injects injectable types}.
   */
  public abstract <T> T inject(T instance);

  /**
   * Returns a new object graph that includes all of the objects in this graph,
   * plus additional objects in the {@literal @}{@link Module}-annotated
   * modules. This graph is a subgraph of the returned graph.
   *
   * <p>The current graph is not modified by this operation: its objects and the
   * dependency links between them are unchanged. But this graph's objects may
   * be shared by both graphs. For example, the singletons of this graph may be
   * injected and used by the returned graph.
   *
   * <p>This <strong>does not</strong> inject any members or validate the graph.
   * See {@link #create} for guidance on injection and validation.
   */
  public abstract ObjectGraph plus(Object... modules);

  /**
   * Do runtime graph problem detection. For fastest graph creation, rely on
   * build time tools for graph validation.
   *
   * @throws IllegalStateException if this graph has problems.
   */
  public abstract void validate();

  /**
   * Injects the static fields of the classes listed in the object graph's
   * {@code staticInjections} property.
   */
  public abstract void injectStatics();

  /**
   * Returns a new dependency graph using the {@literal @}{@link
   * Module}-annotated modules.
   *
   * <p>This <strong>does not</strong> inject any members. Most applications
   * should call {@link #injectStatics} to inject static members and {@link
   * #inject} or get {@link #get(Class)} to inject instance members when this
   * method has returned.
   *
   * <p>This <strong>does not</strong> validate the graph. Rely on build time
   * tools for graph validation, or call {@link #validate} to find problems in
   * the graph at runtime.
   */
  public static ObjectGraph create(Object... modules) {
    return DaggerObjectGraph.makeGraph(null, new FailoverLoader(), modules);
  }

  // visible for testing
  static ObjectGraph createWith(Loader loader, Object... modules) {
    return DaggerObjectGraph.makeGraph(null, loader, modules);
  }

  // TODO(cgruber): Move this internal implementation of ObjectGraph into the internal package.
  static class DaggerObjectGraph extends ObjectGraph {
    private final DaggerObjectGraph base;
    private final Linker linker;
    private final Loader plugin;
    private final Map<Class<?>, StaticInjection> staticInjections;
    private final Map<String, Class<?>> injectableTypes;
    private final List<SetBinding<?>> setBindings;

    DaggerObjectGraph(DaggerObjectGraph base,
        Linker linker,
        Loader plugin,
        Map<Class<?>, StaticInjection> staticInjections,
        Map<String, Class<?>> injectableTypes,
        List<SetBinding<?>> setBindings) {

      this.base = base;
      this.linker = checkNotNull(linker, "linker");
      this.plugin = checkNotNull(plugin, "plugin");
      this.staticInjections = checkNotNull(staticInjections, "staticInjections");
      this.injectableTypes = checkNotNull(injectableTypes, "injectableTypes");
      this.setBindings = checkNotNull(setBindings, "setBindings");
    }

    private static <T> T checkNotNull(T object, String label) {
      if (object == null) throw new NullPointerException(label);
      return object;
    }

    static ObjectGraph makeGraph(DaggerObjectGraph base, Loader plugin, Object... modules) {
      Map<String, Class<?>> injectableTypes = new LinkedHashMap<String, Class<?>>();
      Map<Class<?>, StaticInjection> staticInjections
          = new LinkedHashMap<Class<?>, StaticInjection>();
      StandardBindings baseBindings =
          (base == null) ? new StandardBindings() : new StandardBindings(base.setBindings);
      BindingsGroup overrideBindings = new OverridesBindings();

      Map<ModuleAdapter<?>, Object> loadedModules = Modules.loadModules(plugin, modules);
      for (Entry<ModuleAdapter<?>, Object> loadedModule : loadedModules.entrySet()) {
        ModuleAdapter<Object> moduleAdapter = (ModuleAdapter<Object>) loadedModule.getKey();
        for (int i = 0; i < moduleAdapter.injectableTypes.length; i++) {
          injectableTypes.put(moduleAdapter.injectableTypes[i], moduleAdapter.moduleClass);
        }
        for (int i = 0; i < moduleAdapter.staticInjections.length; i++) {
          staticInjections.put(moduleAdapter.staticInjections[i], null);
        }
        try {
          BindingsGroup addTo = moduleAdapter.overrides ? overrideBindings : baseBindings;
          moduleAdapter.getBindings(addTo, loadedModule.getValue());
        } catch (IllegalArgumentException e) {
          throw new IllegalArgumentException(
              moduleAdapter.moduleClass.getSimpleName() + ": " + e.getMessage(), e);
        }
      }

      // Create a linker and install all of the user's bindings
      Linker linker =
          new Linker((base != null) ? base.linker : null, plugin, new ThrowingErrorHandler());
      linker.installBindings(baseBindings);
      linker.installBindings(overrideBindings);

      return new DaggerObjectGraph(
          base, linker, plugin, staticInjections, injectableTypes, baseBindings.setBindings);
    }

    @Override public ObjectGraph plus(Object... modules) {
      linkEverything();
      return makeGraph(this, plugin, modules);
    }

    private void linkStaticInjections() {
      for (Map.Entry<Class<?>, StaticInjection> entry : staticInjections.entrySet()) {
        StaticInjection staticInjection = entry.getValue();
        if (staticInjection == null) {
          staticInjection = plugin.getStaticInjection(entry.getKey());
          entry.setValue(staticInjection);
        }
        staticInjection.attach(linker);
      }
    }

    private void linkInjectableTypes() {
      for (Map.Entry<String, Class<?>> entry : injectableTypes.entrySet()) {
        linker.requestBinding(entry.getKey(), entry.getValue(), entry.getValue().getClassLoader(),
            false, true);
      }
    }

    @Override public void validate() {
      Map<String, Binding<?>> allBindings = linkEverything();
      new ProblemDetector().detectProblems(allBindings.values());
    }

    /**
     * Links all bindings, injectable types and static injections.
     */
    private Map<String, Binding<?>> linkEverything() {
      Map<String, Binding<?>> bindings = linker.fullyLinkedBindings();
      if (bindings != null) {
        return bindings;
      }
      synchronized (linker) {
        if ((bindings = linker.fullyLinkedBindings()) != null) {
          return bindings;
        }
        linkStaticInjections();
        linkInjectableTypes();
        return linker.linkAll(); // Linker.linkAll() implicitly does Linker.linkRequested().
      }
    }

    @Override public void injectStatics() {
      // We call linkStaticInjections() twice on purpose. The first time through
      // we request all of the bindings we need. The linker returns null for
      // bindings it doesn't have. Then we ask the linker to link all of those
      // requested bindings. Finally we call linkStaticInjections() again: this
      // time the linker won't return null because everything has been linked.
      synchronized (linker) {
        linkStaticInjections();
        linker.linkRequested();
        linkStaticInjections();
      }

      for (Map.Entry<Class<?>, StaticInjection> entry : staticInjections.entrySet()) {
        entry.getValue().inject();
      }
    }

    @Override public <T> T get(Class<T> type) {
      String key = Keys.get(type);
      String injectableTypeKey = type.isInterface() ? key : Keys.getMembersKey(type);
      ClassLoader classLoader = type.getClassLoader();
      @SuppressWarnings("unchecked") // The linker matches keys to bindings by their type.
      Binding<T> binding =
          (Binding<T>) getInjectableTypeBinding(classLoader, injectableTypeKey, key);
      return binding.get();
    }

    @Override public <T> T inject(T instance) {
      String membersKey = Keys.getMembersKey(instance.getClass());
      ClassLoader classLoader = instance.getClass().getClassLoader();
      @SuppressWarnings("unchecked") // The linker matches keys to bindings by their type.
      Binding<T> binding =
          (Binding<T>) getInjectableTypeBinding(classLoader, membersKey, membersKey);
      binding.injectMembers(instance);
      return instance;
    }

    /**
     * @param classLoader the {@code ClassLoader} used to load dependent bindings.
     * @param injectableKey the key used to store the injectable type. This
     *     is a provides key for interfaces and a members injection key for
     *     other types. That way keys can always be created, even if the type
     *     has no injectable constructor.
     * @param key the key to use when retrieving the binding. This may be a
     *     regular (provider) key or a members key.
     */
    private Binding<?> getInjectableTypeBinding(
        ClassLoader classLoader, String injectableKey, String key) {
      Class<?> moduleClass = null;
      for (DaggerObjectGraph graph = this; graph != null; graph = graph.base) {
        moduleClass = graph.injectableTypes.get(injectableKey);
        if (moduleClass != null) break;
      }
      if (moduleClass == null) {
        throw new IllegalArgumentException("No inject registered for " + injectableKey
            + ". You must explicitly add it to the 'injects' option in one of your modules.");
      }

      synchronized (linker) {
        Binding<?> binding = linker.requestBinding(key, moduleClass, classLoader, false, true);
        if (binding == null || !binding.isLinked()) {
          linker.linkRequested();
          binding = linker.requestBinding(key, moduleClass, classLoader, false, true);
        }
        return binding;
      }
    }
  }


  /**
   * A BindingsGroup which fails when existing values are clobbered and sets aside
   * {@link SetBinding}.
   */
  private static final class StandardBindings extends BindingsGroup {
    private final List<SetBinding<?>> setBindings;

    public StandardBindings() {
      setBindings = new ArrayList<SetBinding<?>>();
    }

    public StandardBindings(List<SetBinding<?>> baseSetBindings) {
      setBindings = new ArrayList<SetBinding<?>>(baseSetBindings.size());
      for (SetBinding<?> sb : baseSetBindings) {
        @SuppressWarnings({ "rawtypes", "unchecked" })
        SetBinding<?> child = new SetBinding(sb);
        setBindings.add(child);
        put(child.provideKey, child);
      }
    }

    @Override public Binding<?> contributeSetBinding(String key, SetBinding<?> value) {
      setBindings.add(value);
      return super.put(key, value);
    }
  }

  /**
   * A BindingsGroup which throws an {@link IllegalArgumentException} when a
   * {@link SetBinding} is contributed, since overrides modules cannot contribute such
   * bindings.
   */
  private static final class OverridesBindings extends BindingsGroup {
    OverridesBindings() { }

    @Override public Binding<?> contributeSetBinding(String key, SetBinding<?> value) {
      throw new IllegalArgumentException("Module overrides cannot contribute set bindings.");
    }
  }
}
compiler/src/main/java/dagger/internal/codegen/Util.java
public static TypeMirror getApplicationSupertype(TypeElement type) {
  TypeMirror supertype = type.getSuperclass();
  return Keys.isPlatformType(supertype.toString()) ? null : supertype;
}
compiler/src/main/java/dagger/internal/codegen/Util.java
public static ClassName adapterName(ClassName type, String suffix) {
  return ClassName.get(type.packageName(),
      Joiner.on('$').join(type.simpleNames()) + suffix);
}
core/src/main/java/dagger/internal/Binding.java
public abstract class Binding<T> implements Provider<T>, MembersInjector<T> {
  public static final Binding<Object> UNRESOLVED = new Binding<Object>(null, null, false, null) {
    @Override public Object get() {
      throw new AssertionError("Unresolved binding should never be called to inject.");
    }
    @Override public void injectMembers(Object t) {
      throw new AssertionError("Unresolved binding should never be called to inject.");
    }
  };
  protected static final boolean IS_SINGLETON = true;
  protected static final boolean NOT_SINGLETON = false;

  /** Set if the provided instance is always the same object. */
  private static final int SINGLETON = 1 << 0;

  /** Set if this binding's {@link #attach} completed without any missing dependencies. */
  private static final int LINKED = 1 << 1;

  /** Set if {@link ProblemDetector} is actively visiting this binding. */
  private static final int VISITING = 1 << 2;

  /** Set if {@link ProblemDetector} has confirmed this binding has no circular dependencies. */
  private static final int CYCLE_FREE = 1 << 3;

  private static final int DEPENDED_ON = 1 << 4;

  private static final int LIBRARY = 1 << 5;

  /** The key used to provide instances of 'T', or null if this binding cannot provide instances. */
  public final String provideKey;

  /** The key used to inject members of 'T', or null if this binding cannot inject members. */
  public final String membersKey;

  /** Bitfield of states like SINGLETON and LINKED. */
  private int bits;

  public final Object requiredBy;

  protected Binding(String provideKey, String membersKey, boolean singleton, Object requiredBy) {
    if (singleton && provideKey == null) {
      throw new InvalidBindingException(Keys.getClassName(membersKey),
          "is exclusively members injected and therefore cannot be scoped");
    }
    this.provideKey = provideKey;
    this.membersKey = membersKey;
    this.requiredBy = requiredBy;
    this.bits = (singleton ? SINGLETON : 0);
  }

  /**
   * Links this binding to its dependencies.
   */
  public void attach(Linker linker) {
  }

  @Override public void injectMembers(T t) {
    // If no members to inject, no-op.  Some classes will have no injectable members even
    // if their supertypes do.
  }

  @Override public T get() {
    throw new UnsupportedOperationException("No injectable constructor on " + getClass().getName());
  }

  /**
   * Populates {@code getBindings} and {@code injectMembersBindings} with the
   * bindings used by this binding to satisfy {@link #get} and {@link
   * #injectMembers} calls, respectively.
   *
   * @param getBindings the bindings required by this binding's {@code get}
   *     method. Although {@code get} usually calls into {@code injectMembers},
   *     this <i>does not</i> contain the injectMembers bindings.
   * @param injectMembersBindings the bindings required by this binding's {@code
   *     injectMembers} method.
   */
  public void getDependencies(Set<Binding<?>> getBindings, Set<Binding<?>> injectMembersBindings) {
    // Do nothing.  No override == no dependencies to contribute.
  }

  void setLinked() {
    bits |= LINKED;
  }

  public boolean isLinked() {
    return (bits & LINKED) != 0;
  }

  boolean isSingleton() {
    return (bits & SINGLETON) != 0;
  }

  public boolean isVisiting() {
    return (bits & VISITING) != 0;
  }

  public void setVisiting(boolean visiting) {
    this.bits = visiting ? (bits | VISITING) : (bits & ~VISITING);
  }

  public boolean isCycleFree() {
    return (bits & CYCLE_FREE) != 0;
  }

  public void setCycleFree(boolean cycleFree) {
    this.bits = cycleFree ? (bits | CYCLE_FREE) : (bits & ~CYCLE_FREE);
  }

  public void setLibrary(boolean library) {
    this.bits = library ? (bits | LIBRARY) : (bits & ~LIBRARY);
  }

  public boolean library() {
    return (bits & LIBRARY) != 0;
  }

  public void setDependedOn(boolean dependedOn) {
    this.bits = dependedOn ? (bits | DEPENDED_ON) : (bits & ~DEPENDED_ON);
  }

  public boolean dependedOn() {
    return (bits & DEPENDED_ON) != 0;
  }

  @Override public String toString() {
    return getClass().getSimpleName()
            + "[provideKey=\"" + provideKey + "\", memberskey=\"" + membersKey + "\"]";
  }

  /** An exception thrown by anything attempting to construct a binding which is invalid. */
  public static class InvalidBindingException extends RuntimeException {
    public final String type;

    public InvalidBindingException(String type, String error) {
      super(error);
      this.type = type;
    }
  }
}
compiler/src/main/java/dagger/internal/codegen/Util.java
public static final TypeName SET_OF_BINDINGS = ParameterizedTypeName.get(
    ClassName.get(Set.class), BINDING_OF_ANY);
compiler/src/main/java/dagger/internal/codegen/Util.java
static String elementToString(Element element) {
  switch (element.getKind()) {
    case FIELD:
    // fall through
    case CONSTRUCTOR:
    // fall through
    case METHOD:
      return element.getEnclosingElement() + "." + element;
    default:
      return element.toString();
  }
}
compiler/src/main/java/dagger/internal/codegen/Util.java
static ParameterizedTypeName bindingOf(TypeMirror type) {
  return ParameterizedTypeName.get(ClassName.get(Binding.class), injectableType(type));
}
core/src/main/java/dagger/internal/Linker.java
public final class Linker {
  static final Object UNINITIALIZED = new Object();

  /**
   * The base {@code Linker} which will be consulted to satisfy bindings not
   * otherwise satisfiable from this {@code Linker}. The top-most {@code Linker}
   * in a chain will have a null base linker.
   */
  private final Linker base;

  /** Bindings requiring a call to attach(). May contain deferred bindings. */
  private final Queue<Binding<?>> toLink = new ArrayQueue<Binding<?>>();

  /** True unless calls to requestBinding() were unable to satisfy the binding. */
  private boolean attachSuccess = true;

  /** All errors encountered during injection. */
  private final List<String> errors = new ArrayList<String>();

  /** All of the object graph's bindings. This may contain unlinked bindings. */
  private final Map<String, Binding<?>> bindings = new HashMap<String, Binding<?>>();

  /**
   * An unmodifiable map containing all of the bindings available in this linker, fully linked.
   * This will be null if the bindings are not yet fully linked. It provides both a signal
   * of completion of the {@link #linkAll()} method, as well as a place to reference the final,
   * fully linked map of bindings.
   */
  private volatile Map<String, Binding<?>> linkedBindings = null;

  private final Loader plugin;

  private final ErrorHandler errorHandler;

  public Linker(Linker base, Loader plugin, ErrorHandler errorHandler) {
    if (plugin == null) throw new NullPointerException("plugin");
    if (errorHandler == null) throw new NullPointerException("errorHandler");

    this.base = base;
    this.plugin = plugin;
    this.errorHandler = errorHandler;
  }

  /**
   * Adds all bindings in {@code toInstall}. The caller must call either {@link
   * #linkAll} or {@link #requestBinding} and {@link #linkRequested} before the
   * bindings can be used.
   *
   * This method may only be called before {@link #linkAll()}. Subsequent calls to
   * {@link #installBindings(BindingsGroup)} will throw an {@link IllegalStateException}.
   */
  public void installBindings(BindingsGroup toInstall) {
    if (linkedBindings != null) {
      throw new IllegalStateException("Cannot install further bindings after calling linkAll().");
    }
    for (Map.Entry<String, ? extends Binding<?>> entry : toInstall.entrySet()) {
      bindings.put(entry.getKey(), scope(entry.getValue()));
    }
  }

  /**
   * Links all known bindings (whether requested or installed), plus all of their
   * transitive dependencies. This loads injectable types' bindings as necessary to fill in
   * the gaps.  If this method has returned successfully at least once, all further
   * work is short-circuited.
   *
   * @throws AssertionError if this method is not called within a synchronized block which
   *     holds this {@link Linker} as the lock object.
   */
  public Map<String, Binding<?>> linkAll() {
    assertLockHeld();
    if (linkedBindings != null) {
      return linkedBindings;
    }
    for (Binding<?> binding : bindings.values()) {
      if (!binding.isLinked()) {
        toLink.add(binding);
      }
    }
    linkRequested(); // This method throws if bindings are not resolvable/linkable.
    linkedBindings = Collections.unmodifiableMap(bindings);
    return linkedBindings;
  }

  /**
   * Returns the map of all bindings available to this {@link Linker}, if and only if
   * {@link #linkAll()} has successfully returned at least once, otherwise it returns null;
   */
  public Map<String, Binding<?>> fullyLinkedBindings() {
    return linkedBindings;
  }

  /**
   * Links all requested bindings plus their transitive dependencies. This
   * creates JIT bindings as necessary to fill in the gaps.
   *
   * @throws AssertionError if this method is not called within a synchronized block which
   *     holds this {@link Linker} as the lock object.
   */
  public void linkRequested() {
    assertLockHeld();
    Binding<?> binding;
    while ((binding = toLink.poll()) != null) {
      if (binding instanceof DeferredBinding) {
        DeferredBinding deferred = (DeferredBinding) binding;
        String key = deferred.deferredKey;
        boolean mustHaveInjections = deferred.mustHaveInjections;
        if (bindings.containsKey(key)) {
          continue; // A binding for this key has since been linked.
        }
        try {
          Binding<?> resolvedBinding =
              createBinding(key, binding.requiredBy, deferred.classLoader, mustHaveInjections);
          resolvedBinding.setLibrary(binding.library());
          resolvedBinding.setDependedOn(binding.dependedOn());
          // Fail if the type of binding we got wasn't capable of what was requested.
          if (!key.equals(resolvedBinding.provideKey) && !key.equals(resolvedBinding.membersKey)) {
            throw new IllegalStateException("Unable to create binding for " + key);
          }
          // Enqueue the JIT binding so its own dependencies can be linked.
          Binding<?> scopedBinding = scope(resolvedBinding);
          toLink.add(scopedBinding);
          putBinding(scopedBinding);
        } catch (InvalidBindingException e) {
          addError(e.type + " " + e.getMessage() + " required by " + binding.requiredBy);
          bindings.put(key, Binding.UNRESOLVED);
        } catch (UnsupportedOperationException e) {
          addError("Unsupported: " + e.getMessage() + " required by " + binding.requiredBy);
          bindings.put(key, Binding.UNRESOLVED);
        } catch (IllegalArgumentException e) {
          addError(e.getMessage() + " required by " + binding.requiredBy);
          bindings.put(key, Binding.UNRESOLVED);
        } catch (RuntimeException e) {
          throw e;
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
      } else {
        // Attempt to attach the binding to its dependencies. If any dependency
        // is not available, the attach will fail. We'll enqueue creation of
        // that dependency and retry the attachment later.
        attachSuccess = true;
        binding.attach(this);
        if (attachSuccess) {
          binding.setLinked();
        } else {
          toLink.add(binding);
        }
      }
    }

    try {
      errorHandler.handleErrors(errors);
    } finally {
      errors.clear();
    }
  }

  /**
   * Don't permit bindings to be linked without a lock. Callers should lock
   * before requesting any bindings, link the requested bindings, retrieve
   * the linked bindings, and then release the lock.
   */
  private void assertLockHeld() {
    if (!Thread.holdsLock(this)) throw new AssertionError();
  }

  /**
   * Returns a binding for the key in {@code deferred}. The type of binding
   * to be created depends on the key's type:
   * <ul>
   *   <li>Injections of {@code Provider<Foo>}, {@code MembersInjector<Bar>}, and
   *       {@code Lazy<Blah>} will delegate to the bindings of {@code Foo}, {@code Bar}, and
   *       {@code Blah} respectively.
   *   <li>Injections of raw types will use the injectable constructors of those classes.
   *   <li>Any other injection types require @Provides bindings and will error out.
   * </ul>
   */
  private Binding<?> createBinding(String key, Object requiredBy, ClassLoader classLoader,
      boolean mustHaveInjections) {
    String builtInBindingsKey = Keys.getBuiltInBindingsKey(key);
    if (builtInBindingsKey != null) {
      return new BuiltInBinding<Object>(key, requiredBy, classLoader, builtInBindingsKey);
    }
    String lazyKey = Keys.getLazyKey(key);
    if (lazyKey != null) {
      return new LazyBinding<Object>(key, requiredBy, classLoader, lazyKey);
    }

    String className = Keys.getClassName(key);
    if (className == null) {
      throw new InvalidBindingException(key,
          "is a generic class or an array and can only be bound with concrete type parameter(s) "
          + "in a @Provides method.");
    }
    if (Keys.isAnnotated(key)) {
      throw new InvalidBindingException(key,
          "is a @Qualifier-annotated type and must be bound by a @Provides method.");
    }
    Binding<?> binding =
        plugin.getAtInjectBinding(key, className, classLoader, mustHaveInjections);
    if (binding != null) {
      return binding;
    }
    throw new InvalidBindingException(className, "could not be bound with key " + key);
  }

  /** @deprecated Older, generated code still using this should be re-generated. */
  @Deprecated
  public Binding<?> requestBinding(String key, Object requiredBy) {
    return requestBinding(
        key, requiredBy, getClass().getClassLoader(), true, true);
  }

  /**
   * Returns the binding if it exists immediately. Otherwise this returns
   * null. If the returned binding didn't exist or was unlinked, it will be
   * enqueued to be linked.
   */
  public Binding<?> requestBinding(String key, Object requiredBy, ClassLoader classLoader) {
    return requestBinding(key, requiredBy, classLoader, true, true);
  }

  /** @deprecated Older, generated code still using this should be re-generated. */
  @Deprecated
  public Binding<?> requestBinding(String key, Object requiredBy,
      boolean mustHaveInjections, boolean library) {
    return requestBinding(key, requiredBy, getClass().getClassLoader(),
        mustHaveInjections, library);
  }

  /**
   * Returns the binding if it exists immediately. Otherwise this returns
   * null. If the returned binding didn't exist or was unlinked, it will be
   * enqueued to be linked.
   *
   * @param mustHaveInjections true if the the referenced key requires either an
   *     {@code @Inject} annotation is produced by a {@code @Provides} method.
   *     This isn't necessary for Module.injects types because frameworks need
   *     to inject arbitrary classes like JUnit test cases and Android
   *     activities. It also isn't necessary for supertypes.
   */
  public Binding<?> requestBinding(String key, Object requiredBy, ClassLoader classLoader,
      boolean mustHaveInjections, boolean library) {
    assertLockHeld();

    Binding<?> binding = null;
    for (Linker linker = this; linker != null; linker = linker.base) {
      binding = linker.bindings.get(key);
      if (binding != null) {
        if (linker != this && !binding.isLinked()) throw new AssertionError();
        break;
      }
    }

    if (binding == null) {
      // We can't satisfy this binding. Make sure it'll work next time!
      Binding<?> deferredBinding =
          new DeferredBinding(key, classLoader, requiredBy, mustHaveInjections);
      deferredBinding.setLibrary(library);
      deferredBinding.setDependedOn(true);
      toLink.add(deferredBinding);
      attachSuccess = false;
      return null;
    }

    if (!binding.isLinked()) {
      toLink.add(binding); // This binding was never linked; link it now!
    }

    binding.setLibrary(library);
    binding.setDependedOn(true);
    return binding;
  }

  private <T> void putBinding(final Binding<T> binding) {

    // At binding insertion time it's possible that another binding for the same
    // key to already exist. This occurs when an @Provides method returns a type T
    // and we also inject the members of that type.
    if (binding.provideKey != null) {
      putIfAbsent(bindings, binding.provideKey, binding);
    }
    if (binding.membersKey != null) {
      putIfAbsent(bindings, binding.membersKey, binding);
    }
  }

  /**
   * Returns a scoped binding for {@code binding}.
   */
  static <T> Binding<T> scope(final Binding<T> binding) {
    if (!binding.isSingleton() || binding instanceof SingletonBinding) {
      return binding; // Default scoped binding or already a scoped binding.
    }
    return new SingletonBinding<T>(binding);
  }

  /**
   * Puts the mapping {@code key, value} in {@code map} if no mapping for {@code
   * key} already exists.
   */
  private <K, V> void putIfAbsent(Map<K, V> map, K key, V value) {
    V replaced = map.put(key, value); // Optimistic: prefer only one hash operation lookup.
    if (replaced != null) {
      map.put(key, replaced);
    }
  }

  /** Enqueue {@code message} as a fatal error to be reported to the user. */
  private void addError(String message) {
    errors.add(message);
  }

  /**
   * A Binding that implements singleton behaviour around an existing binding.
   */
  private static class SingletonBinding<T> extends Binding<T> {
    private final Binding<T> binding;
    private volatile Object onlyInstance = UNINITIALIZED;

    SingletonBinding(Binding<T> binding) {
      super(binding.provideKey, binding.membersKey, true, binding.requiredBy);
      this.binding = binding;
    }

    @Override public void attach(Linker linker) {
      binding.attach(linker);
    }

    @Override public void injectMembers(T t) {
      binding.injectMembers(t);
    }

    @SuppressWarnings("unchecked") // onlyInstance is either 'UNINITIALIZED' or a 'T'.
    @Override public T get() {
      if (onlyInstance == UNINITIALIZED) {
        synchronized (this) {
          if (onlyInstance == UNINITIALIZED) {
            onlyInstance = binding.get();
          }
        }
      }
      return (T) onlyInstance;
    }

    @Override public void getDependencies(Set<Binding<?>> get, Set<Binding<?>> injectMembers) {
      binding.getDependencies(get, injectMembers);
    }

    @Override public boolean isCycleFree() {
      return binding.isCycleFree();
    }

    @Override public boolean isLinked() {
      return binding.isLinked();
    }

    @Override public boolean isVisiting() {
      return binding.isVisiting();
    }

    @Override public boolean library() {
      return binding.library();
    }

    @Override public boolean dependedOn() {
      return binding.dependedOn();
    }

    @Override public void setCycleFree(final boolean cycleFree) {
      binding.setCycleFree(cycleFree);
    }

    @Override public void setVisiting(final boolean visiting) {
      binding.setVisiting(visiting);
    }

    @Override public void setLibrary(boolean library) {
      binding.setLibrary(true);
    }

    @Override public void setDependedOn(boolean dependedOn) {
      binding.setDependedOn(dependedOn);
    }

    @Override protected boolean isSingleton() {
      return true;
    }

    @Override protected void setLinked() {
      binding.setLinked();
    }

    @Override public String toString() {
      return "@Singleton/" + binding.toString();
    }
  }

  /** Handles linker errors appropriately. */
  public interface ErrorHandler {
    ErrorHandler NULL = new ErrorHandler() {
      @Override public void handleErrors(List<String> errors) {
      }
    };

    /**
     * Fail if any errors have been enqueued.
     * Implementations may throw exceptions or report the errors through another
     * channel.  Callers are responsible for clearing enqueued errors.
     *
     * @param errors a potentially empty list of error messages.
     */
    void handleErrors(List<String> errors);
  }

  private static class DeferredBinding extends Binding<Object> {
    /** Loader originally intended to load this binding, to be used in loading the actual one */
    final ClassLoader classLoader;
    final String deferredKey;
    final boolean mustHaveInjections;

    DeferredBinding(String deferredKey, ClassLoader classLoader, Object requiredBy,
        boolean mustHaveInjections) {
      super(null, null, false, requiredBy);
      this.deferredKey = deferredKey;
      this.classLoader = classLoader;
      this.mustHaveInjections = mustHaveInjections;
    }

    @Override public void injectMembers(Object t) {
      throw new UnsupportedOperationException("Deferred bindings must resolve first.");
    }

    @Override public void getDependencies(Set<Binding<?>> get, Set<Binding<?>> injectMembers) {
      throw new UnsupportedOperationException("Deferred bindings must resolve first.");
    }

    @Override public String toString() {
      return "DeferredBinding[deferredKey=" + deferredKey + "]";
    }
  }
}


Question: import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeSpec;
import dagger.ObjectGraph;
import dagger.internal.Binding;
import dagger.internal.Linker;
import dagger.internal.StaticInjection;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic;
import static dagger.internal.codegen.AdapterJavadocs.bindingTypeDocs;
import static dagger.internal.codegen.Util.SET_OF_BINDINGS;
import static dagger.internal.codegen.Util.adapterName;
import static dagger.internal.codegen.Util.bindingOf;
import static dagger.internal.codegen.Util.elementToString;
import static dagger.internal.codegen.Util.getApplicationSupertype;
import static dagger.internal.codegen.Util.getNoArgsConstructor;
import static dagger.internal.codegen.Util.getPackage;
import static dagger.internal.codegen.Util.injectableType;
import static dagger.internal.codegen.Util.isCallableConstructor;
import static dagger.internal.codegen.Util.rawTypeToString;
import static dagger.internal.loaders.GeneratedAdapters.INJECT_ADAPTER_SUFFIX;
import static dagger.internal.loaders.GeneratedAdapters.STATIC_INJECTION_SUFFIX;
import static javax.lang.model.element.Modifier.ABSTRACT;
import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PRIVATE;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;
      }
    }
    return true;
  }

  private Set<String> findInjectedClassNames(RoundEnvironment env) {
    // First gather the set of classes that have @Inject-annotated members.
    Set<String> injectedTypeNames = new LinkedHashSet<String>();
    for (Element element : env.getElementsAnnotatedWith(Inject.class)) {
      if (!validateInjectable(element)) {
        continue;
      }
      injectedTypeNames.add(rawTypeToString(element.getEnclosingElement().asType(), '.'));
    }
    return injectedTypeNames;
  }

  private boolean validateInjectable(Element injectable) {
    Element injectableType = injectable.getEnclosingElement();

    if (injectable.getKind() == ElementKind.CLASS) {
      error("@Inject is not valid on a class: " + elementToString(injectable), injectable);
      return false;
    }

    if (injectable.getKind() == ElementKind.METHOD) {
      error("Method injection is not supported: " + elementToString(injectable), injectable);
      return false;
    }

    if (injectable.getKind() == ElementKind.FIELD
        && injectable.getModifiers().contains(FINAL)) {
      error("Can't inject a final field: " + elementToString(injectable), injectable);
      return false;
    }

    if (injectable.getKind() == ElementKind.FIELD
        && injectable.getModifiers().contains(PRIVATE)) {
      error("Can't inject a private field: " + elementToString(injectable), injectable);
      return false;
    }

    if (injectable.getKind() == ElementKind.CONSTRUCTOR
        && injectable.getModifiers().contains(PRIVATE)) {
      error("Can't inject a private constructor: " + elementToString(injectable), injectable);
      return false;
    }

    ElementKind elementKind = injectableType.getEnclosingElement().getKind();
    boolean isClassOrInterface = elementKind.isClass() || elementKind.isInterface();
    boolean isStatic = injectableType.getModifiers().contains(STATIC);

    if (isClassOrInterface && !isStatic) {
      error("Can't inject a non-static inner class: " + elementToString(injectable),
          injectableType);
      return false;
    }

    return true;
  }

  /**
   * @param injectedClassName the name of a class with an @Inject-annotated member.
   */
  private InjectedClass createInjectedClass(String injectedClassName) {
    TypeElement type = processingEnv.getElementUtils().getTypeElement(injectedClassName);
    boolean isAbstract = type.getModifiers().contains(ABSTRACT);
    List<Element> staticFields = new ArrayList<Element>();
    ExecutableElement constructor = null;
    List<Element> fields = new ArrayList<Element>();
    for (Element member : type.getEnclosedElements()) {
      if (member.getAnnotation(Inject.class) == null) {
        continue;
      }

      switch (member.getKind()) {
        case FIELD:
          if (member.getModifiers().contains(STATIC)) {
            staticFields.add(member);
          } else {
            fields.add(member);
          }
          break;
        case CONSTRUCTOR:
          if (constructor != null) {
            // TODO(tbroyer): pass annotation information
            error("Too many injectable constructors on " + type.getQualifiedName(), member);
          } else if (isAbstract) {
            // TODO(tbroyer): pass annotation information
            error("Abstract class " + type.getQualifiedName()
                + " must not have an @Inject-annotated constructor.", member);
          }
          constructor = (ExecutableElement) member;
          break;
        default:
          // TODO(tbroyer): pass annotation information
          error("Cannot inject " + elementToString(member), member);
          break;
      }
    }

    if (constructor == null && !isAbstract) {
      constructor = getNoArgsConstructor(type);
      if (constructor != null && !isCallableConstructor(constructor)) {
        constructor = null;
      }
    }

    return new InjectedClass(type, staticFields, constructor, fields);
  }

  /**
   * Write a companion class for {@code type} that extends {@link Binding}.
   *
   * @param constructor the injectable constructor, or null if this binding
   *     supports members injection only.
   */
  private void generateInjectAdapter(TypeElement type, ExecutableElement constructor,
      List<Element> fields) throws IOException {
    String packageName = getPackage(type).getQualifiedName().toString();
Answer:     TypeMirror supertype = getApplicationSupertype(type);