Automated g4 rollback of changelist b9326a1e.

*** Reason for rollback ***

Breaks users that depend on ComponentProcessor directly.

*** Original change description ***

Split codegen code into a few distinct java_libraries to speed up compilation.

We still ship one jar to Maven Central, as this is purely a build time implementation detail.

***

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=174784361
diff --git a/BUILD b/BUILD
index 6b395fd..e195b51 100644
--- a/BUILD
+++ b/BUILD
@@ -59,28 +59,12 @@
     name = "shaded_compiler",
     rules_file = "shade_rules.txt",
     deps = [
-        "//java/dagger/internal/codegen:base",
-        "//java/dagger/internal/codegen:binding",
-        "//java/dagger/internal/codegen:processor",
-        "//java/dagger/internal/codegen:validation",
-        "//java/dagger/internal/codegen:writing",
+        "//java/dagger/internal/codegen",
         "@com_google_auto_auto_common//jar",
     ],
 )
 
 jarjar_library(
-    name = "shaded_compiler_src",
-    rules_file = "merge_all_rules.txt",
-    deps = [
-        "//java/dagger/internal/codegen:libbase-src.jar",
-        "//java/dagger/internal/codegen:libbinding-src.jar",
-        "//java/dagger/internal/codegen:libprocessor-src.jar",
-        "//java/dagger/internal/codegen:libvalidation-src.jar",
-        "//java/dagger/internal/codegen:libwriting-src.jar",
-    ],
-)
-
-jarjar_library(
     name = "shaded_android_processor",
     rules_file = "shade_rules.txt",
     deps = [
diff --git a/java/dagger/internal/codegen/AnnotationCreatorGenerator.java b/java/dagger/internal/codegen/AnnotationCreatorGenerator.java
index 8f457ee..c5051bc 100644
--- a/java/dagger/internal/codegen/AnnotationCreatorGenerator.java
+++ b/java/dagger/internal/codegen/AnnotationCreatorGenerator.java
@@ -19,9 +19,8 @@
 import static com.squareup.javapoet.MethodSpec.constructorBuilder;
 import static com.squareup.javapoet.MethodSpec.methodBuilder;
 import static com.squareup.javapoet.TypeSpec.classBuilder;
-import static dagger.internal.codegen.AnnotationExpression.createMethodName;
-import static dagger.internal.codegen.AnnotationExpression.getAnnotationCreatorClassName;
 import static dagger.internal.codegen.CodeBlocks.makeParametersCodeBlock;
+import static dagger.internal.codegen.SourceFiles.classFileName;
 import static javax.lang.model.element.Modifier.FINAL;
 import static javax.lang.model.element.Modifier.PRIVATE;
 import static javax.lang.model.element.Modifier.PUBLIC;
@@ -78,6 +77,17 @@
  */
 class AnnotationCreatorGenerator extends SourceFileGenerator<TypeElement> {
 
+  /**
+   * Returns the name of the generated class that contains the static {@code create} methods for an
+   * annotation type.
+   */
+  static ClassName getAnnotationCreatorClassName(TypeElement annotationType) {
+    ClassName annotationTypeName = ClassName.get(annotationType);
+    return annotationTypeName
+        .topLevelClassName()
+        .peerClass(classFileName(annotationTypeName) + "Creator");
+  }
+
   AnnotationCreatorGenerator(Filer filer, Elements elements) {
     super(filer, elements);
   }
@@ -130,6 +140,10 @@
     return createMethod.build();
   }
 
+  static String createMethodName(TypeElement annotationType) {
+    return "create" + annotationType.getSimpleName();
+  }
+
   /**
    * Returns the annotation types for which {@code @AutoAnnotation static Foo createFoo(…)} methods
    * should be written.
diff --git a/java/dagger/internal/codegen/AnnotationExpression.java b/java/dagger/internal/codegen/AnnotationExpression.java
index 9072fe2..61b472a 100644
--- a/java/dagger/internal/codegen/AnnotationExpression.java
+++ b/java/dagger/internal/codegen/AnnotationExpression.java
@@ -18,7 +18,6 @@
 
 import static com.google.auto.common.AnnotationMirrors.getAnnotationValuesWithDefaults;
 import static dagger.internal.codegen.CodeBlocks.makeParametersCodeBlock;
-import static dagger.internal.codegen.SourceFiles.classFileName;
 import static java.util.stream.Collectors.toList;
 
 import com.google.auto.common.MoreElements;
@@ -30,7 +29,6 @@
 import java.util.List;
 import javax.lang.model.element.AnnotationMirror;
 import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
 import javax.lang.model.type.ArrayType;
 import javax.lang.model.type.DeclaredType;
@@ -57,7 +55,7 @@
   AnnotationExpression(AnnotationMirror annotation) {
     this.annotation = annotation;
     this.creatorClass =
-        getAnnotationCreatorClassName(
+        AnnotationCreatorGenerator.getAnnotationCreatorClassName(
             MoreTypes.asTypeElement(annotation.getAnnotationType()));
   }
 
@@ -73,7 +71,7 @@
     return CodeBlock.of(
         "$T.$L($L)",
         creatorClass,
-        createMethodName(
+        AnnotationCreatorGenerator.createMethodName(
             MoreElements.asType(annotation.getAnnotationType().asElement())),
         makeParametersCodeBlock(
             getAnnotationValuesWithDefaults(annotation)
@@ -84,21 +82,6 @@
   }
 
   /**
-   * Returns the name of the generated class that contains the static {@code create} methods for an
-   * annotation type.
-   */
-  static ClassName getAnnotationCreatorClassName(TypeElement annotationType) {
-    ClassName annotationTypeName = ClassName.get(annotationType);
-    return annotationTypeName
-        .topLevelClassName()
-        .peerClass(classFileName(annotationTypeName) + "Creator");
-  }
-
-  static String createMethodName(TypeElement annotationType) {
-    return "create" + annotationType.getSimpleName();
-  }
-
-  /**
    * Returns an expression that evaluates to a {@code value} of a given type on an {@code
    * annotation}.
    */
diff --git a/java/dagger/internal/codegen/BUILD b/java/dagger/internal/codegen/BUILD
index 490e2b1..53e3926 100644
--- a/java/dagger/internal/codegen/BUILD
+++ b/java/dagger/internal/codegen/BUILD
@@ -42,201 +42,13 @@
     "//java/dagger/producers",
 ]
 
-CODEGEN_DEPS = CODEGEN_SHARED_DEPS + [
-    "//third_party:guava",
-]
-
-# Common types needed across all of the codegen package
 java_library(
-    name = "base",
-    srcs = [
-        "Accessibility.java",
-        "AnnotationSpecs.java",
-        "CodeBlocks.java",
-        "CompilerOptions.java",
-        "ContributionType.java",
-        "DaggerElements.java",
-        "DaggerStreams.java",
-        "DaggerTypes.java",
-        "Expression.java",
-        "FeatureStatus.java",
-        "InjectionAnnotations.java",
-        "MapKeyAccessibility.java",
-        "MethodSignature.java",
-        "MoreAnnotationMirrors.java",
-        "MoreAnnotationValues.java",
-        "MultibindingAnnotations.java",
-        "Optionals.java",
-        "SimpleAnnotationMirror.java",
-        "SimpleTypeAnnotationValue.java",
-        "SourceFileGenerationException.java",  # Used in :writing and :processor
-        "SourceFileGenerator.java",  # Needed by InjectBindingRegistry in :binding and also :writing
-        "TypeNames.java",
-        "TypeSpecs.java",
-        "UniqueNameSet.java",
-        "Util.java",
-        "ValidationType.java",
-        "package-info.java",
-    ],
+    name = "codegen",
+    srcs = CODEGEN_SRCS,
+    javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
     plugins = CODEGEN_PLUGINS,
-    tags = ["maven:merged"],
-    deps = CODEGEN_DEPS,
-)
-
-# Classes that help to build a model of the binding graph
-java_library(
-    name = "binding",
-    srcs = [
-        "AnnotationExpression.java",
-        "Binding.java",
-        "BindingDeclaration.java",
-        "BindingGraph.java",
-        "BindingKey.java",
-        "BindingType.java",
-        "BindingTypeMapper.java",
-        "BindingVariableNamer.java",  # needed by FrameworkField
-        "BindsTypeChecker.java",
-        "ComponentDescriptor.java",
-        "ComponentRequirement.java",
-        "ComponentTreeTraverser.java",
-        "ConfigurationAnnotations.java",  # Uses ModuleDescriptors
-        "ContributionBinding.java",
-        "DelegateDeclaration.java",
-        "DependencyRequest.java",
-        "DependencyVariableNamer.java",  # Used by SourceFiles
-        "ErrorMessages.java",  # Consider splitting this up as it pulls in too much
-        "FrameworkDependency.java",
-        "FrameworkField.java",  # Used by SourceFiles
-        "FrameworkType.java",
-        "FrameworkTypes.java",
-        "InjectBindingRegistry.java",
-        "Key.java",
-        "MapKeys.java",
-        "MapType.java",
-        "MembersInjectionBinding.java",
-        "ModuleDescriptor.java",
-        "MultibindingDeclaration.java",
-        "OptionalBindingDeclaration.java",
-        "OptionalType.java",
-        "ProductionBinding.java",
-        "ProvisionBinding.java",
-        "ResolvedBindings.java",
-        "Scope.java",
-        "SetType.java",
-        "SourceFiles.java",  # Consider splitting this up?
-        "SubcomponentDeclaration.java",
-    ],
-    plugins = CODEGEN_PLUGINS,
-    tags = ["maven:merged"],
-    deps = CODEGEN_DEPS + [":base"],
-)
-
-# Code related to validating the user-written Dagger code
-java_library(
-    name = "validation",
-    srcs = [
-        "AnyBindingMethodValidator.java",
-        "BindingDeclarationFormatter.java",
-        "BindingGraphValidator.java",
-        "BindingMethodProcessingStep.java",
-        "BindingMethodValidator.java",
-        "BindsInstanceProcessingStep.java",
-        "BindsMethodValidator.java",
-        "BindsOptionalOfMethodValidator.java",
-        "BuilderValidator.java",
-        "CanReleaseReferencesValidator.java",
-        "ComponentHierarchyValidator.java",
-        "ComponentValidator.java",
-        "DependencyRequestFormatter.java",
-        "ForReleasableReferencesValidator.java",
-        "Formatter.java",
-        "InjectValidator.java",
-        "MapKeyValidator.java",
-        "MethodSignatureFormatter.java",
-        "MissingBindingSuggestions.java",
-        "ModuleValidator.java",
-        "MultibindingAnnotationsProcessingStep.java",
-        "MultibindsMethodValidator.java",
-        "ProducesMethodValidator.java",
-        "ProvidesMethodValidator.java",
-        "ValidationReport.java",
-    ],
-    plugins = CODEGEN_PLUGINS,
-    tags = ["maven:merged"],
-    deps = CODEGEN_DEPS + [
-        ":base",
-        ":binding",
-    ],
-)
-
-# Classes that assemble the model of the generated code and write to the Filer
-java_library(
-    name = "writing",
-    srcs = [
-        "AbstractComponentWriter.java",
-        "AnnotationCreatorGenerator.java",
-        "BindingExpression.java",
-        "BoundInstanceBindingExpression.java",
-        "ComponentBindingExpressions.java",
-        "ComponentBuilder.java",
-        "ComponentGenerator.java",
-        "ComponentInstanceBindingExpression.java",
-        "ComponentProvisionBindingExpression.java",
-        "ComponentRequirementField.java",
-        "ComponentRequirementFields.java",
-        "ComponentWriter.java",
-        "DelegateBindingExpression.java",
-        "FactoryGenerator.java",
-        "FrameworkFieldInitializer.java",
-        "FrameworkInstanceBindingExpression.java",
-        "GeneratedComponentModel.java",
-        "GwtCompatibility.java",
-        "InjectionMethods.java",
-        "MapBindingExpression.java",
-        "MemberSelect.java",
-        "MembersInjectorGenerator.java",
-        "MonitoringModuleGenerator.java",
-        "MonitoringModuleProcessingStep.java",
-        "OptionalBindingExpression.java",
-        "OptionalFactories.java",
-        "PrivateMethodBindingExpression.java",
-        "ProducerFactoryGenerator.java",
-        "ProductionExecutorModuleGenerator.java",
-        "ProviderOrProducerBindingExpression.java",
-        "SetBindingExpression.java",
-        "SimpleInvocationBindingExpression.java",
-        "SimpleMethodBindingExpression.java",
-        "SubcomponentBuilderBindingExpression.java",
-        "SubcomponentWriter.java",
-        "UnwrappedMapKeyGenerator.java",
-    ],
-    plugins = CODEGEN_PLUGINS,
-    tags = ["maven:merged"],
-    deps = CODEGEN_DEPS + [
-        ":base",
-        ":binding",
-    ],
-)
-
-# The processor's "main", if you will
-java_library(
-    name = "processor",
-    srcs = [
-        "CanReleaseReferencesProcessingStep.java",
-        "ComponentProcessingStep.java",
-        "ComponentProcessor.java",
-        "InjectBindingRegistryImpl.java",
-        "InjectProcessingStep.java",
-        "MapKeyProcessingStep.java",
-        "ModuleProcessingStep.java",
-        "ProductionExecutorModuleProcessingStep.java",
-    ],
-    plugins = CODEGEN_PLUGINS,
-    deps = CODEGEN_DEPS + [
-        ":base",
-        ":binding",
-        ":writing",
-        ":validation",
+    deps = CODEGEN_SHARED_DEPS + [
+        "//third_party:guava",
     ],
 )
 
@@ -246,20 +58,12 @@
     name = "codegen-javadoc",
     srcs = CODEGEN_SRCS,
     root_packages = ["dagger.internal.codegen"],
-    deps = [":processor"],
-)
-
-java_library(
-    name = "check-package-javadoc",
-    testonly = 1,
-    srcs = CODEGEN_SRCS,
-    javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
-    deps = CODEGEN_DEPS,
+    deps = [":codegen"],
 )
 
 java_plugin(
     name = "component-codegen",
     generates_api = 1,
     processor_class = "dagger.internal.codegen.ComponentProcessor",
-    deps = [":processor"],
+    deps = [":codegen"],
 )
diff --git a/java/dagger/internal/codegen/ComponentProcessor.java b/java/dagger/internal/codegen/ComponentProcessor.java
index 4097f75..d35e30b 100644
--- a/java/dagger/internal/codegen/ComponentProcessor.java
+++ b/java/dagger/internal/codegen/ComponentProcessor.java
@@ -116,8 +116,11 @@
     SubcomponentDeclaration.Factory subcomponentDeclarationFactory =
         new SubcomponentDeclaration.Factory(keyFactory);
 
-    this.factoryGenerator = new FactoryGenerator(filer, elements, types, compilerOptions);
-    this.membersInjectorGenerator = new MembersInjectorGenerator(filer, elements, types);
+    this.factoryGenerator =
+        new FactoryGenerator(
+            filer, elements, types, compilerOptions, injectValidatorWhenGeneratingCode);
+    this.membersInjectorGenerator =
+        new MembersInjectorGenerator(filer, elements, types, injectValidatorWhenGeneratingCode);
     ComponentGenerator componentGenerator =
         new ComponentGenerator(filer, elements, types, keyFactory, compilerOptions);
     ProducerFactoryGenerator producerFactoryGenerator =
@@ -133,7 +136,7 @@
         new OptionalBindingDeclaration.Factory(keyFactory);
 
     this.injectBindingRegistry =
-        new InjectBindingRegistryImpl(
+        new InjectBindingRegistry(
             elements,
             types,
             messager,
diff --git a/java/dagger/internal/codegen/ComponentValidator.java b/java/dagger/internal/codegen/ComponentValidator.java
index d7ccc3e..d240105 100644
--- a/java/dagger/internal/codegen/ComponentValidator.java
+++ b/java/dagger/internal/codegen/ComponentValidator.java
@@ -21,8 +21,8 @@
 import static dagger.internal.codegen.ConfigurationAnnotations.enclosedBuilders;
 import static dagger.internal.codegen.ConfigurationAnnotations.getComponentDependencies;
 import static dagger.internal.codegen.ConfigurationAnnotations.getComponentModules;
-import static dagger.internal.codegen.ConfigurationAnnotations.getModuleAnnotation;
 import static dagger.internal.codegen.ConfigurationAnnotations.getTransitiveModules;
+import static dagger.internal.codegen.ConfigurationAnnotations.validateComponentDependencies;
 import static dagger.internal.codegen.DaggerElements.getAnnotationMirror;
 import static dagger.internal.codegen.DaggerElements.getAnyAnnotation;
 import static dagger.internal.codegen.ErrorMessages.COMPONENT_ANNOTATED_REUSABLE;
@@ -368,38 +368,6 @@
     }
   }
 
-  private static <T extends Element> void validateComponentDependencies(
-      ValidationReport.Builder<T> report, Iterable<TypeMirror> types) {
-    validateTypesAreDeclared(report, types, "component dependency");
-    for (TypeMirror type : types) {
-      if (getModuleAnnotation(MoreTypes.asTypeElement(type)).isPresent()) {
-        report.addError(
-            String.format("%s is a module, which cannot be a component dependency", type));
-      }
-    }
-  }
-
-  private static <T extends Element> void validateTypesAreDeclared(
-      final ValidationReport.Builder<T> report, Iterable<TypeMirror> types, final String typeName) {
-    for (TypeMirror type : types) {
-      type.accept(
-          new SimpleTypeVisitor6<Void, Void>() {
-            @Override
-            protected Void defaultAction(TypeMirror e, Void aVoid) {
-              report.addError(String.format("%s is not a valid %s type", e, typeName));
-              return null;
-            }
-
-            @Override
-            public Void visitDeclared(DeclaredType t, Void aVoid) {
-              // Declared types are valid
-              return null;
-            }
-          },
-          null);
-    }
-  }
-
   private static Optional<AnnotationMirror> checkForAnnotations(
       TypeMirror type, final Set<? extends Class<? extends Annotation>> annotations) {
     return type.accept(
diff --git a/java/dagger/internal/codegen/ConfigurationAnnotations.java b/java/dagger/internal/codegen/ConfigurationAnnotations.java
index e8fe453..d5e7c9b 100644
--- a/java/dagger/internal/codegen/ConfigurationAnnotations.java
+++ b/java/dagger/internal/codegen/ConfigurationAnnotations.java
@@ -51,6 +51,7 @@
 import javax.lang.model.type.TypeKind;
 import javax.lang.model.type.TypeMirror;
 import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleTypeVisitor6;
 import javax.lang.model.util.Types;
 
 /**
@@ -164,6 +165,36 @@
     return Optional.empty();
   }
 
+  static <T extends Element> void validateComponentDependencies(
+      ValidationReport.Builder<T> report, Iterable<TypeMirror> types) {
+    validateTypesAreDeclared(report, types, "component dependency");
+    for (TypeMirror type : types) {
+      if (getModuleAnnotation(MoreTypes.asTypeElement(type)).isPresent()) {
+        report.addError(
+            String.format("%s is a module, which cannot be a component dependency", type));
+      }
+    }
+  }
+
+  private static <T extends Element> void validateTypesAreDeclared(
+      final ValidationReport.Builder<T> report, Iterable<TypeMirror> types, final String typeName) {
+    for (TypeMirror type : types) {
+      type.accept(new SimpleTypeVisitor6<Void, Void>(){
+        @Override
+        protected Void defaultAction(TypeMirror e, Void aVoid) {
+          report.addError(String.format("%s is not a valid %s type", e, typeName));
+          return null;
+        }
+
+        @Override
+        public Void visitDeclared(DeclaredType t, Void aVoid) {
+          // Declared types are valid
+          return null;
+        }
+      }, null);
+    }
+  }
+
   /**
    * Returns the full set of modules transitively {@linkplain Module#includes included} from the
    * given seed modules.  If a module is malformed and a type listed in {@link Module#includes}
diff --git a/java/dagger/internal/codegen/FactoryGenerator.java b/java/dagger/internal/codegen/FactoryGenerator.java
index 58fe04f..b63070f 100644
--- a/java/dagger/internal/codegen/FactoryGenerator.java
+++ b/java/dagger/internal/codegen/FactoryGenerator.java
@@ -76,15 +76,18 @@
 final class FactoryGenerator extends SourceFileGenerator<ProvisionBinding> {
   private final Types types;
   private final CompilerOptions compilerOptions;
+  private final InjectValidator injectValidator;
 
   FactoryGenerator(
       Filer filer,
       Elements elements,
       Types types,
-      CompilerOptions compilerOptions) {
+      CompilerOptions compilerOptions,
+      InjectValidator injectValidator) {
     super(filer, elements);
     this.types = types;
     this.compilerOptions = compilerOptions;
+    this.injectValidator = injectValidator;
   }
 
   @Override
@@ -103,6 +106,11 @@
     checkArgument(!binding.unresolved().isPresent());
     checkArgument(binding.bindingElement().isPresent());
 
+    if (binding.bindingKind().equals(INJECTION)
+        && !injectValidator.isValidType(binding.contributedType())) {
+      return Optional.empty();
+    }
+
     TypeName providedTypeName = TypeName.get(binding.contributedType());
     ParameterizedTypeName factoryTypeName = factoryOf(providedTypeName);
     ImmutableList<TypeVariableName> typeParameters = bindingTypeElementTypeVariableNames(binding);
diff --git a/java/dagger/internal/codegen/InjectBindingRegistry.java b/java/dagger/internal/codegen/InjectBindingRegistry.java
index b389cd3..2169c4b 100644
--- a/java/dagger/internal/codegen/InjectBindingRegistry.java
+++ b/java/dagger/internal/codegen/InjectBindingRegistry.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Dagger Authors.
+ * Copyright (C) 2014 The Dagger Authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,46 +16,311 @@
 
 package dagger.internal.codegen;
 
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static dagger.internal.codegen.InjectionAnnotations.injectedConstructors;
+import static dagger.internal.codegen.SourceFiles.generatedClassNameForBinding;
+
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.squareup.javapoet.ClassName;
 import dagger.Component;
 import dagger.Provides;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
+import javax.annotation.processing.Messager;
 import javax.inject.Inject;
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic.Kind;
 
 /**
  * Maintains the collection of provision bindings from {@link Inject} constructors and members
- * injection bindings from {@link Inject} fields and methods known to the annotation processor. Note
- * that this registry <b>does not</b> handle any explicit bindings (those from {@link Provides}
+ * injection bindings from {@link Inject} fields and methods known to the annotation processor.
+ * Note that this registry <b>does not</b> handle any explicit bindings (those from {@link Provides}
  * methods, {@link Component} dependencies, etc.).
+ *
+ * @author Gregory Kick
  */
-interface InjectBindingRegistry {
+final class InjectBindingRegistry {
+  private final Elements elements;
+  private final Types types;
+  private final Messager messager;
+  private final InjectValidator injectValidator;
+  private final Key.Factory keyFactory;
+  private final ProvisionBinding.Factory provisionBindingFactory;
+  private final MembersInjectionBinding.Factory membersInjectionBindingFactory;
+  private final CompilerOptions compilerOptions;
+
+  final class BindingsCollection<B extends Binding> {
+    private final BindingType bindingType;
+    private final Map<Key, B> bindingsByKey = Maps.newLinkedHashMap();
+    private final Deque<B> bindingsRequiringGeneration = new ArrayDeque<>();
+    private final Set<Key> materializedBindingKeys = Sets.newLinkedHashSet();
+    
+    BindingsCollection(BindingType bindingType) {
+      this.bindingType = bindingType;
+    }
+
+    void generateBindings(SourceFileGenerator<B> generator) throws SourceFileGenerationException {
+      for (B binding = bindingsRequiringGeneration.poll();
+          binding != null;
+          binding = bindingsRequiringGeneration.poll()) {
+        checkState(!binding.unresolved().isPresent());
+        generator.generate(binding);
+        materializedBindingKeys.add(binding.key());
+      }
+      // Because Elements instantiated across processing rounds are not guaranteed to be equals() to
+      // the logically same element, clear the cache after generating
+      bindingsByKey.clear();
+    }
+
+    /** Returns a previously cached binding. */
+    B getBinding(Key key) {
+      return bindingsByKey.get(key);
+    }
+
+    /** Caches the binding and generates it if it needs generation. */
+    void tryRegisterBinding(B binding, boolean warnIfNotAlreadyGenerated) {
+      tryToCacheBinding(binding);
+      tryToGenerateBinding(binding, warnIfNotAlreadyGenerated);
+    }
+
+    /**
+     * Tries to generate a binding, not generating if it already is generated. For resolved
+     * bindings, this will try to generate the unresolved version of the binding.
+     */
+    void tryToGenerateBinding(B binding, boolean warnIfNotAlreadyGenerated) {
+      if (shouldGenerateBinding(binding, generatedClassNameForBinding(binding))) {
+        bindingsRequiringGeneration.offer(binding);
+        if (compilerOptions.warnIfInjectionFactoryNotGeneratedUpstream()
+            && warnIfNotAlreadyGenerated) {
+          messager.printMessage(
+              Kind.NOTE,
+              String.format(
+                  "Generating a %s for %s. "
+                      + "Prefer to run the dagger processor over that class instead.",
+                  bindingType.frameworkClass().getSimpleName(),
+                  types.erasure(binding.key().type()))); // erasure to strip <T> from msgs.
+        }
+      }
+    }
+
+    /** Returns true if the binding needs to be generated. */
+    private boolean shouldGenerateBinding(B binding, ClassName factoryName) {
+      return !binding.unresolved().isPresent()
+          && elements.getTypeElement(factoryName.toString()) == null
+          && !materializedBindingKeys.contains(binding.key())
+          && !bindingsRequiringGeneration.contains(binding);
+    }
+
+    /** Caches the binding for future lookups by key. */
+    private void tryToCacheBinding(B binding) {
+      // We only cache resolved bindings or unresolved bindings w/o type arguments.
+      // Unresolved bindings w/ type arguments aren't valid for the object graph.
+      if (binding.unresolved().isPresent()
+          || binding.bindingTypeElement().get().getTypeParameters().isEmpty()) {
+        Key key = binding.key();
+        Binding previousValue = bindingsByKey.put(key, binding);
+        checkState(previousValue == null || binding.equals(previousValue),
+            "couldn't register %s. %s was already registered for %s",
+            binding, previousValue, key);
+      }
+    }
+  }
+
+  private final BindingsCollection<ProvisionBinding> provisionBindings =
+      new BindingsCollection<>(BindingType.PROVISION);
+  private final BindingsCollection<MembersInjectionBinding> membersInjectionBindings =
+      new BindingsCollection<>(BindingType.MEMBERS_INJECTION);
+
+  InjectBindingRegistry(
+      Elements elements,
+      Types types,
+      Messager messager,
+      InjectValidator injectValidator,
+      Key.Factory keyFactory,
+      ProvisionBinding.Factory provisionBindingFactory,
+      MembersInjectionBinding.Factory membersInjectionBindingFactory,
+      CompilerOptions compilerOptions) {
+    this.elements = elements;
+    this.types = types;
+    this.messager = messager;
+    this.injectValidator = injectValidator;
+    this.keyFactory = keyFactory;
+    this.provisionBindingFactory = provisionBindingFactory;
+    this.membersInjectionBindingFactory = membersInjectionBindingFactory;
+    this.compilerOptions = compilerOptions;
+  }
+
   /**
-   * Returns a {@link ProvisionBinding} for {@code key}. If none has been registered yet, registers
-   * one.
+   * This method ensures that sources for all registered {@link Binding bindings} (either
+   * {@linkplain #registerBinding explicitly} or implicitly via
+   * {@link #getOrFindMembersInjectionBinding} or {@link #getOrFindProvisionBinding}) are generated.
    */
-  Optional<ProvisionBinding> getOrFindProvisionBinding(Key key);
+  void generateSourcesForRequiredBindings(FactoryGenerator factoryGenerator,
+      MembersInjectorGenerator membersInjectorGenerator) throws SourceFileGenerationException {
+    provisionBindings.generateBindings(factoryGenerator);
+    membersInjectionBindings.generateBindings(membersInjectorGenerator);
+  }
+
+  /**
+   * Registers the binding for generation and later lookup. If the binding is resolved, we also
+   * attempt to register an unresolved version of it.
+   */
+  private void registerBinding(ProvisionBinding binding, boolean warnIfNotAlreadyGenerated) {
+    provisionBindings.tryRegisterBinding(binding, warnIfNotAlreadyGenerated);
+    if (binding.unresolved().isPresent()) {
+      provisionBindings.tryToGenerateBinding(binding.unresolved().get(), warnIfNotAlreadyGenerated);
+    }
+  }
+
+  /**
+   * Registers the binding for generation and later lookup. If the binding is resolved, we also
+   * attempt to register an unresolved version of it.
+   */
+  private void registerBinding(MembersInjectionBinding binding, boolean warnIfNotAlreadyGenerated) {
+    /*
+     * We generate MembersInjector classes for types with @Inject constructors only if they have any
+     * injection sites.
+     *
+     * We generate MembersInjector classes for types without @Inject constructors only if they have
+     * local (non-inherited) injection sites.
+     *
+     * Warn only when registering bindings post-hoc for those types.
+     */
+    warnIfNotAlreadyGenerated =
+        warnIfNotAlreadyGenerated
+            && (!injectedConstructors(binding.membersInjectedType()).isEmpty()
+                ? !binding.injectionSites().isEmpty()
+                : binding.hasLocalInjectionSites());
+    membersInjectionBindings.tryRegisterBinding(binding, warnIfNotAlreadyGenerated);
+    if (binding.unresolved().isPresent()) {
+      membersInjectionBindings.tryToGenerateBinding(
+          binding.unresolved().get(), warnIfNotAlreadyGenerated);
+    }
+  }
+
+  @CanIgnoreReturnValue
+  Optional<ProvisionBinding> tryRegisterConstructor(ExecutableElement constructorElement) {
+    return tryRegisterConstructor(constructorElement, Optional.empty(), false);
+  }
+
+  @CanIgnoreReturnValue
+  private Optional<ProvisionBinding> tryRegisterConstructor(
+      ExecutableElement constructorElement,
+      Optional<TypeMirror> resolvedType,
+      boolean warnIfNotAlreadyGenerated) {
+    TypeElement typeElement = MoreElements.asType(constructorElement.getEnclosingElement());
+    DeclaredType type = MoreTypes.asDeclared(typeElement.asType());
+    Key key = keyFactory.forInjectConstructorWithResolvedType(type);
+    ProvisionBinding cachedBinding = provisionBindings.getBinding(key);
+    if (cachedBinding != null) {
+      return Optional.of(cachedBinding);
+    }
+
+    ValidationReport<TypeElement> report = injectValidator.validateConstructor(constructorElement);
+    report.printMessagesTo(messager);
+    if (report.isClean()) {
+      ProvisionBinding binding =
+          provisionBindingFactory.forInjectConstructor(constructorElement, resolvedType);
+      registerBinding(binding, warnIfNotAlreadyGenerated);
+      if (membersInjectionBindingFactory.hasInjectedMembersIn(type)) {
+        tryRegisterMembersInjectedType(typeElement, resolvedType, warnIfNotAlreadyGenerated);
+      }
+      return Optional.of(binding);
+    }
+    return Optional.empty();
+  }
+
+  @CanIgnoreReturnValue
+  Optional<MembersInjectionBinding> tryRegisterMembersInjectedType(TypeElement typeElement) {
+    return tryRegisterMembersInjectedType(typeElement, Optional.empty(), false);
+  }
+
+  @CanIgnoreReturnValue
+  private Optional<MembersInjectionBinding> tryRegisterMembersInjectedType(
+      TypeElement typeElement,
+      Optional<TypeMirror> resolvedType,
+      boolean warnIfNotAlreadyGenerated) {
+    DeclaredType type = MoreTypes.asDeclared(typeElement.asType());
+    Key key = keyFactory.forInjectConstructorWithResolvedType(type);
+    MembersInjectionBinding cachedBinding = membersInjectionBindings.getBinding(key);
+    if (cachedBinding != null) {
+      return Optional.of(cachedBinding);
+    }
+
+    ValidationReport<TypeElement> report =
+        injectValidator.validateMembersInjectionType(typeElement);
+    report.printMessagesTo(messager);
+    if (report.isClean()) {
+      MembersInjectionBinding binding =
+          membersInjectionBindingFactory.forInjectedType(type, resolvedType);
+      registerBinding(binding, warnIfNotAlreadyGenerated);
+      if (binding.parentKey().isPresent() && !binding.injectionSites().isEmpty()) {
+        getOrFindMembersInjectionBinding(binding.parentKey().get());
+      }
+      return Optional.of(binding);
+    }
+    return Optional.empty();
+  }
+
+  @CanIgnoreReturnValue
+  Optional<ProvisionBinding> getOrFindProvisionBinding(Key key) {
+    checkNotNull(key);
+    if (!key.isValidImplicitProvisionKey(types)) {
+      return Optional.empty();
+    }
+    ProvisionBinding binding = provisionBindings.getBinding(key);
+    if (binding != null) {
+      return Optional.of(binding);
+    }
+
+    // ok, let's see if we can find an @Inject constructor
+    TypeElement element = MoreElements.asType(types.asElement(key.type()));
+    ImmutableSet<ExecutableElement> injectConstructors = injectedConstructors(element);
+    switch (injectConstructors.size()) {
+      case 0:
+        // No constructor found.
+        return Optional.empty();
+      case 1:
+        return tryRegisterConstructor(
+            Iterables.getOnlyElement(injectConstructors), Optional.of(key.type()), true);
+      default:
+        throw new IllegalStateException("Found multiple @Inject constructors: "
+            + injectConstructors);
+    }
+  }
 
   /**
    * Returns a {@link MembersInjectionBinding} for {@code key}. If none has been registered yet,
    * registers one, along with all necessary members injection bindings for superclasses.
    */
-  Optional<MembersInjectionBinding> getOrFindMembersInjectionBinding(Key key);
-
   @CanIgnoreReturnValue
-  Optional<ProvisionBinding> tryRegisterConstructor(ExecutableElement constructorElement);
-
-  @CanIgnoreReturnValue
-  Optional<MembersInjectionBinding> tryRegisterMembersInjectedType(TypeElement typeElement);
-
-  /**
-   * This method ensures that sources for all registered {@link Binding bindings} (either explicitly
-   * or implicitly via {@link #getOrFindMembersInjectionBinding} or {@link
-   * #getOrFindProvisionBinding}) are generated.
-   */
-  void generateSourcesForRequiredBindings(
-      SourceFileGenerator<ProvisionBinding> factoryGenerator,
-      SourceFileGenerator<MembersInjectionBinding> membersInjectorGenerator)
-      throws SourceFileGenerationException;
+  Optional<MembersInjectionBinding> getOrFindMembersInjectionBinding(Key key) {
+    checkNotNull(key);
+    // TODO(gak): is checking the kind enough?
+    checkArgument(key.isValidMembersInjectionKey());
+    MembersInjectionBinding binding = membersInjectionBindings.getBinding(key);
+    if (binding != null) {
+      return Optional.of(binding);
+    }
+    Optional<MembersInjectionBinding> newBinding =
+        tryRegisterMembersInjectedType(
+            MoreTypes.asTypeElement(key.type()), Optional.of(key.type()), true);
+    return newBinding;
+  }
 }
diff --git a/java/dagger/internal/codegen/InjectBindingRegistryImpl.java b/java/dagger/internal/codegen/InjectBindingRegistryImpl.java
deleted file mode 100644
index 3a6e314..0000000
--- a/java/dagger/internal/codegen/InjectBindingRegistryImpl.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2014 The Dagger Authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dagger.internal.codegen;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static dagger.internal.codegen.InjectionAnnotations.injectedConstructors;
-import static dagger.internal.codegen.SourceFiles.generatedClassNameForBinding;
-
-import com.google.auto.common.MoreElements;
-import com.google.auto.common.MoreTypes;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import com.squareup.javapoet.ClassName;
-import dagger.Component;
-import dagger.Provides;
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import javax.annotation.processing.Messager;
-import javax.inject.Inject;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.Types;
-import javax.tools.Diagnostic.Kind;
-
-/**
- * Maintains the collection of provision bindings from {@link Inject} constructors and members
- * injection bindings from {@link Inject} fields and methods known to the annotation processor.
- * Note that this registry <b>does not</b> handle any explicit bindings (those from {@link Provides}
- * methods, {@link Component} dependencies, etc.).
- *
- * @author Gregory Kick
- */
-final class InjectBindingRegistryImpl implements InjectBindingRegistry {
-  private final Elements elements;
-  private final Types types;
-  private final Messager messager;
-  private final InjectValidator injectValidator;
-  private final InjectValidator injectValidatorWhenGeneratingCode;
-  private final Key.Factory keyFactory;
-  private final ProvisionBinding.Factory provisionBindingFactory;
-  private final MembersInjectionBinding.Factory membersInjectionBindingFactory;
-  private final CompilerOptions compilerOptions;
-
-  final class BindingsCollection<B extends Binding> {
-    private final BindingType bindingType;
-    private final Map<Key, B> bindingsByKey = Maps.newLinkedHashMap();
-    private final Deque<B> bindingsRequiringGeneration = new ArrayDeque<>();
-    private final Set<Key> materializedBindingKeys = Sets.newLinkedHashSet();
-    
-    BindingsCollection(BindingType bindingType) {
-      this.bindingType = bindingType;
-    }
-
-    void generateBindings(SourceFileGenerator<B> generator) throws SourceFileGenerationException {
-      for (B binding = bindingsRequiringGeneration.poll();
-          binding != null;
-          binding = bindingsRequiringGeneration.poll()) {
-        checkState(!binding.unresolved().isPresent());
-        if (injectValidatorWhenGeneratingCode.isValidType(binding.key().type())) {
-          generator.generate(binding);
-        }
-        materializedBindingKeys.add(binding.key());
-      }
-      // Because Elements instantiated across processing rounds are not guaranteed to be equals() to
-      // the logically same element, clear the cache after generating
-      bindingsByKey.clear();
-    }
-
-    /** Returns a previously cached binding. */
-    B getBinding(Key key) {
-      return bindingsByKey.get(key);
-    }
-
-    /** Caches the binding and generates it if it needs generation. */
-    void tryRegisterBinding(B binding, boolean warnIfNotAlreadyGenerated) {
-      tryToCacheBinding(binding);
-      tryToGenerateBinding(binding, warnIfNotAlreadyGenerated);
-    }
-
-    /**
-     * Tries to generate a binding, not generating if it already is generated. For resolved
-     * bindings, this will try to generate the unresolved version of the binding.
-     */
-    void tryToGenerateBinding(B binding, boolean warnIfNotAlreadyGenerated) {
-      if (shouldGenerateBinding(binding, generatedClassNameForBinding(binding))) {
-        bindingsRequiringGeneration.offer(binding);
-        if (compilerOptions.warnIfInjectionFactoryNotGeneratedUpstream()
-            && warnIfNotAlreadyGenerated) {
-          messager.printMessage(
-              Kind.NOTE,
-              String.format(
-                  "Generating a %s for %s. "
-                      + "Prefer to run the dagger processor over that class instead.",
-                  bindingType.frameworkClass().getSimpleName(),
-                  types.erasure(binding.key().type()))); // erasure to strip <T> from msgs.
-        }
-      }
-    }
-
-    /** Returns true if the binding needs to be generated. */
-    private boolean shouldGenerateBinding(B binding, ClassName factoryName) {
-      return !binding.unresolved().isPresent()
-          && elements.getTypeElement(factoryName.toString()) == null
-          && !materializedBindingKeys.contains(binding.key())
-          && !bindingsRequiringGeneration.contains(binding);
-    }
-
-    /** Caches the binding for future lookups by key. */
-    private void tryToCacheBinding(B binding) {
-      // We only cache resolved bindings or unresolved bindings w/o type arguments.
-      // Unresolved bindings w/ type arguments aren't valid for the object graph.
-      if (binding.unresolved().isPresent()
-          || binding.bindingTypeElement().get().getTypeParameters().isEmpty()) {
-        Key key = binding.key();
-        Binding previousValue = bindingsByKey.put(key, binding);
-        checkState(previousValue == null || binding.equals(previousValue),
-            "couldn't register %s. %s was already registered for %s",
-            binding, previousValue, key);
-      }
-    }
-  }
-
-  private final BindingsCollection<ProvisionBinding> provisionBindings =
-      new BindingsCollection<>(BindingType.PROVISION);
-  private final BindingsCollection<MembersInjectionBinding> membersInjectionBindings =
-      new BindingsCollection<>(BindingType.MEMBERS_INJECTION);
-
-  InjectBindingRegistryImpl(
-      Elements elements,
-      Types types,
-      Messager messager,
-      InjectValidator injectValidator,
-      Key.Factory keyFactory,
-      ProvisionBinding.Factory provisionBindingFactory,
-      MembersInjectionBinding.Factory membersInjectionBindingFactory,
-      CompilerOptions compilerOptions) {
-    this.elements = elements;
-    this.types = types;
-    this.messager = messager;
-    this.injectValidator = injectValidator;
-    this.injectValidatorWhenGeneratingCode = injectValidator.whenGeneratingCode();
-    this.keyFactory = keyFactory;
-    this.provisionBindingFactory = provisionBindingFactory;
-    this.membersInjectionBindingFactory = membersInjectionBindingFactory;
-    this.compilerOptions = compilerOptions;
-  }
-
-  // TODO(dpb): make the SourceFileGenerators fields so they don't have to be passed in
-  @Override
-  public void generateSourcesForRequiredBindings(
-      SourceFileGenerator<ProvisionBinding> factoryGenerator,
-      SourceFileGenerator<MembersInjectionBinding> membersInjectorGenerator)
-      throws SourceFileGenerationException {
-    provisionBindings.generateBindings(factoryGenerator);
-    membersInjectionBindings.generateBindings(membersInjectorGenerator);
-  }
-
-  /**
-   * Registers the binding for generation and later lookup. If the binding is resolved, we also
-   * attempt to register an unresolved version of it.
-   */
-  private void registerBinding(ProvisionBinding binding, boolean warnIfNotAlreadyGenerated) {
-    provisionBindings.tryRegisterBinding(binding, warnIfNotAlreadyGenerated);
-    if (binding.unresolved().isPresent()) {
-      provisionBindings.tryToGenerateBinding(binding.unresolved().get(), warnIfNotAlreadyGenerated);
-    }
-  }
-
-  /**
-   * Registers the binding for generation and later lookup. If the binding is resolved, we also
-   * attempt to register an unresolved version of it.
-   */
-  private void registerBinding(MembersInjectionBinding binding, boolean warnIfNotAlreadyGenerated) {
-    /*
-     * We generate MembersInjector classes for types with @Inject constructors only if they have any
-     * injection sites.
-     *
-     * We generate MembersInjector classes for types without @Inject constructors only if they have
-     * local (non-inherited) injection sites.
-     *
-     * Warn only when registering bindings post-hoc for those types.
-     */
-    warnIfNotAlreadyGenerated =
-        warnIfNotAlreadyGenerated
-            && (!injectedConstructors(binding.membersInjectedType()).isEmpty()
-                ? !binding.injectionSites().isEmpty()
-                : binding.hasLocalInjectionSites());
-    membersInjectionBindings.tryRegisterBinding(binding, warnIfNotAlreadyGenerated);
-    if (binding.unresolved().isPresent()) {
-      membersInjectionBindings.tryToGenerateBinding(
-          binding.unresolved().get(), warnIfNotAlreadyGenerated);
-    }
-  }
-
-  @Override
-  public Optional<ProvisionBinding> tryRegisterConstructor(ExecutableElement constructorElement) {
-    return tryRegisterConstructor(constructorElement, Optional.empty(), false);
-  }
-
-  @CanIgnoreReturnValue
-  private Optional<ProvisionBinding> tryRegisterConstructor(
-      ExecutableElement constructorElement,
-      Optional<TypeMirror> resolvedType,
-      boolean warnIfNotAlreadyGenerated) {
-    TypeElement typeElement = MoreElements.asType(constructorElement.getEnclosingElement());
-    DeclaredType type = MoreTypes.asDeclared(typeElement.asType());
-    Key key = keyFactory.forInjectConstructorWithResolvedType(type);
-    ProvisionBinding cachedBinding = provisionBindings.getBinding(key);
-    if (cachedBinding != null) {
-      return Optional.of(cachedBinding);
-    }
-
-    ValidationReport<TypeElement> report = injectValidator.validateConstructor(constructorElement);
-    report.printMessagesTo(messager);
-    if (report.isClean()) {
-      ProvisionBinding binding =
-          provisionBindingFactory.forInjectConstructor(constructorElement, resolvedType);
-      registerBinding(binding, warnIfNotAlreadyGenerated);
-      if (membersInjectionBindingFactory.hasInjectedMembersIn(type)) {
-        tryRegisterMembersInjectedType(typeElement, resolvedType, warnIfNotAlreadyGenerated);
-      }
-      return Optional.of(binding);
-    }
-    return Optional.empty();
-  }
-
-  @Override
-  public Optional<MembersInjectionBinding> tryRegisterMembersInjectedType(TypeElement typeElement) {
-    return tryRegisterMembersInjectedType(typeElement, Optional.empty(), false);
-  }
-
-  @CanIgnoreReturnValue
-  private Optional<MembersInjectionBinding> tryRegisterMembersInjectedType(
-      TypeElement typeElement,
-      Optional<TypeMirror> resolvedType,
-      boolean warnIfNotAlreadyGenerated) {
-    DeclaredType type = MoreTypes.asDeclared(typeElement.asType());
-    Key key = keyFactory.forInjectConstructorWithResolvedType(type);
-    MembersInjectionBinding cachedBinding = membersInjectionBindings.getBinding(key);
-    if (cachedBinding != null) {
-      return Optional.of(cachedBinding);
-    }
-
-    ValidationReport<TypeElement> report =
-        injectValidator.validateMembersInjectionType(typeElement);
-    report.printMessagesTo(messager);
-    if (report.isClean()) {
-      MembersInjectionBinding binding =
-          membersInjectionBindingFactory.forInjectedType(type, resolvedType);
-      registerBinding(binding, warnIfNotAlreadyGenerated);
-      if (binding.parentKey().isPresent() && !binding.injectionSites().isEmpty()) {
-        getOrFindMembersInjectionBinding(binding.parentKey().get());
-      }
-      return Optional.of(binding);
-    }
-    return Optional.empty();
-  }
-
-  @CanIgnoreReturnValue
-  @Override
-  public Optional<ProvisionBinding> getOrFindProvisionBinding(Key key) {
-    checkNotNull(key);
-    if (!key.isValidImplicitProvisionKey(types)) {
-      return Optional.empty();
-    }
-    ProvisionBinding binding = provisionBindings.getBinding(key);
-    if (binding != null) {
-      return Optional.of(binding);
-    }
-
-    // ok, let's see if we can find an @Inject constructor
-    TypeElement element = MoreElements.asType(types.asElement(key.type()));
-    ImmutableSet<ExecutableElement> injectConstructors = injectedConstructors(element);
-    switch (injectConstructors.size()) {
-      case 0:
-        // No constructor found.
-        return Optional.empty();
-      case 1:
-        return tryRegisterConstructor(
-            Iterables.getOnlyElement(injectConstructors), Optional.of(key.type()), true);
-      default:
-        throw new IllegalStateException("Found multiple @Inject constructors: "
-            + injectConstructors);
-    }
-  }
-
-  @CanIgnoreReturnValue
-  @Override
-  public Optional<MembersInjectionBinding> getOrFindMembersInjectionBinding(Key key) {
-    checkNotNull(key);
-    // TODO(gak): is checking the kind enough?
-    checkArgument(key.isValidMembersInjectionKey());
-    MembersInjectionBinding binding = membersInjectionBindings.getBinding(key);
-    if (binding != null) {
-      return Optional.of(binding);
-    }
-    Optional<MembersInjectionBinding> newBinding =
-        tryRegisterMembersInjectedType(
-            MoreTypes.asTypeElement(key.type()), Optional.of(key.type()), true);
-    return newBinding;
-  }
-}
diff --git a/java/dagger/internal/codegen/InjectProcessingStep.java b/java/dagger/internal/codegen/InjectProcessingStep.java
index e9ca5fc..2343589 100644
--- a/java/dagger/internal/codegen/InjectProcessingStep.java
+++ b/java/dagger/internal/codegen/InjectProcessingStep.java
@@ -38,8 +38,8 @@
 final class InjectProcessingStep implements BasicAnnotationProcessor.ProcessingStep {
   private final InjectBindingRegistry injectBindingRegistry;
 
-  InjectProcessingStep(InjectBindingRegistry injectBindingRegistry) {
-    this.injectBindingRegistry = injectBindingRegistry;
+  InjectProcessingStep(InjectBindingRegistry factoryRegistrar) {
+    this.injectBindingRegistry = factoryRegistrar;
   }
 
   @Override
diff --git a/java/dagger/internal/codegen/MembersInjectorGenerator.java b/java/dagger/internal/codegen/MembersInjectorGenerator.java
index fff1c63..81620a3 100644
--- a/java/dagger/internal/codegen/MembersInjectorGenerator.java
+++ b/java/dagger/internal/codegen/MembersInjectorGenerator.java
@@ -65,10 +65,13 @@
  */
 final class MembersInjectorGenerator extends SourceFileGenerator<MembersInjectionBinding> {
   private final Types types;
+  private final InjectValidator injectValidator;
 
-  MembersInjectorGenerator(Filer filer, Elements elements, Types types) {
+  MembersInjectorGenerator(
+      Filer filer, Elements elements, Types types, InjectValidator injectValidator) {
     super(filer, elements);
     this.types = types;
+    this.injectValidator = injectValidator;
   }
 
   @Override
@@ -87,6 +90,9 @@
     if (binding.injectionSites().isEmpty()) {
       return Optional.empty();
     }
+    if (!injectValidator.isValidType(binding.key().type())) {
+      return Optional.empty();
+    }
     // We don't want to write out resolved bindings -- we want to write out the generic version.
     checkState(
         !binding.unresolved().isPresent(),
diff --git a/java/dagger/internal/codegen/SourceFileGenerator.java b/java/dagger/internal/codegen/SourceFileGenerator.java
index 0c1b01c..436a748 100644
--- a/java/dagger/internal/codegen/SourceFileGenerator.java
+++ b/java/dagger/internal/codegen/SourceFileGenerator.java
@@ -42,7 +42,7 @@
 
   private static final AnnotationSpec GENERATED =
       AnnotationSpec.builder(Generated.class)
-          .addMember("value", "$S", "dagger.internal.codegen.ComponentProcessor")
+          .addMember("value", "$S", ComponentProcessor.class.getName())
           .addMember("comments", "$S", GENERATED_COMMENTS)
           .build();
 
@@ -93,7 +93,8 @@
         JavaFile.builder(generatedTypeName.packageName(), typeSpecBuilder.build())
             .skipJavaLangImports(true);
     if (!generatedAnnotationAvailable) {
-      javaFileBuilder.addFileComment("Generated by Dagger ($L).", GENERATED_COMMENTS);
+      javaFileBuilder.addFileComment(
+          "Generated by $L ($L).", ComponentProcessor.class.getName(), GENERATED_COMMENTS);
     }
     return javaFileBuilder.build();
   }
diff --git a/javatests/dagger/internal/codegen/BUILD b/javatests/dagger/internal/codegen/BUILD
index 005d110..824d074 100644
--- a/javatests/dagger/internal/codegen/BUILD
+++ b/javatests/dagger/internal/codegen/BUILD
@@ -27,11 +27,7 @@
     javacopts = DOCLINT_HTML_AND_SYNTAX,
     deps = [
         "//java/dagger:core",
-        "//java/dagger/internal/codegen:base",
-        "//java/dagger/internal/codegen:binding",
-        "//java/dagger/internal/codegen:processor",
-        "//java/dagger/internal/codegen:validation",
-        "//java/dagger/internal/codegen:writing",
+        "//java/dagger/internal/codegen",
         "//java/dagger/producers",
         "//third_party:auto_common",
         "//third_party:auto_value",
diff --git a/merge_all_rules.txt b/merge_all_rules.txt
deleted file mode 100644
index 345c532..0000000
--- a/merge_all_rules.txt
+++ /dev/null
@@ -1 +0,0 @@
-# an empty rules file causes jarjar to merge all of the jar contents without any renaming
diff --git a/util/execute-deploy.sh b/util/execute-deploy.sh
index ad25d1a..364fa53 100755
--- a/util/execute-deploy.sh
+++ b/util/execute-deploy.sh
@@ -10,7 +10,7 @@
 python $(dirname $0)/maven/generate_poms.py $VERSION_NAME \
   //java/dagger:core \
   //gwt:gwt \
-  //java/dagger/internal/codegen:processor \
+  //java/dagger/internal/codegen:codegen \
   //java/dagger/producers:producers \
   //java/dagger/android:android \
   //java/dagger/android:libandroid.jar \
@@ -43,9 +43,9 @@
 
   mvn $MVN_GOAL \
     -Dfile=$(library_output_file $library) \
-    -Djavadoc=$(library_output_file $javadoc) \
+    -Djavadoc=bazel-bin/$javadoc \
     -DpomFile=$pomfile \
-    -Dsources=$(library_output_file $srcjar) \
+    -Dsources=bazel-bin/$srcjar \
     "${EXTRA_MAVEN_ARGS[@]:+${EXTRA_MAVEN_ARGS[@]}}"
 }
 
@@ -63,7 +63,7 @@
 
 deploy_library \
   shaded_compiler.jar \
-  shaded_compiler_src.jar \
+  java/dagger/internal/codegen/libcodegen-src.jar \
   java/dagger/internal/codegen/codegen-javadoc.jar \
   dagger-compiler.pom.xml
 
diff --git a/util/maven/generate_poms.py b/util/maven/generate_poms.py
index 010e0e1..af19c98 100644
--- a/util/maven/generate_poms.py
+++ b/util/maven/generate_poms.py
@@ -28,8 +28,8 @@
 
 def deps_of(label):
   return _shell(
-      """bazel query 'let deps = labels(deps, {0}) in $deps
-      except attr(tags, "maven:(compile_only|merged|shaded)", $deps)
+      """bazel query 'let deps = labels(deps, {0})in $deps
+      except attr(tags, "maven:(compile_only|shaded)", $deps)
       '""".format(label))
 
 def exports_for(label):
@@ -65,7 +65,7 @@
             'javax.inject:javax.inject:1:jar:sources',
         ],
     },
-    '//java/dagger/internal/codegen:processor': {
+    '//java/dagger/internal/codegen:codegen': {
         'name': 'Dagger Compiler',
         'artifact': 'dagger-compiler',
     },